Author: Colin Watson <cjwatson@ubuntu.com>
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 
