diff --git a/srcpkgs/mouseemu/files/99-mouseemu.rules b/srcpkgs/mouseemu/files/99-mouseemu.rules new file mode 100644 index 00000000000..9e0358725be --- /dev/null +++ b/srcpkgs/mouseemu/files/99-mouseemu.rules @@ -0,0 +1,3 @@ +# Send mouseemu a HUP signal if a new event device is connected + +ACTION=="add", KERNEL=="event[0-9]*", RUN+="/bin/sh -c '/bin/kill -HUP $$(pidof mouseemu)'" diff --git a/srcpkgs/mouseemu/files/mouseemu/conf b/srcpkgs/mouseemu/files/mouseemu/conf new file mode 100644 index 00000000000..4ae9e8d7436 --- /dev/null +++ b/srcpkgs/mouseemu/files/mouseemu/conf @@ -0,0 +1,12 @@ +# Taken from Debian. +# These are the default values on PowerPC. On all other architectures +# middle and right click are disabled by default. +# Key codes can be found in include/linux/input.h in the kernel headers +# or by using `showkey` in a console. + +#MID_CLICK="-middle 0 68" # F10 with no modifier +#MID_CLICK="-middle 125 272" # Left Apple Key (LEFTMETA) + click +#RIGHT_CLICK="-right 0 87" # F11 with no modifier +#RIGHT_CLICK="-right 29 272" # Left Ctrl + click +#SCROLL="-scroll 56" # Alt key +#TYPING_BLOCK="-typing-block 300" # block mouse for 300ms after a keypress diff --git a/srcpkgs/mouseemu/files/mouseemu/run b/srcpkgs/mouseemu/files/mouseemu/run new file mode 100644 index 00000000000..1ce7c17df5e --- /dev/null +++ b/srcpkgs/mouseemu/files/mouseemu/run @@ -0,0 +1,3 @@ +#!/bin/sh +[ -r conf ] && . ./conf +exec mouseemu -nofork $MID_CLICK $RIGHT_CLICK $SCROLL $TYPING_BLOCK diff --git a/srcpkgs/mouseemu/patches/001-nofork.patch b/srcpkgs/mouseemu/patches/001-nofork.patch new file mode 100644 index 00000000000..0ae248d2872 --- /dev/null +++ b/srcpkgs/mouseemu/patches/001-nofork.patch @@ -0,0 +1,13 @@ +Author: +Description: Don't kill ourselves if not forking into the background +--- a/mouseemu.c ++++ b/mouseemu.c +@@ -706,7 +706,7 @@ + } + /* tell the parent we are running without problems */ + /* What should we do if the parent is dead? */ +- if (answer) { ++ if (answer && !nofork) { + answer=0; + kill(getppid(), SIGUSR1); + } diff --git a/srcpkgs/mouseemu/patches/002-mod-passthrough.patch b/srcpkgs/mouseemu/patches/002-mod-passthrough.patch new file mode 100644 index 00000000000..31175c32d7a --- /dev/null +++ b/srcpkgs/mouseemu/patches/002-mod-passthrough.patch @@ -0,0 +1,13 @@ +Author: +Description: Pass through key events of modifier keys +--- a/mouseemu.c ++++ b/mouseemu.c +@@ -174,7 +174,7 @@ + /* 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 && !b2_mod_pressed && !b3_mod_pressed) { ++ if (inp.code != b2_key && inp.code != b3_key) { + passthrough(ui_keyb_fd, inp); + } + } diff --git a/srcpkgs/mouseemu/patches/003-usage.patch b/srcpkgs/mouseemu/patches/003-usage.patch new file mode 100644 index 00000000000..16fd7203ce6 --- /dev/null +++ b/srcpkgs/mouseemu/patches/003-usage.patch @@ -0,0 +1,143 @@ +Author: +Description: print usage message to stderr for wrong arguments +--- a/mouseemu.c ++++ b/mouseemu.c +@@ -517,6 +517,31 @@ + + } + ++/* print usage message to stdout/stderr */ ++void usage(FILE *stream, char *argv[]) { ++ fprintf(stream, "usage: %s \n" ++ "\t[-middle B2_MOD B2_KEY]\n" ++ "\t[-right B3_MOD B3_KEY]\n" ++ "\t[-scroll SCROLL_MOD]\n" ++ "\t[-typing-block DELAY]\n" ++ "\t[-device UINPUT_DEVICE]\n" ++ "\t[-nofork]\n", ++ argv[0]); ++ fprintf(stream, "All modifier and button key arguments are\n" ++ "key scancodes. They can be found in \n" ++ "/usr/src/linux/include/linux/input.h,\n" ++ "or by using `showkey` in a console.\n" ++ "Use decimal values. BTN_LEFT(272) is usable as " ++ "B2_KEY or B3_KEY.\n\n"); ++ fprintf(stream, "Default uinput device: " DEFAULT_UINPUT ".\n"); ++ fprintf(stream, "Default keys:\n" ++ "\tMiddle click : F10 (0 68)\n" ++ "\tRight click : F11 (0 87)\n" ++ "\tScroll mod. : Alt (56)\n" ++ "\tDefault blocking time while typing: 300ms\n"); ++ ++ exit(0); ++} + + int main(int argc, char *argv[]) + { +@@ -535,72 +560,59 @@ + if (argc > 1) { + int i = 0; + if (!strcmp(argv[1],"-help")) { +-err: +- printf("usage: %s \n" +- "\t[-middle B2_MOD B2_KEY]\n" +- "\t[-right B3_MOD B3_KEY]\n" +- "\t[-scroll SCROLL_MOD]\n" +- "\t[-typing-block DELAY]\n" +- "\t[-device UINPUT_DEVICE]\n" +- "\t[-nofork]\n", +- argv[0]); +- printf("Key codes can be found in " +- "/usr/src/linux/include/linux/input.h,\n" +- "or by using `showkey` in console.\n" +- "Use decimal values. BTN_LEFT(272) is usable as " +- "B2_KEY or B3_KEY.\n\n"); +- printf("Default uinput device: " DEFAULT_UINPUT ".\n"); +- printf("Default keys:\n" +- "\tMiddle click : F10 (0 68)\n" +- "\tRight click : F11 (0 87)\n" +- "\tScroll mod. : Alt (56)\n" +- "\tDefault blocking time while typing: 300ms\n"); +- +- exit(0); ++ usage(stdout, argv); + } else { +- for (i = 1; i < argc; i++) { +- int j = i+1; ++ i = 1; ++ while (i < argc) { + if (!strcmp(argv[i], "-middle")) { +- if (argc > j+1) { +- b2_mod = atoi(argv[j]); +- b2_key = atoi(argv[j+1]); ++ if (argc > i+2) { ++ b2_mod = atoi(argv[i+1]); ++ b2_key = atoi(argv[i+2]); ++ i += 3; + } else +- goto err; ++ usage(stderr, argv); + continue; + } +- if (!strcmp(argv[i], "-right")) { +- if (argc > j+1) { +- b3_mod = atoi(argv[j]); +- b3_key = atoi(argv[j+1]); ++ else if (!strcmp(argv[i], "-right")) { ++ if (argc > i+2) { ++ b3_mod = atoi(argv[i+1]); ++ b3_key = atoi(argv[i+2]); ++ i += 3; + } else +- goto err; ++ usage(stderr, argv); + continue; + } +- if (!strcmp(argv[i], "-scroll")) { +- if (argc > j) { +- scroll_mod = atoi(argv[j]); ++ else if (!strcmp(argv[i], "-scroll")) { ++ if (argc > i+1) { ++ scroll_mod = atoi(argv[i+1]); ++ i += 2; + } else +- goto err; ++ usage(stderr, argv); + continue; + } +- if (!strcmp(argv[i], "-typing-block")) { +- if (argc > j) { +- typing_block_delay = atoi(argv[j]); ++ else if (!strcmp(argv[i], "-typing-block")) { ++ if (argc > i+1) { ++ typing_block_delay = atoi(argv[i+1]); ++ i += 2; + } else +- goto err; ++ usage(stderr, argv); + continue; + } +- if (!strcmp(argv[i], "-device")) { +- if (argc > j) { +- uinputdev = argv[j]; ++ else if (!strcmp(argv[i], "-device")) { ++ if (argc > i+1) { ++ uinputdev = argv[i+1]; ++ i += 2; + } else +- goto err; ++ usage(stderr, argv); + continue; + } +- if (!strcmp(argv[i], "-nofork")) { ++ else if (!strcmp(argv[i], "-nofork")) { + nofork=1; ++ i += 1; + continue; +- } ++ } else { ++ usage(stderr, argv); ++ } + } + } + } diff --git a/srcpkgs/mouseemu/patches/004-defaults.patch b/srcpkgs/mouseemu/patches/004-defaults.patch new file mode 100644 index 00000000000..79bd9345654 --- /dev/null +++ b/srcpkgs/mouseemu/patches/004-defaults.patch @@ -0,0 +1,70 @@ +Author: +Description: change defaults to not emaulate mouse buttons for \!powerpc +--- a/mouseemu.c ++++ b/mouseemu.c +@@ -24,11 +24,15 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include "mouseemu.h" + #include "defkeys.h" + ++static int use_defaults = 0; ++ + static int b2_mod = BUTTON2MOD; + static int b2_key = BUTTON2KEY; + +@@ -534,10 +538,16 @@ + "Use decimal values. BTN_LEFT(272) is usable as " + "B2_KEY or B3_KEY.\n\n"); + fprintf(stream, "Default uinput device: " DEFAULT_UINPUT ".\n"); +- fprintf(stream, "Default keys:\n" ++ fprintf(stream, "Default keys:\n"); ++ if (use_defaults) ++ fprintf(stream, + "\tMiddle click : F10 (0 68)\n" +- "\tRight click : F11 (0 87)\n" +- "\tScroll mod. : Alt (56)\n" ++ "\tRight click : F11 (0 87)\n"); ++ else ++ fprintf(stream, ++ "\tMiddle click : none (0 0)\n" ++ "\tRight click : none (0 0)\n"); ++ fprintf(stream, "\tScroll mod. : Alt (56)\n" + "\tDefault blocking time while typing: 300ms\n"); + + exit(0); +@@ -556,6 +566,29 @@ + + install_sighandler(); + ++#ifdef __powerpc__ ++ use_defaults = 1; ++#else ++#if defined(__i386__) || defined(__amd64__) ++ { ++ FILE *dmidecode; ++ char line[1024]; ++ dmidecode = popen("dmidecode -s system-manufacturer 2>/dev/null", "r"); ++ if (dmidecode) { ++ if (fgets(line, 1024, dmidecode) && !strncmp(line, "Apple", 5)) ++ use_defaults = 1; ++ pclose(dmidecode); ++ } ++ } ++#endif ++#endif ++ if (!use_defaults) { ++ b2_mod = 0; ++ b2_key = 0; ++ b3_mod = 0; ++ b3_key = 0; ++ } ++ + uinputdev = DEFAULT_UINPUT; + if (argc > 1) { + int i = 0; diff --git a/srcpkgs/mouseemu/patches/005-manpage.patch b/srcpkgs/mouseemu/patches/005-manpage.patch new file mode 100644 index 00000000000..a56887534a5 --- /dev/null +++ b/srcpkgs/mouseemu/patches/005-manpage.patch @@ -0,0 +1,54 @@ +Author: +Description: add default values and information about keycodes to manpage +--- a/mouseemu.8 ++++ b/mouseemu.8 +@@ -30,22 +30,45 @@ + .SH OPTIONS + .TP + .B -middle B2_MOD B2_KEY +-modifier and key for the middle (second) mouse button ++Modifier and key for the middle (second) mouse button. Defaults to F10 and no modifier ++on PowerPC and Intel Macs, and to none on all other architectures. + .TP + .B -right B3_MOD B3_KEY +-modifier and key for the right (third) mouse button ++Modifier and key for the right (third) mouse button. Defaults to F11 and no modifier ++on PowerPC and Intel Macs, and to none on all other architectures. + .TP + .B -scroll SCROLL_MOD +-modifier for the scrolling function ++Modifier for the scrolling function. Defaults to Alt. + .TP + .B -typing-block DELAY + Time in milliseconds for which the trackpad will be blocked while typing on the keyboard. ++Defaults to 300ms. + .TP + .B -device UINPUT +-device node for the uinput device ++Device node for the uinput device. Defaults to /dev/uinput. If this device is not read and ++writeable the following devices are also tried: /dev/uinput, /dev/input/uinput and ++/dev/misc/uinput. + .TP + .B -nofork + don't run in the background ++.TP ++.B -help ++show usage message ++.PP ++The key codes for the buttons and modifiers are key scancodes. They can be found in ++include/linux/input.h in the kernel headers or by using `showkey` in a console. The ++keycodes must be given as decimal values (`showkey` displays hex values!). ++ ++.SH EXAMPLES ++.PP ++To have the same behaviour as in MacOS X (CTRL-click for right mouse button and no ++emulation for the middle button): ++.PP ++.RS 4 ++.B mouseemu -middle 0 0 -right 29 272 ++.RE ++.PP ++The code for the (left) mouse button is 272 (0x110 in hex). The code for CTRL is 29. + + .SH AUTHOR + Mouseemu was written by Colin Leroy diff --git a/srcpkgs/mouseemu/patches/006-rescan.patch b/srcpkgs/mouseemu/patches/006-rescan.patch new file mode 100644 index 00000000000..8cb343e7048 --- /dev/null +++ b/srcpkgs/mouseemu/patches/006-rescan.patch @@ -0,0 +1,288 @@ +Author: Michael Schmitz +Description: rescan event devices on disconnects + +Note @q66: modified to use /run instead of /var/run + +--- a/mouseemu.8 ++++ b/mouseemu.8 +@@ -52,13 +52,20 @@ + .B -nofork + don't run in the background + .TP ++.B -autorescan ++Automatically scan every 5s for new devices. This is normally not need, as udev should ++inform mouseemu about new devices. ++.TP + .B -help + show usage message + .PP + The key codes for the buttons and modifiers are key scancodes. They can be found in + include/linux/input.h in the kernel headers or by using `showkey` in a console. The + keycodes must be given as decimal values (`showkey` displays hex values!). +- ++.PP ++Mouseemu does normally not automatically scan for new devices. An udev rule is used ++to trigger a rescan when new devices are connected. You can also trigger a rescan ++manually by sending a HUP signal to the mouseemu process. + .SH EXAMPLES + .PP + To have the same behaviour as in MacOS X (CTRL-click for right mouse button and no +@@ -69,7 +76,12 @@ + .RE + .PP + The code for the (left) mouse button is 272 (0x110 in hex). The code for CTRL is 29. +- ++.PP ++Trigger a rescan for newly attached devices: ++.PP ++.RS 4 ++.B kill -HUP `cat /run/mouseemu.pid` ++.RE + .SH AUTHOR + Mouseemu was written by Colin Leroy + .nh +--- a/mouseemu.c ++++ b/mouseemu.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -51,12 +52,14 @@ + + static int running = -1; + volatile sig_atomic_t answer = 1; ++volatile sig_atomic_t rescan = 0; + pid_t pid = -1; +-#define EVENT_DEVS 6 ++#define EVENT_DEVS 32 + static kdev eventdevs[EVENT_DEVS]; + static input_handler ihandler[EVENT_DEVS]; + +- ++static int debug = 0; ++static int autorescan = 0; + + static void send_event(int fd, int type, int code, int value) + { +@@ -224,12 +227,18 @@ + ioctl(fd, EVIOCGBIT(0, EV_MAX), bit); + 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; ++ } + 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); + } ++ if (debug) fprintf(stderr, "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]; +@@ -238,12 +247,18 @@ + m++; + } else if (test_bit(EV_REL, bit)) { + ioctl(fd, EVIOCGID, id); ++ /* our own virtual mouse (on rescans)*/ ++ if (id[ID_PRODUCT] == 0x1E && id[ID_VENDOR] == 0x1F) { ++ close(fd); ++ continue; ++ } + 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); + } ++ if (debug) fprintf(stderr, "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]; +@@ -261,6 +276,27 @@ + } + } + ++void rescan_devs() ++{ ++ int i, cfd; ++ ++ for (i=0; i maxfd) + maxfd = ihandler[n].fd; +@@ -313,7 +349,7 @@ + int n; + + for (n=0; n < EVENT_DEVS; n++) { +- if (ihandler[n].fd == -1) break; ++ if (ihandler[n].fd == -1) continue; + if (FD_ISSET(ihandler[n].fd, inset)) + ihandler[n].handler (ihandler[n].fd); + } +@@ -461,7 +497,7 @@ + + void uinput_cleanup() + { +- int i; ++ int i, cfd; + + printf("mouseemu: cleaning...\n"); + +@@ -470,8 +506,9 @@ + + for (i=0; i 0) { + + tv.tv_sec = 1; tv.tv_usec = 0; + maxfd = create_fdset(&inset); +- if ((val = select (maxfd+1, &inset, NULL, NULL, &tv)) >= 0) { ++ val = select (maxfd+1, &inset, NULL, NULL, &tv); ++ /* signal received, so rescan for devices when idle*/ ++ if (val == 0 && rescan) { ++ rescan = 0; ++ rescan_devs(); ++ } ++ if (val >= 0) { + if (val == 0) + usleep(10); +- else +- call_inputhandler(&inset); ++ else { ++ if (errno == ENODEV) { ++ if (debug) fprintf(stderr, "select returned %d, errno %d, rescanning devices\n", val, errno); ++ errno = 0; ++ rescan_devs(); ++ usleep(500); ++ } else { ++ call_inputhandler(&inset); ++ } ++ } + } + /* tell the parent we are running without problems */ + /* What should we do if the parent is dead? */ diff --git a/srcpkgs/mouseemu/patches/007-syslog.patch b/srcpkgs/mouseemu/patches/007-syslog.patch new file mode 100644 index 00000000000..1a340eb611a --- /dev/null +++ b/srcpkgs/mouseemu/patches/007-syslog.patch @@ -0,0 +1,216 @@ +Author: Michael Schmitz +Description: log to syslog instead of stderr +--- a/mouseemu.8 ++++ b/mouseemu.8 +@@ -56,6 +56,9 @@ + Automatically scan every 5s for new devices. This is normally not need, as udev should + inform mouseemu about new devices. + .TP ++.B -debug ++print debugging messages about device scans ++.TP + .B -help + show usage message + .PP +--- a/mouseemu.c ++++ b/mouseemu.c +@@ -18,12 +18,14 @@ + + #include + #include ++#include + #include + #include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -61,6 +63,17 @@ + static int debug = 0; + static int autorescan = 0; + ++/* print debug messages to syslog or stderr */ ++void debugf(const char *format, ...) { ++ va_list ap; ++ ++ if (debug) { ++ va_start(ap, format); ++ vsyslog(LOG_DEBUG, format, ap); ++ va_end(ap); ++ } ++} ++ + static void send_event(int fd, int type, int code, int value) + { + struct input_event event; +@@ -238,7 +251,7 @@ + unregister_inputhandler(eventdevs[m].handle); + close(eventdevs[m].handle); + } +- if (debug) fprintf(stderr, "keyboard: fd %d event%d, vendor %4x product %4x\n", fd, n, id[ID_VENDOR], id[ID_PRODUCT]); ++ 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]; +@@ -258,7 +271,7 @@ + unregister_inputhandler(eventdevs[m].handle); + close(eventdevs[m].handle); + } +- if (debug) fprintf(stderr, "mouse : fd %d event%d, vendor %4x product %4x\n", fd, n, id[ID_VENDOR], id[ID_PRODUCT]); ++ 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]; +@@ -373,27 +386,27 @@ + { + int fd = -1; + +- printf("Trying to open %s...", uinputdev); ++ syslog(LOG_NOTICE, "Trying to open %s...", uinputdev); + fd = open (uinputdev, O_RDWR); +- printf(" %s.\n", (fd > 0)?"ok":"error"); ++ syslog(LOG_NOTICE, " %s.\n", (fd > 0)?"ok":"error"); + if (fd > 0) + return fd; + +- printf("Trying to open /dev/uinput..."); ++ syslog(LOG_NOTICE, "Trying to open /dev/uinput..."); + fd = open("/dev/uinput", O_RDWR); +- printf(" %s.\n", (fd > 0)?"ok":"error"); ++ syslog(LOG_NOTICE, " %s.\n", (fd > 0)?"ok":"error"); + if (fd > 0) + return fd; + +- printf("Trying to open /dev/input/uinput..."); ++ syslog(LOG_NOTICE, "Trying to open /dev/input/uinput..."); + fd = open("/dev/input/uinput", O_RDWR); +- printf(" %s.\n", (fd > 0)?"ok":"error"); ++ syslog(LOG_NOTICE, " %s.\n", (fd > 0)?"ok":"error"); + if (fd > 0) + return fd; + +- printf("Trying to open /dev/misc/uinput..."); ++ syslog(LOG_NOTICE, "Trying to open /dev/misc/uinput..."); + fd = open("/dev/misc/uinput", O_RDWR); +- printf(" %s.\n", (fd > 0)?"ok":"error"); ++ syslog(LOG_NOTICE, " %s.\n", (fd > 0)?"ok":"error"); + if (fd > 0) + return fd; + +@@ -499,7 +512,7 @@ + { + int i, cfd; + +- printf("mouseemu: cleaning...\n"); ++ syslog(LOG_NOTICE, "mouseemu: cleaning...\n"); + + uinput_close(ui_keyb_fd); + uinput_close(ui_mouse_fd); +@@ -575,7 +588,8 @@ + "\t[-typing-block DELAY]\n" + "\t[-device UINPUT_DEVICE]\n" + "\t[-nofork]\n" +- "\t[-autorescan]\n", ++ "\t[-autorescan]\n" ++ "\t[-debug]\n", + argv[0]); + fprintf(stream, "All modifier and button key arguments are\n" + "key scancodes. They can be found in \n" +@@ -608,8 +622,6 @@ + int nofork = 0; + //int argv0size = strlen(argv[0]); + +- printf("mouseemu " VERSION " (C) Colin Leroy \n"); +- + install_sighandler(); + + #ifdef __powerpc__ +@@ -694,23 +706,33 @@ + autorescan=1; + i += 1; + continue; ++ } ++ else if (!strcmp(argv[i], "-debug")) { ++ debug=1; ++ i += 1; ++ continue; + } else { + usage(stderr, argv); + } + } + } + } +- printf("using (%d+%d) as middle button, (%d+%d) as right button, (%d) as scroll.\n", ++ ++ if (nofork) ++ openlog("mouseemu", LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_DAEMON); ++ else ++ openlog("mouseemu", LOG_NDELAY | LOG_PID, LOG_DAEMON); ++ ++ syslog(LOG_NOTICE, "mouseemu " VERSION " (C) Colin Leroy \n"); ++ syslog(LOG_NOTICE, "using (%d+%d) as middle button, (%d+%d) as right button, (%d) as scroll.\n", + b2_mod, b2_key, b3_mod, b3_key, scroll_mod); +- printf("using %s.\n", uinputdev); + +- + if (nofork) + goto startops; + + fpid = fork(); + if (fpid == -1) { +- printf("can't fork\n"); ++ syslog(LOG_NOTICE, "can't fork\n"); + goto startops; + } + if (fpid != 0) { +@@ -720,7 +742,7 @@ + setsid(); + pid = fork(); + if (pid == -1) { +- printf("can't fork\n"); ++ syslog(LOG_NOTICE, "can't fork\n"); + goto startops; + } + +@@ -761,7 +783,7 @@ + } + + } +- printf("terminating, %i\n",answer); ++ syslog(LOG_NOTICE, "terminating, %i\n",answer); + if (kill(pid, SIGTERM)<0) + perror("mouseemu: termination of uinput handlers failed\n"); + +@@ -773,8 +795,6 @@ + + //strncpy(argv[0],"mouseemu",argv0size); + startops: +- if (nofork) +- debug = 1; + + for (i=0; i +Description: create pidfile in /run/mouseemu.pid + +Note @q66: modified to use /run instead of /var/run + +--- a/mouseemu.c ++++ b/mouseemu.c +@@ -755,6 +755,7 @@ + + struct sigaction sa; + sigset_t mask, oldmask; ++ FILE *pidfile; + + /* SIGHUP and SIGALRM are only useful in the child */ + memset(&sa, 0, sizeof(sa)); +@@ -762,6 +763,15 @@ + sigaction(SIGHUP, &sa, NULL); + sigaction(SIGALRM, &sa, NULL); + ++ /* write PID file so the user can signal us for device rescans */ ++ pidfile = fopen("/run/mouseemu.pid", "w"); ++ if (!pidfile) { ++ perror("mouseemu: can't open /run/mouseemu.pid"); ++ exit(1); ++ } ++ fprintf(pidfile, "%d\n", pid); ++ fclose(pidfile); ++ + /*we start only after we received the first sigusr1 from child:*/ + + sigemptyset(&mask); diff --git a/srcpkgs/mouseemu/patches/009-uinput_error_msg.patch b/srcpkgs/mouseemu/patches/009-uinput_error_msg.patch new file mode 100644 index 00000000000..5fc51c3234d --- /dev/null +++ b/srcpkgs/mouseemu/patches/009-uinput_error_msg.patch @@ -0,0 +1,15 @@ +Author: +Description: send error message to stderr if no uinput device is found +--- a/mouseemu.c ++++ b/mouseemu.c +@@ -821,8 +821,8 @@ + + running = uinput_setup(); + if (running < 0) { +- syslog(LOG_NOTICE, "Make sure uinput module is loaded or available " +- "in the kernel.\n"); ++ fprintf(stderr, "No uinput device found! Make sure the uinput module is loaded\n" ++ "or CONFIG_INPUT_UINPUT is compiled into the kernel.\n"); + } + + diff --git a/srcpkgs/mouseemu/patches/010-initialize_device.patch b/srcpkgs/mouseemu/patches/010-initialize_device.patch new file mode 100644 index 00000000000..e9eeea9cb99 --- /dev/null +++ b/srcpkgs/mouseemu/patches/010-initialize_device.patch @@ -0,0 +1,13 @@ +Author: +Description: Intialize all fields in uinput_user_dev, otherwise strange things +like dead keyboard, etc. might happen +--- a/mouseemu.c ++++ b/mouseemu.c +@@ -418,6 +418,7 @@ + struct uinput_user_dev device; + int i; + ++ memset(&device, 0, sizeof(struct uinput_user_dev)); + /*setup keyboard device */ + + if(ui_keyb_fd > 0) { diff --git a/srcpkgs/mouseemu/patches/011-write_error.patch b/srcpkgs/mouseemu/patches/011-write_error.patch new file mode 100644 index 00000000000..f308fb63e9c --- /dev/null +++ b/srcpkgs/mouseemu/patches/011-write_error.patch @@ -0,0 +1,13 @@ +Author: +Description: Fix write error detection +--- a/mouseemu.c ++++ b/mouseemu.c +@@ -92,7 +92,7 @@ + + static void passthrough(int fd, struct input_event event) + { +- if (write(fd, &event, sizeof(event)) < sizeof(event)) ++ if (write(fd, &event, sizeof(event)) <= 0) + perror("passthrough error"); + + } diff --git a/srcpkgs/mouseemu/patches/012-bustype_virtual.patch b/srcpkgs/mouseemu/patches/012-bustype_virtual.patch new file mode 100644 index 00000000000..6ce7b5a7652 --- /dev/null +++ b/srcpkgs/mouseemu/patches/012-bustype_virtual.patch @@ -0,0 +1,32 @@ +Author: Colin Watson +Description: No description. +--- a/mouseemu.c ++++ b/mouseemu.c +@@ -30,6 +30,9 @@ + #include + #include + #include ++#ifndef BUS_VIRTUAL /* new in Linux 2.6.19 */ ++#define BUS_VIRTUAL 0x06 ++#endif + #include + #include "mouseemu.h" + #include "defkeys.h" +@@ -434,7 +437,7 @@ + + strcpy(device.name, "Mouseemu virtual keyboard"); + +- device.id.bustype = 0; ++ device.id.bustype = BUS_VIRTUAL; + device.id.vendor = 0x1F; + device.id.product = 0x1F; + device.id.version = 0; +@@ -476,7 +479,7 @@ + + strcpy(device.name, "Mouseemu virtual mouse"); + +- device.id.bustype = 0; ++ device.id.bustype = BUS_VIRTUAL; + device.id.vendor = 0x1F; + device.id.product = 0x1E; + device.id.version = 0; diff --git a/srcpkgs/mouseemu/patches/013-dual_devices.patch b/srcpkgs/mouseemu/patches/013-dual_devices.patch new file mode 100644 index 00000000000..cdce7506c7c --- /dev/null +++ b/srcpkgs/mouseemu/patches/013-dual_devices.patch @@ -0,0 +1,235 @@ +Author: Colin Watson +Description: No description. +--- a/mouseemu.c ++++ b/mouseemu.c +@@ -187,52 +187,68 @@ + } + } + +-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) { ++ passthrough(ui_keyb_fd, inp); ++ 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 +256,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); + } +@@ -313,12 +329,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; +@@ -335,6 +352,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) { +@@ -367,7 +385,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); + } + } + +@@ -816,6 +834,7 @@ + eventdevs[i].product= 0; + + ihandler[i].handler=0; ++ ihandler[i].mode=0; + ihandler[i].fd=-1; + } + +--- a/mouseemu.h ++++ b/mouseemu.h +@@ -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 diff --git a/srcpkgs/mouseemu/template b/srcpkgs/mouseemu/template new file mode 100644 index 00000000000..bdb756ec266 --- /dev/null +++ b/srcpkgs/mouseemu/template @@ -0,0 +1,36 @@ +# Template file for 'mouseemu' +pkgname=mouseemu +version=0.15 +revision=1 +wrksrc=${pkgname} +depends="procps-ng" +short_desc="Emulate mouse buttons and mouse wheel" +maintainer="q66 " +license="GPL-2.0-or-later" +homepage="http://geekounet.org/powerbook/" +distfiles="http://deb.debian.org/debian/pool/main/m/${pkgname}/${pkgname}_${version}.orig.tar.gz" +checksum=bbef220a814931f8ee482c82dfd63ad0a8ec895fc7df7bac1a1ada880d59af59 +conf_files="/etc/sv/mouseemu/conf" +patch_args="-Np1" + +case "$XBPS_TARGET_MACHINE" in + x86_64*|i686*) depends+=" dmidecode";; +esac + +post_patch() { + # No sbin in void + vsed -i 's,usr/sbin,usr/bin,g' Makefile +} + +do_build() { + # build it ourselves because no point in patching the makefile... + # but let the makefile install + ${CC} ${CFLAGS} ${LDFLAGS} -o mouseemu mouseemu.c +} + +do_install() { + vinstall ${FILESDIR}/99-mouseemu.rules 644 usr/lib/udev/rules.d/ + vbin mouseemu + vman mouseemu.8 + vsv mouseemu +}