/* * Copyright (C) 2007 Olli Salonen * see btnx.c for detailed license information */ #include #include #include #include #include #include #include #include #include #include "uinput.h" #include "btnx.h" #define BTNX_VENDOR 0xB216 #define BTNX_PRODUCT_MOUSE 0x0001 #define BTNX_PRODUCT_KBD 0x0002 /* Static variables */ static int uinput_mouse_fd = -1; static int uinput_kbd_fd = -1; /* * uinput_init() function partially derived from Micah Dowty's uinput_mouse.c * */ /* Open and init uinput file descriptors */ int uinput_init(const char *dev_name) { struct uinput_user_dev dev_mouse, dev_kbd; int i; uinput_mouse_fd = open_handler("uinput", O_WRONLY | O_NDELAY); if (uinput_mouse_fd < 0) { perror( OUT_PRE "Error opening the uinput device.\n" OUT_PRE "Make sure you have loaded the uinput module (modprobe uinput)"); exit(BTNX_ERROR_OPEN_UINPUT); } uinput_kbd_fd = open_handler("uinput", O_WRONLY | O_NDELAY); if (uinput_kbd_fd < 0) { perror(OUT_PRE "Error opening the uinput device"); exit(BTNX_ERROR_OPEN_UINPUT); } memset(&dev_mouse, 0, sizeof(dev_mouse)); dev_mouse.id.bustype = 0; dev_mouse.id.vendor = BTNX_VENDOR; dev_mouse.id.product = BTNX_PRODUCT_MOUSE; dev_mouse.id.version = 0; strcpy(dev_mouse.name, UMOUSE_NAME); write(uinput_mouse_fd, &dev_mouse, sizeof(dev_mouse)); memset(&dev_kbd, 0, sizeof(dev_kbd)); dev_kbd.id.bustype = 0; dev_kbd.id.vendor = BTNX_VENDOR; dev_kbd.id.product = BTNX_PRODUCT_KBD; dev_kbd.id.version = 0; strcpy(dev_kbd.name, UKBD_NAME); write(uinput_kbd_fd, &dev_kbd, sizeof(dev_kbd)); ioctl(uinput_mouse_fd, UI_SET_EVBIT, EV_REL); ioctl(uinput_mouse_fd, UI_SET_RELBIT, REL_X); ioctl(uinput_mouse_fd, UI_SET_RELBIT, REL_Y); ioctl(uinput_mouse_fd, UI_SET_RELBIT, REL_WHEEL); ioctl(uinput_mouse_fd, UI_SET_EVBIT, EV_KEY); for (i=BTN_MISC; ikeycode <= KEY_UNKNOWN || bev->keycode >= KEY_OK) && bev->keycode < BTNX_EXTRA_EVENTS) fd = uinput_kbd_fd; else fd = uinput_mouse_fd; gettimeofday(&event.time, NULL); for (i=0; imod[i] == 0) continue; event.type = EV_KEY; event.code = bev->mod[i]; event.value = bev->pressed; write(uinput_kbd_fd, &event, sizeof(event)); event.type = EV_SYN; event.code = SYN_REPORT; event.value = 0; write(uinput_kbd_fd, &event, sizeof(event)); usleep(10); // Needs a little delay for mouse + modifier combo } if (bev->keycode > BTNX_EXTRA_EVENTS) { event.type = EV_REL; if (bev->keycode == REL_WHEELFORWARD || bev->keycode == REL_WHEELBACK) event.code = REL_WHEEL; if (bev->keycode == REL_WHEELFORWARD) event.value = 1; else if (bev->keycode == REL_WHEELBACK) event.value = -1; write(fd, &event, sizeof(event)); } else { event.type = EV_KEY; event.code = bev->keycode; event.value = bev->pressed; write(fd, &event, sizeof(event)); } event.type = EV_SYN; event.code = SYN_REPORT; event.value = 0; write(fd, &event, sizeof(event)); }