#include #include #include #include #include #include #include #include #include #include /* * https://www.elecom.co.jp/products/M-XGL20DLBK.html * このマウスの Fnボタンの状態を捕捉し表示します。 */ /* * 0: 変化なし * 1: Down * 2: Up */ int button_state(char state, char state_diff, char target_bit) { if (state_diff & target_bit) { if (state & target_bit) { return 1; } else { return 2; }; } return 0; } int fd = -1; void abort_handler(int sig) { close(fd); }; int main (int argc, char **argv) { char name[1024]; char buf[128]; int count = 0; /* ioctl() requires a file descriptor, so we check we got one, and then open it */ if (argc != 2) { fprintf(stderr, "usage: %s [hiddevice]\nprobably /dev/usb/hiddev0\n", argv[0]); exit(1); } if ((fd = open(argv[1], O_RDONLY)) < 0) { fprintf(stderr, "hiddev %s open", argv[1]); exit(1); } signal(SIGINT, abort_handler); /* ioctl() accesses the underlying driver */ ioctl(fd, HIDIOCGNAME(sizeof(name)), name); /* the HIDIOCGVERSION ioctl() returns an int */ /* so we unpack it and display it */ printf("hiddev device name is %s\n",name); char before_status = 0; for (;;) { int c = read(fd, buf + count, 8); /* 8以下だと何も返ってこない。この値はどう決まるか? */ if (0 > c) { printf ("hiddev %s: read error", argv[1]); break; } count += c; if (128 == count) { count = 0; char state = buf[20]; char diff = buf[20] ^ before_status; before_status = state; const char fn1_flag = 0x20; const char fn2_flag = 0x40; const char fn3_flag = 0x80; switch(button_state(state,diff,fn1_flag)) { case 1: printf(" Fn1 Down\n"); break; case 2: printf(" Fn1 Up\n"); break; } switch(button_state(state,diff,fn2_flag)) { case 1: printf(" Fn2 Down\n"); break; case 2: printf(" Fn2 Up\n"); break; } switch(button_state(state,diff,fn3_flag)) { case 1: printf(" Fn3 Down\n"); break; case 2: printf(" Fn3 Up\n"); break; } } } close(fd); exit(0); }