Problem with mousedev.c
Subsystems (2)
PATCH 1/1 Problem with mousedev.c
To make a long story short, mousedev.c does not properly implement the EXPS/2 protocol, specificly dealing with the wheel.
The lower 8 bits of the 4th byte are supposed to be 0x1 or 0xf to indicate movement of the first wheel, and 0x2 or 0xe for the second wheel.
Attached is a patch to correct this.
This does not get my two wheel mouse working perfectly yet, sadly that will take a bit of a hack, and I'm not sure where the best place to put it is yet, but this gets it back to generating correct data.
Zephaniah E. Hull.
(Debian GPM maintainer.)
Signature · 8 lines
1024D/E65A7801 Zephaniah E. Hull <[email protected]> 92ED 94E4 B1E6 3624 226D 5727 4453 008B E65A 7801 CCs of replies from mailing lists are requested. Yes, Java is so bulletproofed that to a C programmer it feels like being in a straightjacket, but it's a really comfy and warm straightjacket, and the world would be a safer place if everyone was straightjacketed most of the time. -- Overheard in the SDM.
drivers/input/mousedev.c +19 -5
@@ -62,7 +62,7 @@struct fasync_struct *fasync;struct mousedev *mousedev;struct mousedev_list *next; -int dx, dy, dz, oldx, oldy; +int dw, dx, dy, dz, oldx, oldy;signed char ps2[6 ];unsigned long buttons;unsigned char ready, buffer, bufsiz;
@@ -117,6 +117,7 @@case REL_X : list->dx += value;break ;case REL_Y : list->dy -= value;break ;case REL_WHEEL :if (list->mode) list->dz -= value;break ; +case REL_HWHEEL :if (list->mode ==2 ) list->dw -= value;break ; }break ;
@@ -260,9 +261,22 @@ list->bufsiz = off +3 ;if (list->mode ==2 ) { - list->ps2[off +3 ] = (list->dz >7 ?7 : (list->dz <-7 ?-7 : list->dz)); - list->dz -= list->ps2[off +3 ]; - list->ps2[off +3 ] = (list->ps2[off +3 ] &0x0f ) | ((list->buttons &0x18 ) <<1 ); +if (!list->dz && !list->dw) { + list->ps2[off +3 ] =0 ; + }else if (list->dw >0 ) { + list->ps2[off +3 ] =0x2 ; + list->dw--; + }else if (list->dw <0 ) { + list->ps2[off +3 ] =0xe ; + list->dw++; + }else if (list->dz >0 ) { + list->ps2[off +3 ] =0x1 ; + list->dz--; + }else if (list->dz <0 ) { + list->ps2[off +3 ] =0xf ; + list->dz++; + } + list->ps2[off +3 ] |= (list->buttons &0x18 ) <<1 ; list->bufsiz++; }
@@ -272,7 +286,7 @@ list->bufsiz++; } -if (!list->dx && !list->dy && (!list->mode || !list->dz)) list->ready =0 ; +if (!list->dx && !list->dy && (!list->mode || !list->dz) && ((list->mode !=2 ) || !list->dw)) list->ready =0 ; list->buffer = list->bufsiz; }
Quoted 6 lines · Zephaniah E. Hull
To make a long story short,
mousedev.cdoes not properly implement the EXPS/2 protocol, specificly dealing with the wheel.The lower 8 bits of the 4th byte are supposed to be
0x1or0xfto indicate movement of the first wheel, and0x2or0xefor the second wheel.
Hi,
I was talking about this problem with Vojtech some months ago,
and unfortunately we were not able to find correct way to implement it:
there are mouses (probably majority) which have only one wheel, and which reports fast wheel movement as 2,3,4... or 0xe,0xd,.... Protocol is documented this way on Microsoft web pages.
Then there is another group of mices (mine A4Tech with two wheels
being one of them) which reports vertical wheel always as 1/0xF, and horizontal as 2/0xE (and if you move both, they reports once horizontal and once vertical wheel).
Unfortunately we were not able to find how to detect these mouses in
advance, and when I asked A4Tech, I got back answer that I should use their mouse driver, and not one delivered by Microsoft (although Linux was every third word in question). From this answer I conclude that there is no way to autodetect it, and it has to be specified by some options passed to mouse driver.
Petr Vandrovec [email protected]
Quoted 8 lines · Petr Vandrovec
Quoted 6 lines · Zephaniah E. Hull
To make a long story short,
mousedev.cdoes not properly implement the EXPS/2 protocol, specificly dealing with the wheel.The lower 8 bits of the 4th byte are supposed to be
0x1or0xfto indicate movement of the first wheel, and0x2or0xefor the second wheel.
Quoted 6 lines
Hi,
I was talking about this problem with Vojtech some months ago,
and unfortunately we were not able to find correct way to implement it:
there are mouses (probably majority) which have only one wheel, and which reports fast wheel movement as 2,3,4... or 0xe,0xd,.... Protocol is documented this way on Microsoft web pages.
Crap, I have interestingly enough never had reports of a mouse which generates fast wheel movement in that manner, this makes things a bit more, er, interesting.
Is this for exps2 or imps2?
(Trying to find the page from microsoft now.)
Quoted 6 lines
Then there is another group of mices (mine A4Tech with two wheels
being one of them) which reports vertical wheel always as 1/0xF, and horizontal as 2/0xE (and if you move both, they reports once horizontal and once vertical wheel).
Quoted 6 lines
Unfortunately we were not able to find how to detect these mouses in
advance, and when I asked A4Tech, I got back answer that I should use their mouse driver, and not one delivered by Microsoft (although Linux was every third word in question). From this answer I conclude that there is no way to autodetect it, and it has to be specified by some options passed to mouse driver.
We can deal with one half of this, by acting like the a4tech mice when emulating the exps2 protocol, as far as when reading from them in PS/2 mode....
On the bright side, USB mice are fucked up in new and interesting ways!
(Have a patch for dealing with this A4Tech mouse's second wheel when it is attached as a USB device, but until mousedev.c knows what to do with information about the second wheel...)
Zephaniah E. Hull.
(Debian gpm maintainer.)
Signature · 9 lines
1024D/E65A7801 Zephaniah E. Hull <[email protected]> 92ED 94E4 B1E6 3624 226D 5727 4453 008B E65A 7801 CCs of replies from mailing lists are requested. [1] Yes, we ARE rather dull people. We appreciate being dull people. Exciting is only good when it happens to someone else ... as in "an exciting wreck", "an exciting plane crash", "an exciting install of Windows XP", et al. -- Ralph Wade Phillips in the Scary Devil Monastery.
Quoted 6 lines · Zephaniah E. Hull
To make a long story short,
mousedev.cdoes not properly implement the EXPS/2 protocol, specificly dealing with the wheel.The lower 8 bits of the 4th byte are supposed to be
0x1or0xfto indicate movement of the first wheel, and0x2or0xefor the second wheel.
No, see microsoft documentation. They're expected to be a 4-bit signed binary complement value that indicates the amount of movement.
Quoted 5 lines
Attached is a patch to correct this.
This does not get my two wheel mouse working perfectly yet, sadly that will take a bit of a hack, and I'm not sure where the best place to put it is yet, but this gets it back to generating correct data.
PS/2 A4-Tech mouse do the ugly trick you describe above to stuff two wheel information into a single-wheel oriented ImExPS/2 protocol. USB A4-Tech mouse do another ugly trick (additional button which specifies which wheel is rotating). I'm not interested in supporting these ugly tricks.
If you want to support the H-Wheel in GPM, then please add /dev/input/event support into GPM. (simple patch attached, you may need to do more changes, namely for h-wheel).
mice.c.new renamed from mice.c +44 -0
@@ -1405,6 +1405,46 @@ return type; } +static int M_evdev(Gpm_Event *state, unsigned char *data) +{ + struct input_event *event = (struct input_event *)data; + switch (event->type) { + case EV_KEY: + switch (event->code) { + case BTN_LEFT: + state->buttons = (state->buttons & ~GPM_B_LEFT) | (GPM_B_LEFT*event->value); + break; + case BTN_RIGHT: + state->buttons = (state->buttons & ~GPM_B_RIGHT) | (GPM_B_RIGHT*event->value); + break; + case BTN_MIDDLE: + state->buttons = (state->buttons & ~GPM_B_MIDDLE) | (GPM_B_MIDDLE*event->value); + break; + default: + break; + } + break; + case EV_REL: + switch (event->code) { + case REL_X: + state->dx = event->value; + break; + case REL_Y: + state->dy = event->value; + break; + case REL_WHEEL: + state->wdx = event->value; + break; + default: + break; + } + break; + default: + break; + } + return 0; +} +
@@ -1550,6 +1590,9 @@ " connector with 6 pins), 3 buttons.", "", M_kmiabps2, I_kmiabps2, STD_FLG, {0x00, 0x00, 0x00, 0x00}, 3, 1, 0, 0, 0}, + + {"evdev", "Linux input event device", "", M_evdev, NULL, STD_FLG, + {0x00, 0x00, 0x00, 0x00}, sizeof(struct input_event), + sizeof(struct input_event), 0, 0, 0}, {"", "",
"", NULL, NULL, 0,
mice.c.new renamed from mice.c +1 -0
@@ -69,6 +69,7 @@ #include <linux/joystick.h> #endif +#include <linux/input.h> #include "gpmInt.h" #include "twiddler.h"
Signature · 2 lines
Vojtech Pavlik SuSE Labs
Quoted 10 lines · Vojtech Pavlik
Quoted 6 lines · Zephaniah E. Hull
To make a long story short,
mousedev.cdoes not properly implement the EXPS/2 protocol, specificly dealing with the wheel.The lower 8 bits of the 4th byte are supposed to be
0x1or0xfto indicate movement of the first wheel, and0x2or0xefor the second wheel.No, see microsoft documentation. They're expected to be a 4-bit signed binary complement value that indicates the amount of movement.
After some poking, two questions.
The first is the URL for the documentation in question? This seems inconsistent with what I remember reading in the past, but can't seem to find anymore.
The second is if you have actually seen hardware which /actually/ generates the wheel data described while speaking exps2?
Quoted 7 lines
Quoted 6 lines
Attached is a patch to correct this.
This does not get my two wheel mouse working perfectly yet, sadly that will take a bit of a hack, and I'm not sure where the best place to put it is yet, but this gets it back to generating correct data.
Quoted 5 lines
PS/2 A4-Tech mouse do the ugly trick you describe above to stuff two wheel information into a single-wheel oriented ImExPS/2 protocol. USB A4-Tech mouse do another ugly trick (additional button which specifies which wheel is rotating). I'm not interested in supporting these ugly tricks.
Sadly, if PS/2 mice are any indication, mouse makers /will/ manage to fuck things up on enough popular mice under USB as well, and there needs to be a place to shove the dirty hacks needed to make things Just Work for users..
At least with USB stuff we can /identify/ the damn things, which means that we are leaps and bounds ahead of where we are for PS2 stuff.
Quoted 4 lines
If you want to support the H-Wheel in GPM, then please add
/dev/input/eventsupport into GPM. (simple patch attached, you may need to do more changes, namely for h-wheel).
Thanks, my next gpm upload should include it, now to get support for the same for X.. (Arrgh, X hacking is even lower on my list of things to do then kernel hacking is. Probably because I've done more of it.)
Signature · 6 lines
1024D/E65A7801 Zephaniah E. Hull <[email protected]> 92ED 94E4 B1E6 3624 226D 5727 4453 008B E65A 7801 CCs of replies from mailing lists are requested. Has anyone got a reference cynic? I think I need to recalibrate myself. -- James Riden in the SDM.
Quoted 33 lines · Zephaniah E. Hull
Quoted 10 lines · Vojtech Pavlik
Quoted 6 lines · Zephaniah E. Hull
To make a long story short,
mousedev.cdoes not properly implement the EXPS/2 protocol, specificly dealing with the wheel.The lower 8 bits of the 4th byte are supposed to be
0x1or0xfto indicate movement of the first wheel, and0x2or0xefor the second wheel.No, see microsoft documentation. They're expected to be a 4-bit signed binary complement value that indicates the amount of movement.
After some poking, two questions.
The first is the URL for the documentation in question? This seems inconsistent with what I remember reading in the past, but can't seem to find anymore.
The second is if you have actually seen hardware which /actually/ generates the wheel data described while speaking exps2?
Quoted 7 lines
Quoted 6 lines
Attached is a patch to correct this.
This does not get my two wheel mouse working perfectly yet, sadly that will take a bit of a hack, and I'm not sure where the best place to put it is yet, but this gets it back to generating correct data.
Quoted 5 lines
PS/2 A4-Tech mouse do the ugly trick you describe above to stuff two wheel information into a single-wheel oriented ImExPS/2 protocol. USB A4-Tech mouse do another ugly trick (additional button which specifies which wheel is rotating). I'm not interested in supporting these ugly tricks.
Quoted 4 lines
Sadly, if PS/2 mice are any indication, mouse makers /will/ manage to fuck things up on enough popular mice under USB as well, and there needs to be a place to shove the dirty hacks needed to make things Just Work for users..
That place would be hid-input.c and psmouse.c. NOT mousedev.c.
Quoted 10 lines
At least with USB stuff we can /identify/ the damn things, which means that we are leaps and bounds ahead of where we are for PS2 stuff.
Quoted 4 lines
If you want to support the H-Wheel in GPM, then please add
/dev/input/eventsupport into GPM. (simple patch attached, you may need to do more changes, namely for h-wheel).Thanks, my next gpm upload should include it, now to get support for the same for X.. (Arrgh, X hacking is even lower on my list of things to do then kernel hacking is. Probably because I've done more of it.)
Signature · 2 lines
Vojtech Pavlik SuSE Labs
Quoted 7 lines · Vojtech Pavlik
Quoted 4 lines · Zephaniah E. Hull
Sadly, if PS/2 mice are any indication, mouse makers /will/ manage to fuck things up on enough popular mice under USB as well, and there needs to be a place to shove the dirty hacks needed to make things Just Work for users..
That place would be
hid-input.candpsmouse.c. NOTmousedev.c.
Agreed, at the moment my patch for dealing with the A4 mouse hits three files in the HID layer, and is not the cleanest, however it is attached for reference.
Now if I could only find (better) documentation on the various PS2 protocols to find one that has in the spec itself handling for multiple wheels..
Signature · 8 lines
1024D/E65A7801 Zephaniah E. Hull <[email protected]> 92ED 94E4 B1E6 3624 226D 5727 4453 008B E65A 7801 CCs of replies from mailing lists are requested. "I would rather spend 10 hours reading someone else's source code than 10 minutes listening to Musak waiting for technical support which isn't." (By Dr. Greg Wettstein, Roger Maris Cancer Center)
drivers/usb/hid-core.c +3 -0
@@ -1086,6 +1086,8 @@#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 +#define USB_VENDOR_ID_A4TECH 0x09DA +#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006struct hid_blacklist {__u16 idVendor;__u16 idProduct;
@@ -1115,6 +1117,7 @@ { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK }, { 0, 0 } };
drivers/usb/hid-input.c +19 -0
@@ -269,6 +269,11 @@ }set_bit (usage->type, input->evbit); +if ((usage->type ==EV_REL ) + && (device->quirks &HID_QUIRK_2WHEEL_MOUSE_HACK ) + && (usage->code ==REL_WHEEL )) { +set_bit (REL_HWHEEL , bit); + }while (usage->code <= max &&test_and_set_bit (usage->code, bit)) { usage->code =find_next_zero_bit (bit, max +1 , usage->code);
@@ -303,6 +308,20 @@struct input_dev *input = &hid->input;int *quirks = &hid->quirks; +if ((hid->quirks &HID_QUIRK_2WHEEL_MOUSE_HACK ) + && (usage->code ==BTN_BACK )) { +if (value) + hid->quirks |=HID_QUIRK_2WHEEL_MOUSE_HACK_ON ; +else + hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON ; +return ; + } +if ((hid->quirks &HID_QUIRK_2WHEEL_MOUSE_HACK_ON ) + && (usage->code ==REL_WHEEL )) { +input_event (input, usage->type,REL_HWHEEL , value); +return ; + } +if (usage->hat_min != usage->hat_max) { value = (value - usage->hat_min) *8 / (usage->hat_max - usage->hat_min +1 ) +1 ;if (value <0 || value >8 ) value =0 ;
drivers/usb/hid.h +2 -0
@@ -186,6 +186,8 @@#define HID_QUIRK_NOTOUCH 0x02#define HID_QUIRK_IGNORE 0x04#define HID_QUIRK_NOGET 0x08 +#define HID_QUIRK_2WHEEL_MOUSE_HACK 0x10 +#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x20/* * This is the global enviroment of the parser. This information is
Quoted 7 lines · Zephaniah E. Hull
Quoted 6 lines · Vojtech Pavlik
Quoted 4 lines · Zephaniah E. Hull
Sadly, if PS/2 mice are any indication, mouse makers /will/ manage to fuck things up on enough popular mice under USB as well, and there needs to be a place to shove the dirty hacks needed to make things Just Work for users..
Quoted 5 lines
Quoted 1 line
That place would be
hid-input.candpsmouse.c. NOTmousedev.c.Agreed, at the moment my patch for dealing with the A4 mouse hits three files in the HID layer, and is not the cleanest, however it is attached for reference.
The patch is quite OK, it should not report BTN_BACK to userspace, though, and also it should not depend on the hid-input.c assigning BTN_BACK to the button which specifies the wheel.
Quoted 82 lines
Now if I could only find (better) documentation on the various PS2 protocols to find one that has in the spec itself handling for multiple wheels..
Signature · 10 lines
1024D/E65A7801 Zephaniah E. Hull <[email protected]> 92ED 94E4 B1E6 3624 226D 5727 4453 008B E65A 7801 CCs of replies from mailing lists are requested. "I would rather spend 10 hours reading someone else's source code than 10 minutes listening to Musak waiting for technical support which isn't." (By Dr. Greg Wettstein, Roger Maris Cancer Center) diff -ur linux.orig/drivers/usb/hid-core.c linux/drivers/usb/hid-core.cdrivers/usb/hid-core.c +3
-0@@ -1086,6 +1086,8 @@#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 +#define USB_VENDOR_ID_A4TECH 0x09DA +#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006struct hid_blacklist {__u16 idVendor;__u16 idProduct;@@ -1115,6 +1117,7 @@ { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK }, { 0, 0 } };diff -ur
linux.orig/drivers/usb/hid-input.clinux/drivers/usb/hid-input.cdrivers/usb/hid-input.c +19
-0@@ -269,6 +269,11 @@ }set_bit (usage->type, input->evbit); +if ((usage->type ==EV_REL ) + && (device->quirks &HID_QUIRK_2WHEEL_MOUSE_HACK ) + && (usage->code ==REL_WHEEL )) { +set_bit (REL_HWHEEL , bit); + }while (usage->code <= max &&test_and_set_bit (usage->code, bit)) { usage->code =find_next_zero_bit (bit, max +1 , usage->code);@@ -303,6 +308,20 @@struct input_dev *input = &hid->input;int *quirks = &hid->quirks; +if ((hid->quirks &HID_QUIRK_2WHEEL_MOUSE_HACK ) + && (usage->code ==BTN_BACK )) { +if (value) + hid->quirks |=HID_QUIRK_2WHEEL_MOUSE_HACK_ON ; +else + hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON ; +return ; + } +if ((hid->quirks &HID_QUIRK_2WHEEL_MOUSE_HACK_ON ) + && (usage->code ==REL_WHEEL )) { +input_event (input, usage->type,REL_HWHEEL , value); +return ; + } +if (usage->hat_min != usage->hat_max) { value = (value - usage->hat_min) *8 / (usage->hat_max - usage->hat_min +1 ) +1 ;if (value <0 || value >8 ) value =0 ;diff -ur
linux.orig/drivers/usb/hid.hlinux/drivers/usb/hid.hdrivers/usb/hid.h +2
-0@@ -186,6 +186,8 @@#define HID_QUIRK_NOTOUCH 0x02#define HID_QUIRK_IGNORE 0x04#define HID_QUIRK_NOGET 0x08 +#define HID_QUIRK_2WHEEL_MOUSE_HACK 0x10 +#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x20/* * This is the global enviroment of the parser. This information is
Signature · 2 lines
Vojtech Pavlik SuSE Labs
Quoted 3 lines · Vojtech Pavlik
The patch is quite OK, it should not report
BTN_BACKto userspace, though, and also it should not depend on thehid-input.cassigningBTN_BACKto the button which specifies the wheel.
Hrm, it does not report BTN_BACK events, but it is present in the bit mask, however we could refuse to set the bit if the quirk is present.
As far as not depending on the BTN_BACK being assigned as such, I'm not quite sure how to tell the event handler which one to use without an additional field somewhere.
That said, I have not gotten my head around the entirety of the HID layer, so I could very easily be missing something obvious.
Signature · 6 lines
1024D/E65A7801 Zephaniah E. Hull <[email protected]> 92ED 94E4 B1E6 3624 226D 5727 4453 008B E65A 7801 CCs of replies from mailing lists are requested. <Mercury> Knghtbrd: Eww, find a better name, the movie sucked.. <G> <Knghtbrd> Mercury: The engine is better than the movie