tags 407725 patch thanks On Sat, Jan 20, 2007 at 08:55:38PM +0100, Andreas Krebl wrote: > after starting mouseemu the mousepointer does not react anymore. > /etc/init.d/mouseemu stop reanimates the mousepointer
I suspect this may be due to a single USB device (e.g. a hub) emitting both keyboard and mouse events; mouseemu can't cope with this at all at the moment. The attached patch fixes a problem with the same symptoms on my Intel iMac by reshuffling mouseemu's event handling. Cheers, -- Colin Watson [EMAIL PROTECTED]
#! /bin/sh /usr/share/dpatch/dpatch-run ## dual_devices.dpatch by Colin Watson <[EMAIL PROTECTED]> ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: No description. @DPATCH@ diff -urNad mouseemu-0.15~/mouseemu.c mouseemu-0.15/mouseemu.c --- mouseemu-0.15~/mouseemu.c 2007-02-08 01:59:26.000000000 +0000 +++ mouseemu-0.15/mouseemu.c 2007-02-08 01:59:44.000000000 +0000 @@ -187,52 +187,66 @@ } } -void keyboard_handler (int fd) +void keyboard_handler (struct input_event inp) { - struct input_event inp; - if (read(fd, &inp, sizeof(inp)) == sizeof(inp)) { - if (!event_parse(inp.code, inp.value) && !is_modifier(inp)) { - last_key = (inp.time.tv_sec*1000000 + inp.time.tv_usec); - } + if (inp.type != EV_KEY && inp.type != EV_REP) + return; + if (inp.type == EV_KEY && (inp.code == BTN_LEFT || inp.code == BTN_MIDDLE || inp.code == BTN_RIGHT)) + return; + + if (!event_parse(inp.code, inp.value) && !is_modifier(inp)) { + last_key = (inp.time.tv_sec*1000000 + inp.time.tv_usec); + } /* I think its best not to pass scroll, or experiment with not passing the release if * we actually used it for scrolling (but some apps may get stuck?) */ - if (inp.code != b2_key && inp.code != b3_key) { - passthrough(ui_keyb_fd, inp); - } + if (inp.code != b2_key && inp.code != b3_key) { + passthrough(ui_keyb_fd, inp); } } -static void mouse_handler (int fd) +static void mouse_handler (struct input_event inp) +{ + if (inp.type != EV_KEY && inp.type != EV_REL && inp.type != EV_SYN) + return; + if (inp.type == EV_KEY && inp.code != BTN_LEFT && inp.code != BTN_MIDDLE && inp.code != BTN_RIGHT) + return; + + if (inp.type == EV_KEY && inp.code == BTN_LEFT) { + if (b2_key == BTN_LEFT && b2_mod_pressed) + report_click(BTN_MIDDLE, inp.value); + else if (b3_key == BTN_LEFT && b3_mod_pressed) + report_click(BTN_RIGHT, inp.value); + else + passthrough(ui_mouse_fd, inp); + } + else if (scroll_mod_pressed + && inp.type == EV_REL + && (inp.code == REL_Y || inp.code == REL_X)) { + report_scroll (inp.value); + //printf("inp.value %d\n", inp.value); + } else { + if ((inp.time.tv_sec*1000000+inp.time.tv_usec)-last_key > typing_block_delay*1000 + || inp.type == EV_REL) + passthrough(ui_mouse_fd, inp); + } +} + +static void event_handler (int mode, int fd) { - int count; struct input_event inp; - if ((count = read(fd, &inp, sizeof(inp))) == sizeof(inp)) { - if (inp.type == EV_KEY && inp.code == BTN_LEFT) { - if (b2_key == BTN_LEFT && b2_mod_pressed) - report_click(BTN_MIDDLE, inp.value); - else if (b3_key == BTN_LEFT && b3_mod_pressed) - report_click(BTN_RIGHT, inp.value); - else - passthrough(ui_mouse_fd, inp); - } - else if (scroll_mod_pressed - && inp.type == EV_REL - && (inp.code == REL_Y || inp.code == REL_X)) { - report_scroll (inp.value); - //printf("inp.value %d\n", inp.value); - } else { - if ((inp.time.tv_sec*1000000+inp.time.tv_usec)-last_key > typing_block_delay*1000 - || inp.type == EV_REL) - passthrough(ui_mouse_fd, inp); - } + if (read(fd, &inp, sizeof(inp)) == sizeof(inp)) { + if (mode & HANDLER_KEYBOARD) + keyboard_handler(inp); + if (mode & HANDLER_MOUSE) + mouse_handler(inp); } } void scan_for_devs() { - int n, m, fd; + int n, m, fd, mode; char filename[20]; unsigned long bit[NBITS(EV_MAX)]; unsigned short id[EVENT_DEVS]; @@ -240,47 +254,47 @@ for (n = 0, m = 0; n < EVENT_DEVS; n++) { sprintf(filename, "/dev/input/event%d", n); if ((fd = open(filename, O_RDONLY)) >= 0) { + mode = 0; ioctl(fd, EVIOCGBIT(0, EV_MAX), bit); + ioctl(fd, EVIOCGID, id); if (test_bit(EV_KEY, bit) && test_bit(EV_REP, bit)) { - ioctl(fd, EVIOCGID, id); /* our own virtual keyboard (on rescans)*/ if (id[ID_PRODUCT] == 0x1F && id[ID_VENDOR] == 0x1F) { close(fd); continue; } + mode |= HANDLER_KEYBOARD; if (id[ID_PRODUCT] != eventdevs[m].product || id[ID_VENDOR] != eventdevs[m].vendor) { - if (eventdevs[m].handle >= 0) { - unregister_inputhandler(eventdevs[m].handle); - close(eventdevs[m].handle); - } debugf("keyboard: fd %d event%d, vendor %4x product %4x\n", fd, n, id[ID_VENDOR], id[ID_PRODUCT]); - eventdevs[m].handle= fd; - eventdevs[m].product = id[ID_PRODUCT]; - eventdevs[m].vendor = id[ID_VENDOR]; - register_inputhandler(fd, keyboard_handler, 1); } - m++; - } else if (test_bit(EV_REL, bit)) { - ioctl(fd, EVIOCGID, id); + } + if (test_bit(EV_REL, bit)) { /* our own virtual mouse (on rescans)*/ if (id[ID_PRODUCT] == 0x1E && id[ID_VENDOR] == 0x1F) { close(fd); continue; } + mode |= HANDLER_MOUSE; + if (id[ID_PRODUCT] != eventdevs[m].product || + id[ID_VENDOR] != eventdevs[m].vendor) { + debugf("mouse : fd %d event%d, vendor %4x product %4x\n", fd, n, id[ID_VENDOR], id[ID_PRODUCT]); + } + } + if (mode) { if (id[ID_PRODUCT] != eventdevs[m].product || id[ID_VENDOR] != eventdevs[m].vendor) { if (eventdevs[m].handle >= 0) { unregister_inputhandler(eventdevs[m].handle); close(eventdevs[m].handle); } - debugf("mouse : fd %d event%d, vendor %4x product %4x\n", fd, n, id[ID_VENDOR], id[ID_PRODUCT]); eventdevs[m].handle= fd; eventdevs[m].product = id[ID_PRODUCT]; eventdevs[m].vendor = id[ID_VENDOR]; - register_inputhandler(fd, mouse_handler, 1); - } - m++; + register_inputhandler(mode, fd, event_handler, 1); + } else + close(fd); + m++; } else close(fd); } @@ -310,12 +324,13 @@ scan_for_devs(); } -int register_inputhandler (int fd, void (*func)(int fd), int grab) +int register_inputhandler (int mode, int fd, void (*func)(int mode, int fd), int grab) { int n; for (n=0; n < EVENT_DEVS; n++) if (ihandler[n].fd == -1) { + ihandler[n].mode = mode; ihandler[n].fd = fd; ihandler[n].handler = func; ihandler[n].grab = grab; @@ -332,6 +347,7 @@ for (n = 0; n < EVENT_DEVS; n++) if (found) { + ihandler[n-1].mode = ihandler[n].mode; ihandler[n-1].fd = ihandler[n].fd; ihandler[n-1].handler = ihandler[n].handler; } else if (ihandler[n].fd == fd) { @@ -364,7 +380,7 @@ for (n=0; n < EVENT_DEVS; n++) { if (ihandler[n].fd == -1) continue; if (FD_ISSET(ihandler[n].fd, inset)) - ihandler[n].handler (ihandler[n].fd); + ihandler[n].handler (ihandler[n].mode, ihandler[n].fd); } } @@ -809,6 +825,7 @@ eventdevs[i].product= 0; ihandler[i].handler=0; + ihandler[i].mode=0; ihandler[i].fd=-1; } diff -urNad mouseemu-0.15~/mouseemu.h mouseemu-0.15/mouseemu.h --- mouseemu-0.15~/mouseemu.h 2005-03-30 07:41:00.000000000 +0100 +++ mouseemu-0.15/mouseemu.h 2007-02-08 01:59:27.000000000 +0000 @@ -33,6 +33,9 @@ #define BTN2 0x04 #define BTN3 0x02 +#define HANDLER_KEYBOARD (1 << 0) +#define HANDLER_MOUSE (1 << 1) + /* device structure */ typedef struct _kdev { int handle; @@ -42,11 +45,12 @@ /* handler structure */ typedef struct _ihandler { - void (*handler)(int fd); + void (*handler)(int mode, int fd); + int mode; int fd; int grab; } input_handler; void unregister_inputhandler (int fd); -int register_inputhandler(int fd, void (*func)(int fd), int grab); +int register_inputhandler(int mode, int fd, void (*func)(int mode, int fd), int grab); #endif