diff options
| author | Tony Lindgren <tony@atomide.com> | 2015-06-09 23:37:31 -0700 |
|---|---|---|
| committer | Tony Lindgren <tony@atomide.com> | 2015-06-09 23:37:31 -0700 |
| commit | 63e63a1981c7247fea41ce97b3144befc8f2fb7b (patch) | |
| tree | 74a5708579661a741b6c62096530e68aee949273 /drivers/input/joydev.c | |
| parent | 5b83b2234be6733cfe22036c38031b2c890b3db8 (diff) | |
| parent | a3e362f18c01f28abcb6d8e5d00be8b5d97ea09d (diff) | |
Merge branch 'wakeirq-8250' into omap-for-v4.2/wakeirq-v2
Diffstat (limited to 'drivers/input/joydev.c')
| -rw-r--r-- | drivers/input/joydev.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index f362883c94e3..1d247bcf2ae2 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -747,6 +747,63 @@ static void joydev_cleanup(struct joydev *joydev) 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) { @@ -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)) return false; + /* Avoid absolute mice */ + if (joydev_dev_is_absolute_mouse(dev)) + return false; + return true; } |
