Mario Lang, le Sat 15 Dec 2007 17:17:47 +0100, a écrit :
> As usual, I am not the best code designer,

Nobody is :)
> so some starting help for getting this into brltty core would
> be very appreciated?  Dave?
> 
> P.S.: The following code checks for a specific keyboard.
> We will of course want to do something much more generic here,
> like test for a keyboard that actually has the keys we'd like to watch out 
> for.
> The function has_event() can be used to do this, a call like
> has_event(filedescriptor, EV_KEY, KEY_ESC) will return 1 if the keyboard
> associated with filedescriptor does have an ESC key...
> 
> #include <dirent.h>
> #include <fcntl.h>
> #include <linux/input.h>
> #include <linux/uinput.h>
> #include <stdio.h>
> #include <string.h>
> #include <sys/stat.h>
> #include <sys/types.h>
> #include <unistd.h>
> 
> static int
> has_event(int fd, unsigned short type, unsigned short code)
> {
> #define MAX(a,b) a>b?a:b
>   const unsigned int len = sizeof(unsigned long)*8;
>   const unsigned int max = MAX(EV_MAX,
>                              MAX(KEY_MAX,
>                                  MAX(REL_MAX,
>                                      MAX(ABS_MAX,
>                                          MAX(LED_MAX,
>                                              MAX(SND_MAX, FF_MAX))))));
>   unsigned long bits[(max+len-1)/len];
>   if (ioctl(fd, EVIOCGBIT(type, max), bits)) {
>     return (bits[code/len] >> (code%len)) & 1;
>   }
>   return 0;
> #undef MAX
> }
> 
> static int
> constructKeyboard (char *name, struct input_id *id, unsigned long *keymask)
> {
>   int fd;
>   if ((fd = open("/dev/input/uinput", O_WRONLY)) > 0) {
>     struct uinput_user_dev description;
> 
>     memset(&description, 0, sizeof(description));
>     strncpy(description.name, name, UINPUT_MAX_NAME_SIZE);
>     memcpy(&description.id, id, sizeof(description.id));
>     if (write(fd, &description, sizeof(description)) == sizeof(description)) {
>       int key;
> 
>       ioctl(fd, UI_SET_EVBIT, EV_KEY);
>       ioctl(fd, UI_SET_EVBIT, EV_REP);
> 
>       for (key=KEY_RESERVED; key<=KEY_MAX; key++) {
>         if ((keymask[key/(sizeof(unsigned long)*8)] >> (key%(sizeof(unsigned 
> long)*8)))&1) {
>         ioctl(fd, UI_SET_KEYBIT, key);
>       }
>       }
>       if (ioctl(fd, UI_DEV_CREATE) != -1) {
>       return fd;
>       } else {
>       perror("ioctl UI_DEV_CREATE");
>       }
>     } else {
>       perror("write (struct uinput_user_dev)");
>     }
>   } else {
>     perror("open /dev/input/uinput");
>   }
>   return -1;
> }
> 
> int
> main(int argc, char *argv[])
> {
>   char root[] = "/dev/input";
>   int rootLength = strlen(root);
>   int foundKeyboard = 0;
>   DIR *directory;
> 
>   if ((directory = opendir(root))) {
>     struct dirent *entry;
> 
>     while ((entry = readdir(directory))) {
>       size_t nameLength = strlen(entry->d_name);
>       struct stat status;
>       char path[rootLength + 1 + nameLength + 1];
> 
>       snprintf(path, sizeof(path), "%s/%s", root, entry->d_name);
>       if (stat(path, &status) == -1) continue;
>       if (S_ISCHR(status.st_mode)) {
>         int fd;
> 
>         if ((fd = open(path, O_RDONLY)) > 0) {
>           struct input_id id;
>         
>           if (ioctl(fd, EVIOCGID, &id) != -1) {
>             if (id.bustype == 3 &&
>                 id.vendor == 0X0430 && id.product == 0X0005 &&
>               has_event(fd, EV_KEY, KEY_HELP)) {
>             unsigned long keymask[(KEY_MAX+(sizeof(unsigned 
> long)*8)-1)/(sizeof(unsigned long)*8)];
>               struct input_event event;
> 
>               foundKeyboard = 1;
> 
>             if (ioctl(fd, EVIOCGBIT(EV_KEY, KEY_MAX), keymask)) {
>               int uinput = constructKeyboard("test", &id, keymask);
>             
>               if (uinput != -1) {
>                 ioctl(fd, EVIOCGRAB, 1);
>                 while (read(fd, &event, sizeof(event)) == sizeof(event)) {
>                   if (event.type == EV_KEY) {
>                     switch (event.code) {
>                     case KEY_MUTE:
>                       printf("MUTE %s\n", event.value ? "press":"release");
>                       break;
>                     case KEY_VOLUMEDOWN:
>                       printf("VOLUMEDOWN %s\n", event.value ? 
> "press":"release");
>                       break;
>                     case KEY_VOLUMEUP:
>                       printf("VOLUMEUP %s\n", event.value ? 
> "press":"release");
>                       break;
>                     case KEY_POWER:
>                       printf("POWER %s\n", event.value ? "press":"release");
>                       break;
>                     case KEY_STOP:
>                       printf("STOP %s\n", event.value ? "press":"release");
>                       break;
>                     case KEY_AGAIN:
>                       printf("AGAIN %s\n", event.value ? "press":"release");
>                       break;
>                     case KEY_PROPS:
>                       printf("PROPS %s\n", event.value ? "press":"release");
>                       break;;
>                     case KEY_UNDO:
>                       printf("UNDO %s\n", event.value ? "press":"release");
>                       break;;
>                     default:
>                       write(uinput, &event, sizeof(event));
>                       printf("%d = %d\n", event.code, event.value);
>                     }
>                   }
>                 }
> 
>                 ioctl(fd, EVIOCGRAB, 0);
>                 close(uinput);
>               }
>             }
>           }
>           }
>           close(fd);
>         }
>       }
>     }
>     closedir(directory);
> 
>     if (!foundKeyboard) {
>       printf("No supported USB keyboard found.\n");
>     }
>   } else {
>     fprintf(stderr, "Unable to open %s\n", root);
>   }
>   return 0;
> }
> 
> 
> -- 
> CYa,
>   Mario | Debian Developer <URL:http://debian.org/>
>   .''`. | Get my public key via finger [EMAIL PROTECTED]
>  : :' : | 1024D/7FC1A0854909BCCDBE6C102DDFFC022A6B113E44
>  `. `'
>    `-      <URL:http://delysid.org/>  <URL:http://www.staff.tugraz.at/mlang/>
> _______________________________________________
> This message was sent via the BRLTTY mailing list.
> To post a message, send an e-mail to: BRLTTY@mielke.cc
> For general information, go to: http://mielke.cc/mailman/listinfo/brltty
> 

-- 
Samuel
"c'est pas nous qui sommes à la rue, c'est la rue qui est à nous"
_______________________________________________
This message was sent via the BRLTTY mailing list.
To post a message, send an e-mail to: BRLTTY@mielke.cc
For general information, go to: http://mielke.cc/mailman/listinfo/brltty

Reply via email to