--- Begin Message ---
- To: submit@bugs.debian.org
- Subject: mouseemu: pass through mouse buttons / relative events that mouseemu doesn't understand
- From: Colin Watson <cjwatson@ubuntu.com>
- Date: Fri, 28 Aug 2009 09:36:24 +0100
- Message-id: <20090828083624.GB13423@riva.ucam.org>
Package: mouseemu
Version: 0.15-8
Severity: normal
Tags: patch
User: ubuntu-devel@lists.ubuntu.com
Usertags: origin-ubuntu ubuntu-patch karmic
We've been installing mouseemu by default on Intel Macs in Ubuntu for a
while (which is probably overkill, but that's a separate bug), and
apparently this causes problems when the user actually has a mouse with
more than three buttons. Here's the text of the original report
(https://bugs.launchpad.net/ubuntu/+source/mouseemu/+bug/419947):
Mouseemu creates an emulated "3-button scroll" mouse, i.e. left and
right buttons, plus a clickable scrollwheel. This is useful when
running on a system with this many buttons or less (e.g. a laptop
touchpad)
Unfortunately, mouseemu also swallows all events from the system's
"real" mouse, including events caused by buttons outside the
3-button-scroll limitation. As a result, if your system has more
buttons (e.g. side buttons, or a wheel with horizontal scroll) then
the extra buttons are not used, as mouseemu does not forward those
events.
I've attached a dpatch to fix this; obviously it would also need to be
added to 00list etc.
Thanks,
--
Colin Watson [cjwatson@ubuntu.com]
#! /bin/sh /usr/share/dpatch/dpatch-run
## more_mouse_buttons.dpatch by Colin Watson <cjwatson@ubuntu.com>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Pass through any additional mouse buttons supported by real mouse
## DP: devices on the system.
@DPATCH@
diff -urNad mouseemu-0.16~/mouseemu.c mouseemu-0.16/mouseemu.c
--- mouseemu-0.16~/mouseemu.c 2009-08-27 20:18:25.000000000 +0100
+++ mouseemu-0.16/mouseemu.c 2009-08-27 20:22:25.000000000 +0100
@@ -209,7 +209,7 @@
{
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)
+ if (inp.type == EV_KEY && (inp.code < BTN_MISC || inp.code >= KEY_OK))
return;
if (inp.type == EV_KEY && inp.code == BTN_LEFT) {
@@ -227,7 +227,8 @@
//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)
+ || inp.type == EV_REL
+ || (inp.type == EV_KEY && inp.code != BTN_MIDDLE && inp.code != BTN_RIGHT))
passthrough(ui_mouse_fd, inp);
}
}
@@ -254,8 +255,11 @@
for (n = 0, m = 0; n < EVENT_DEVS; n++) {
sprintf(filename, "/dev/input/event%d", n);
if ((fd = open(filename, O_RDONLY)) >= 0) {
+ unsigned long mousebtns[NBITS(KEY_MAX)], mouserels[NBITS(REL_MAX)];
+ memset(mousebtns, 0, sizeof(mousebtns));
+ memset(mouserels, 0, sizeof(mouserels));
mode = 0;
- ioctl(fd, EVIOCGBIT(0, EV_MAX), bit);
+ ioctl(fd, EVIOCGBIT(0, sizeof(bit)), bit);
ioctl(fd, EVIOCGID, id);
if (test_bit(EV_KEY, bit) && test_bit(EV_REP, bit)) {
/* our own virtual keyboard (on rescans)*/
@@ -270,6 +274,7 @@
}
}
if (test_bit(EV_REL, bit)) {
+ int i;
/* our own virtual mouse (on rescans)*/
if (id[ID_PRODUCT] == 0x1E && id[ID_VENDOR] == 0x1F) {
close(fd);
@@ -280,6 +285,16 @@
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]);
}
+ ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(mousebtns)), mousebtns);
+ debugf("mouse : buttons:\n");
+ for (i = BTN_MISC; i < KEY_OK; ++i)
+ if (((unsigned char *)mousebtns)[i / 8] & (1 << (i % 8)))
+ debugf(" 0x%x\n", i);
+ ioctl(fd, EVIOCGBIT(EV_REL, sizeof(mouserels)), mouserels);
+ debugf("mouse : relative events:\n");
+ for (i = REL_X; i <= REL_MAX; ++i)
+ if (((unsigned char *)mouserels)[i / 8] & (1 << (i % 8)))
+ debugf(" 0x%x\n", i);
}
if (mode) {
if (id[ID_PRODUCT] != eventdevs[m].product ||
@@ -291,6 +306,8 @@
eventdevs[m].handle= fd;
eventdevs[m].product = id[ID_PRODUCT];
eventdevs[m].vendor = id[ID_VENDOR];
+ memcpy(eventdevs[m].mousebtns, mousebtns, sizeof(mousebtns));
+ memcpy(eventdevs[m].mouserels, mouserels, sizeof(mouserels));
register_inputhandler(mode, fd, event_handler, 1);
} else
close(fd);
@@ -303,6 +320,8 @@
eventdevs[m].product = 0;
eventdevs[m].vendor = 0;
eventdevs[m].handle = -1;
+ memset(eventdevs[m].mousebtns, 0, sizeof(eventdevs[m].mousebtns));
+ memset(eventdevs[m].mouserels, 0, sizeof(eventdevs[m].mouserels));
}
}
@@ -322,6 +341,8 @@
eventdevs[i].product = 0;
eventdevs[i].vendor = 0;
eventdevs[i].handle = -1;
+ memset(eventdevs[i].mousebtns, 0, sizeof(eventdevs[i].mousebtns));
+ memset(eventdevs[i].mouserels, 0, sizeof(eventdevs[i].mouserels));
}
usleep(100);
scan_for_devs();
@@ -435,7 +456,7 @@
int uinput_setup(void)
{
struct uinput_user_dev device;
- int i;
+ int i, j;
memset(&device, 0, sizeof(struct uinput_user_dev));
/*setup keyboard device */
@@ -518,10 +539,32 @@
ioctl(ui_mouse_fd, UI_SET_RELBIT, REL_X);
ioctl(ui_mouse_fd, UI_SET_RELBIT, REL_Y);
ioctl(ui_mouse_fd, UI_SET_RELBIT, REL_WHEEL);
+ for (i = REL_X; i <= REL_MAX; ++i) {
+ if (i == REL_X || i == REL_Y || i == REL_WHEEL)
+ continue;
+ for (j = 0; j < EVENT_DEVS; ++j) {
+ if (((unsigned char *)eventdevs[j].mouserels)[i / 8] & (1 << (i % 8))) {
+ debugf("Enabling additional relative event 0x%x\n", i);
+ ioctl(ui_mouse_fd, UI_SET_RELBIT, i);
+ break;
+ }
+ }
+ }
ioctl(ui_mouse_fd, UI_SET_KEYBIT, BTN_LEFT);
ioctl(ui_mouse_fd, UI_SET_KEYBIT, BTN_RIGHT);
ioctl(ui_mouse_fd, UI_SET_KEYBIT, BTN_MIDDLE);
+ for (i = BTN_MISC; i < KEY_OK; ++i) {
+ if (i == BTN_LEFT || i == BTN_RIGHT || i == BTN_MIDDLE)
+ continue;
+ for (j = 0; j < EVENT_DEVS; ++j) {
+ if (((unsigned char *)eventdevs[j].mousebtns)[i / 8] & (1 << (i % 8))) {
+ debugf("Enabling additional button 0x%x\n", i);
+ ioctl(ui_mouse_fd, UI_SET_KEYBIT, i);
+ break;
+ }
+ }
+ }
ioctl(ui_mouse_fd, UI_DEV_CREATE, NULL);
@@ -830,6 +873,8 @@
eventdevs[i].handle = -1;
eventdevs[i].vendor = 0;
eventdevs[i].product= 0;
+ memset(eventdevs[i].mousebtns, 0, sizeof(eventdevs[i].mousebtns));
+ memset(eventdevs[i].mouserels, 0, sizeof(eventdevs[i].mouserels));
ihandler[i].handler=0;
ihandler[i].mode=0;
diff -urNad mouseemu-0.16~/mouseemu.h mouseemu-0.16/mouseemu.h
--- mouseemu-0.16~/mouseemu.h 2009-08-27 20:18:25.000000000 +0100
+++ mouseemu-0.16/mouseemu.h 2009-08-27 20:18:25.000000000 +0100
@@ -41,6 +41,8 @@
int handle;
unsigned short vendor;
unsigned short product;
+ unsigned long mousebtns[NBITS(KEY_MAX)];
+ unsigned long mouserels[NBITS(REL_MAX)];
} kdev;
/* handler structure */
--- End Message ---