|
@@ -747,6 +747,63 @@ static void joydev_cleanup(struct joydev *joydev)
|
|
input_close_device(handle);
|
|
input_close_device(handle);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
|
|
|
|
+{
|
|
|
|
+ DECLARE_BITMAP(jd_scratch, KEY_CNT);
|
|
|
|
+
|
|
|
|
+ BUILD_BUG_ON(ABS_CNT > KEY_CNT || EV_CNT > KEY_CNT);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Virtualization (VMware, etc) and remote management (HP
|
|
|
|
+ * ILO2) solutions use absolute coordinates for their virtual
|
|
|
|
+ * pointing devices so that there is one-to-one relationship
|
|
|
|
+ * between pointer position on the host screen and virtual
|
|
|
|
+ * guest screen, and so their mice use ABS_X, ABS_Y and 3
|
|
|
|
+ * primary button events. This clashes with what joydev
|
|
|
|
+ * considers to be joysticks (a device with at minimum ABS_X
|
|
|
|
+ * axis).
|
|
|
|
+ *
|
|
|
|
+ * Here we are trying to separate absolute mice from
|
|
|
|
+ * joysticks. A device is, for joystick detection purposes,
|
|
|
|
+ * considered to be an absolute mouse if the following is
|
|
|
|
+ * true:
|
|
|
|
+ *
|
|
|
|
+ * 1) Event types are exactly EV_ABS, EV_KEY and EV_SYN.
|
|
|
|
+ * 2) Absolute events are exactly ABS_X and ABS_Y.
|
|
|
|
+ * 3) Keys are exactly BTN_LEFT, BTN_RIGHT and BTN_MIDDLE.
|
|
|
|
+ * 4) Device is not on "Amiga" bus.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ bitmap_zero(jd_scratch, EV_CNT);
|
|
|
|
+ __set_bit(EV_ABS, jd_scratch);
|
|
|
|
+ __set_bit(EV_KEY, jd_scratch);
|
|
|
|
+ __set_bit(EV_SYN, jd_scratch);
|
|
|
|
+ if (!bitmap_equal(jd_scratch, dev->evbit, EV_CNT))
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ bitmap_zero(jd_scratch, ABS_CNT);
|
|
|
|
+ __set_bit(ABS_X, jd_scratch);
|
|
|
|
+ __set_bit(ABS_Y, jd_scratch);
|
|
|
|
+ if (!bitmap_equal(dev->absbit, jd_scratch, ABS_CNT))
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ bitmap_zero(jd_scratch, KEY_CNT);
|
|
|
|
+ __set_bit(BTN_LEFT, jd_scratch);
|
|
|
|
+ __set_bit(BTN_RIGHT, jd_scratch);
|
|
|
|
+ __set_bit(BTN_MIDDLE, jd_scratch);
|
|
|
|
+
|
|
|
|
+ if (!bitmap_equal(dev->keybit, jd_scratch, KEY_CNT))
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Amiga joystick (amijoy) historically uses left/middle/right
|
|
|
|
+ * button events.
|
|
|
|
+ */
|
|
|
|
+ if (dev->id.bustype == BUS_AMIGA)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
|
|
static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
|
|
static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
|
|
{
|
|
{
|
|
@@ -758,6 +815,10 @@ static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
|
|
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
|
|
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
|
|
+ /* Avoid absolute mice */
|
|
|
|
+ if (joydev_dev_is_absolute_mouse(dev))
|
|
|
|
+ return false;
|
|
|
|
+
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|