First off, yes, I know that the approach is a massive kluge, and that the code needs a cleanup.
Yes, I also know that I left in some debugging lines.
So, really, I'm looking for advice on how to make this _less_ evil, or a
confirmation that nobody can see how to support this mouse without
really evil stuff.
To describe the problem, this is a 'tilt wheel' mouse, with 5 buttons.
It report REL_X, REL_Y, REL_WHEEL, BTN_LEFT, BTN_RIGHT, BTN_MIDDLE,
BTN_SIDE, and BTN_EXTRA.
If you're noticing a lack of ways to report the tilt wheel, you have
less imagination then the people who decided to build this thing.
Tilt wheel events are reported by, in the same USB report, sending
BTN_MIDDLE and BTN_SIDE/BTN_EXTRA (depending on which way, of course).
There is no way to differentiate BTN_MIDDLE down and tilting the wheel
from BTN_MIDDLE down and hitting the side buttons, and I still can't
decide if we should send side button events or tilt wheel events in that
case. Currently the patch generates side button events for that case.
So, now that you've had the disclaimer which explains why this code is
so evil, and why the layering violations seemed like a good idea at the
time..
Signed-off-by: "Zephaniah E. Hull" <[EMAIL PROTECTED]>
(But oh god, please don't submit this as is, at least remove the debug
statements and check line lengths.)
diff -ur linux-test/drivers/usb/input/hid-core.c
linux-2.6/drivers/usb/input/hid-core.c
--- linux-test/drivers/usb/input/hid-core.c 2006-07-24 23:36:01.000000000
-0400
+++ linux-2.6/drivers/usb/input/hid-core.c 2006-08-07 17:22:58.000000000
-0400
@@ -1563,6 +1563,9 @@
#define USB_VENDOR_ID_CREATIVELABS 0x062a
#define USB_DEVICE_ID_CREATIVELABS_SILVERCREST 0x0201
+#define USB_VENDOR_ID_MICROINV 0x1241
+#define USB_DEVICE_ID_PD945P 0x1166
+
/*
* Alphabetically sorted blacklist by quirk type.
*/
@@ -1693,6 +1696,8 @@
{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU,
HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE,
HID_QUIRK_2WHEEL_MOUSE_HACK_5 },
+ { USB_VENDOR_ID_MICROINV, USB_DEVICE_ID_PD945P,
HID_QUIRK_TILT_MOUSE_HACK },
+
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD,
HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR,
HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
diff -ur linux-test/drivers/usb/input/hid.h linux-2.6/drivers/usb/input/hid.h
--- linux-test/drivers/usb/input/hid.h 2006-07-24 23:36:01.000000000 -0400
+++ linux-2.6/drivers/usb/input/hid.h 2006-08-07 17:01:41.000000000 -0400
@@ -251,6 +251,11 @@
#define HID_QUIRK_CYMOTION 0x00000800
#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000
#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000
+#define HID_QUIRK_TILT_MOUSE_HACK 0x00004000
+#define HID_QUIRK_TILT_MOUSE_HACK_ON 0x00008000
+#define HID_QUIRK_TILT_MOUSE_HACK_DOWN_1 0x00010000
+#define HID_QUIRK_TILT_MOUSE_HACK_DOWN_0 0x00020000
+#define HID_QUIRK_TILT_MOUSE_HACK_DOWN
(HID_QUIRK_TILT_MOUSE_HACK_DOWN_1 | HID_QUIRK_TILT_MOUSE_HACK_DOWN_0)
/*
* This is the global environment of the parser. This information is
diff -ur linux-test/drivers/usb/input/hid-input.c
linux-2.6/drivers/usb/input/hid-input.c
--- linux-test/drivers/usb/input/hid-input.c 2006-07-24 23:36:01.000000000
-0400
+++ linux-2.6/drivers/usb/input/hid-input.c 2006-08-07 17:19:46.000000000
-0400
@@ -586,6 +586,12 @@
|| ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) &&
(usage->hid == 0x00090007)))
goto ignore;
+ if ((device->quirks & HID_QUIRK_TILT_MOUSE_HACK) &&
+ (usage->type == EV_KEY) && (usage->code == BTN_MIDDLE)) {
+ set_bit(BTN_FORWARD, bit);
+ set_bit(BTN_BACK, bit);
+ }
+
if (usage->type == EV_ABS) {
int a = field->logical_minimum;
@@ -647,6 +653,53 @@
return;
}
+#ifdef DEBUG
+ if (usage->type == EV_KEY) {
+ printk(KERN_DEBUG "hid_event: ");
+ resolv_event(usage->type, usage->code);
+ printk(": v=%d q=0x%x\n", value, hid->quirks);
+ printk(KERN_DEBUG "bits: M%d S%d E%d F%d B%d\n",
+ !!test_bit(BTN_MIDDLE, input->key),
+ !!test_bit(BTN_SIDE, input->key),
+ !!test_bit(BTN_EXTRA, input->key),
+ !!test_bit(BTN_FORWARD, input->key),
+ !!test_bit(BTN_BACK, input->key)
+ );
+ }
+#endif
+ /*
+ * FIXME: HID_QUIRK_TILT_MOUSE_HACK is _EVIL_.
+ * Someone please find a better way.
+ */
+ if ((hid->quirks & HID_QUIRK_TILT_MOUSE_HACK) &&
+ (usage->code == BTN_MIDDLE) &&
+ ((hid->quirks & HID_QUIRK_TILT_MOUSE_HACK_ON) ||
+ (!test_bit(BTN_MIDDLE, input->key) == value))) {
+ if (value)
+ hid->quirks |= HID_QUIRK_TILT_MOUSE_HACK_DOWN_1;
+ else
+ hid->quirks |= HID_QUIRK_TILT_MOUSE_HACK_DOWN_0;
+ return;
+ }
+
+ if ((hid->quirks & HID_QUIRK_TILT_MOUSE_HACK_DOWN) &&
+ (usage->code == BTN_SIDE) &&
+ (!test_bit(BTN_FORWARD, input->key) == value)) {
+ input_event(input, usage->type, BTN_FORWARD, value);
+ if (hid->quirks & HID_QUIRK_TILT_MOUSE_HACK_DOWN_1)
+ hid->quirks |= HID_QUIRK_TILT_MOUSE_HACK_ON;
+ return;
+ }
+
+ if ((hid->quirks & HID_QUIRK_TILT_MOUSE_HACK_DOWN) &&
+ (usage->code == BTN_EXTRA) &&
+ (!test_bit(BTN_BACK, input->key) == value)) {
+ input_event(input, usage->type, BTN_BACK, value);
+ if (hid->quirks & HID_QUIRK_TILT_MOUSE_HACK_DOWN_1)
+ hid->quirks |= HID_QUIRK_TILT_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;
@@ -709,9 +762,35 @@
void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
{
struct hid_input *hidinput;
+ struct input_dev *input;
+
+#ifdef DEBUG
+ printk(KERN_DEBUG "hid: quirks: 0x%x\n", hid->quirks);
+#endif
+
+ list_for_each_entry(hidinput, &hid->inputs, list) {
+ input = hidinput->input;
+#ifdef DEBUG
+ printk(KERN_DEBUG "bits: M%d S%d E%d F%d B%d\n",
+ !!test_bit(BTN_MIDDLE, input->key),
+ !!test_bit(BTN_SIDE, input->key),
+ !!test_bit(BTN_EXTRA, input->key),
+ !!test_bit(BTN_FORWARD, input->key),
+ !!test_bit(BTN_BACK, input->key)
+ );
+#endif
+ if (!(hid->quirks & HID_QUIRK_TILT_MOUSE_HACK_ON)) {
+ if (hid->quirks & HID_QUIRK_TILT_MOUSE_HACK_DOWN_1)
+ input_event(input, EV_KEY, BTN_MIDDLE, 1);
+ else if (hid->quirks & HID_QUIRK_TILT_MOUSE_HACK_DOWN_0)
+ input_event(input, EV_KEY, BTN_MIDDLE, 0);
+ }
+ input_sync(input);
+ }
- list_for_each_entry(hidinput, &hid->inputs, list)
- input_sync(hidinput->input);
+ if (hid->quirks & HID_QUIRK_TILT_MOUSE_HACK_DOWN_0)
+ hid->quirks &= ~HID_QUIRK_TILT_MOUSE_HACK_ON;
+ hid->quirks &= ~HID_QUIRK_TILT_MOUSE_HACK_DOWN;
}
static int hidinput_find_field(struct hid_device *hid, unsigned int type,
unsigned int code, struct hid_field **field)
--
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.
Stubborness will get you where self-esteem won't let you go.
-- Queen Of Swords in the SDM.
signature.asc
Description: Digital signature
------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________ [email protected] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
