aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2015-05-20 17:50:30 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-05-21 18:58:27 -0400
commit15397f153cfd69c2164c1fa593e26707ed1a3e72 (patch)
treee50c1163a187d0e15ec600c9af211a1c902f21ae
parent412dbad2c7e273b48e8477247c74b2ad65c452d2 (diff)
Input: joydev - don't classify the vmmouse as a joystick
Joydev is currently thinking some absolute mice are joystick, and that messes up games in VMware guests, as the cursor typically gets stuck in the top left corner. Try to detect the event signature of a VMmouse input device and back off for such devices. We're still incorrectly detecting, for example, the VMware absolute USB mouse as a joystick, but adding an event signature matching also that device would be considerably more risky, so defer that to a later merge window. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/joydev.c61
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)
747 input_close_device(handle); 747 input_close_device(handle);
748} 748}
749 749
750static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
751{
752 DECLARE_BITMAP(jd_scratch, KEY_CNT);
753
754 BUILD_BUG_ON(ABS_CNT > KEY_CNT || EV_CNT > KEY_CNT);
755
756 /*
757 * Virtualization (VMware, etc) and remote management (HP
758 * ILO2) solutions use absolute coordinates for their virtual
759 * pointing devices so that there is one-to-one relationship
760 * between pointer position on the host screen and virtual
761 * guest screen, and so their mice use ABS_X, ABS_Y and 3
762 * primary button events. This clashes with what joydev
763 * considers to be joysticks (a device with at minimum ABS_X
764 * axis).
765 *
766 * Here we are trying to separate absolute mice from
767 * joysticks. A device is, for joystick detection purposes,
768 * considered to be an absolute mouse if the following is
769 * true:
770 *
771 * 1) Event types are exactly EV_ABS, EV_KEY and EV_SYN.
772 * 2) Absolute events are exactly ABS_X and ABS_Y.
773 * 3) Keys are exactly BTN_LEFT, BTN_RIGHT and BTN_MIDDLE.
774 * 4) Device is not on "Amiga" bus.
775 */
776
777 bitmap_zero(jd_scratch, EV_CNT);
778 __set_bit(EV_ABS, jd_scratch);
779 __set_bit(EV_KEY, jd_scratch);
780 __set_bit(EV_SYN, jd_scratch);
781 if (!bitmap_equal(jd_scratch, dev->evbit, EV_CNT))
782 return false;
783
784 bitmap_zero(jd_scratch, ABS_CNT);
785 __set_bit(ABS_X, jd_scratch);
786 __set_bit(ABS_Y, jd_scratch);
787 if (!bitmap_equal(dev->absbit, jd_scratch, ABS_CNT))
788 return false;
789
790 bitmap_zero(jd_scratch, KEY_CNT);
791 __set_bit(BTN_LEFT, jd_scratch);
792 __set_bit(BTN_RIGHT, jd_scratch);
793 __set_bit(BTN_MIDDLE, jd_scratch);
794
795 if (!bitmap_equal(dev->keybit, jd_scratch, KEY_CNT))
796 return false;
797
798 /*
799 * Amiga joystick (amijoy) historically uses left/middle/right
800 * button events.
801 */
802 if (dev->id.bustype == BUS_AMIGA)
803 return false;
804
805 return true;
806}
750 807
751static bool joydev_match(struct input_handler *handler, struct input_dev *dev) 808static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
752{ 809{
@@ -758,6 +815,10 @@ static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
758 if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit)) 815 if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
759 return false; 816 return false;
760 817
818 /* Avoid absolute mice */
819 if (joydev_dev_is_absolute_mouse(dev))
820 return false;
821
761 return true; 822 return true;
762} 823}
763 824