Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.1:Update
mouseemu
mouseemu.rescan.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File mouseemu.rescan.patch of Package mouseemu
#! /bin/sh /usr/share/dpatch/dpatch-run ## 61_rescan.dpatch.dpatch by Michael Schmitz <schmitz@biophys.uni-duesseldorf.de> ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: rescan event devices on disconnects @DPATCH@ --- mouseemu.8 | 16 ++++++++- mouseemu.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 102 insertions(+), 12 deletions(-) --- a/mouseemu.8 +++ b/mouseemu.8 @@ -52,13 +52,20 @@ writeable the following devices are also .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 @@ emulation for the middle button): .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 /var/run/mouseemu.pid` +.RE .SH AUTHOR Mouseemu was written by Colin Leroy .nh --- a/mouseemu.c +++ b/mouseemu.c @@ -19,6 +19,7 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <errno.h> #include <fcntl.h> #include <string.h> #include <signal.h> @@ -51,12 +52,14 @@ static int ui_keyb_fd = -1; 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 @@ void scan_for_devs() 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 @@ void scan_for_devs() 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 scan_for_devs() } } +void rescan_devs() +{ + int i, cfd; + + for (i=0; i<EVENT_DEVS; i++) { + if (ihandler[i].fd != -1) { + cfd=ihandler[i].fd; + unregister_inputhandler(ihandler[i].fd); + close(cfd); + i--; + } + } + for (i=0; i<EVENT_DEVS; i++) { + eventdevs[i].product = 0; + eventdevs[i].vendor = 0; + eventdevs[i].handle = -1; + } + usleep(100); + scan_for_devs(); +} + int register_inputhandler (int fd, void (*func)(int fd), int grab) { int n; @@ -300,7 +336,7 @@ int create_fdset (fd_set *watchset) FD_ZERO(watchset); for (maxfd=n=0; n < EVENT_DEVS; n++) { - if (ihandler[n].fd == -1) break; + if (ihandler[n].fd == -1) continue; FD_SET(ihandler[n].fd, watchset); if (ihandler[n].fd > maxfd) maxfd = ihandler[n].fd; @@ -313,7 +349,7 @@ void call_inputhandler(fd_set *inset) 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 @@ int uinput_setup(void) void uinput_cleanup() { - int i; + int i, cfd; printf("mouseemu: cleaning...\n"); @@ -470,8 +506,9 @@ void uinput_cleanup() for (i=0; i<EVENT_DEVS; i++) { if (ihandler[i].fd != -1) { + cfd=ihandler[i].fd; unregister_inputhandler(ihandler[i].fd); - close(ihandler[i].fd); + close(cfd); } } @@ -489,6 +526,11 @@ void monitor(int sig_num) { if (sig_num == SIGUSR1) { answer = 1; + } else if (sig_num == SIGHUP) { + rescan = 1; + } else if (sig_num == SIGALRM) { + rescan = 1; + alarm(5); } else { //printf("mouseemu: aborting on sig %i \n",sig_num); /*terminate the parent:*/ @@ -512,10 +554,13 @@ void install_sighandler(void) /*SIGUSR1 for process communication *SIGTERM and SIGCHLD for quitting + *SIGHUP and SIGALRM for rescaning devices */ sigaction(SIGUSR1, &usr_action, NULL); sigaction(SIGTERM, &usr_action, NULL); + sigaction(SIGHUP, &usr_action, NULL); sigaction(SIGCHLD, &usr_action, NULL); + sigaction(SIGALRM, &usr_action, NULL); sigprocmask(SIG_UNBLOCK, &mask, 0); @@ -529,7 +574,8 @@ void usage(FILE *stream, char *argv[]) { "\t[-scroll SCROLL_MOD]\n" "\t[-typing-block DELAY]\n" "\t[-device UINPUT_DEVICE]\n" - "\t[-nofork]\n", + "\t[-nofork]\n" + "\t[-autorescan]\n", argv[0]); fprintf(stream, "All modifier and button key arguments are\n" "key scancodes. They can be found in \n" @@ -643,6 +689,11 @@ int main(int argc, char *argv[]) nofork=1; i += 1; continue; + } + else if (!strcmp(argv[i], "-autorescan")) { + autorescan=1; + i += 1; + continue; } else { usage(stderr, argv); } @@ -680,8 +731,15 @@ int main(int argc, char *argv[]) * */ + struct sigaction sa; sigset_t mask, oldmask; + /* SIGHUP and SIGALRM are only useful in the child */ + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_IGN; + sigaction(SIGHUP, &sa, NULL); + sigaction(SIGALRM, &sa, NULL); + /*we start only after we received the first sigusr1 from child:*/ sigemptyset(&mask); @@ -715,6 +773,9 @@ int main(int argc, char *argv[]) //strncpy(argv[0],"mouseemu",argv0size); startops: + if (nofork) + debug = 1; + for (i=0; i<EVENT_DEVS; i++) { eventdevs[i].handle = -1; eventdevs[i].vendor = 0; @@ -737,17 +798,34 @@ startops: chdir("/"); + if (autorescan) + alarm(5); + /*main loop*/ while(running > 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? */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor