diff options
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) | |||
747 | input_close_device(handle); | 747 | input_close_device(handle); |
748 | } | 748 | } |
749 | 749 | ||
750 | static 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 | ||
751 | static bool joydev_match(struct input_handler *handler, struct input_dev *dev) | 808 | static 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 | ||