From 81618a789de497e8f2ab7f1ee8bb471b5b0976b7 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 23 Dec 2015 15:15:29 +1000 Subject: [PATCH libinput] evdev: only reject devices with missing MT x/y if they're MT devices A fake MT device may have ABS_MT_POSITION_X but not Y. In this case we don't care, because we don't handle those axes anyway. http://bugs.freedesktop.org/show_bug.cgi?id=93474 Signed-off-by: Peter Hutterer --- src/evdev.c | 11 +- test/Makefile.am | 1 + test/device.c | 31 +++++ test/litest-device-anker-mouse-kbd.c | 225 +++++++++++++++++++++++++++++++++++ test/litest.c | 2 + test/litest.h | 1 + 6 files changed, 264 insertions(+), 7 deletions(-) create mode 100644 test/litest-device-anker-mouse-kbd.c diff --git a/src/evdev.c b/src/evdev.c index 3708072..d798097 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1800,13 +1800,12 @@ evdev_fix_android_mt(struct evdev_device *device) { struct libevdev *evdev = device->evdev; - if (libevdev_has_event_code(evdev, EV_ABS, ABS_X) || + if (libevdev_has_event_code(evdev, EV_ABS, ABS_X) && libevdev_has_event_code(evdev, EV_ABS, ABS_Y)) return; if (!libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_X) || - !libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_Y) || - evdev_is_fake_mt_device(device)) + !libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_Y)) return; libevdev_enable_event_code(evdev, EV_ABS, ABS_X, @@ -1868,7 +1867,8 @@ evdev_reject_device(struct evdev_device *device) libevdev_has_event_code(evdev, EV_REL, REL_Y)) return -1; - if (libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_X) ^ + if (!evdev_is_fake_mt_device(device) && + libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_X) ^ libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_Y)) return -1; @@ -2039,9 +2039,6 @@ evdev_configure_device(struct evdev_device *device) return -1; } - if (!evdev_is_fake_mt_device(device)) - evdev_fix_android_mt(device); - if (libevdev_has_event_code(evdev, EV_ABS, ABS_X)) { if (evdev_fix_abs_resolution(device, ABS_X, ABS_Y)) device->abs.fake_resolution = 1; diff --git a/test/Makefile.am b/test/Makefile.am index e4ed8e5..1b3090e 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -15,6 +15,7 @@ liblitest_la_SOURCES = \ litest-int.h \ litest-device-alps-semi-mt.c \ litest-device-alps-dualpoint.c \ + litest-device-anker-mouse-kbd.c \ litest-device-asus-rog-gladius.c \ litest-device-atmel-hover.c \ litest-device-bcm5974.c \ diff --git a/test/device.c b/test/device.c index b7fa0e0..03659ac 100644 --- a/test/device.c +++ b/test/device.c @@ -1254,6 +1254,35 @@ START_TEST(device_abs_rel) } END_TEST +START_TEST(device_quirks_no_abs_mt_y) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_pointer *pev; + int code; + + litest_drain_events(li); + + litest_event(dev, EV_REL, REL_HWHEEL, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + event = libinput_get_event(li); + pev = litest_is_axis_event(event, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, + LIBINPUT_POINTER_AXIS_SOURCE_WHEEL); + libinput_event_destroy(libinput_event_pointer_get_base_event(pev)); + + for (code = ABS_MISC + 1; code < ABS_MAX; code++) { + litest_event(dev, EV_ABS, code, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_assert_empty_queue(li); + } + +} +END_TEST + void litest_setup_tests(void) { @@ -1308,4 +1337,6 @@ litest_setup_tests(void) litest_add_no_device("device:invalid rel events", device_touchpad_rel); litest_add_no_device("device:invalid rel events", device_touch_rel); litest_add_no_device("device:invalid rel events", device_abs_rel); + + litest_add_for_device("device:quirks", device_quirks_no_abs_mt_y, LITEST_ANKER_MOUSE_KBD); } diff --git a/test/litest-device-anker-mouse-kbd.c b/test/litest-device-anker-mouse-kbd.c new file mode 100644 index 0000000..ca1441d --- /dev/null +++ b/test/litest-device-anker-mouse-kbd.c @@ -0,0 +1,225 @@ +/* + * Copyright © 2015 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "litest.h" +#include "litest-int.h" + +/* Recording from https://bugs.freedesktop.org/show_bug.cgi?id=93474 + * This is the keyboard device for this mouse. + */ + +static void litest_anker_mouse_kbd_setup(void) +{ + struct litest_device *d = litest_create_device(LITEST_ANKER_MOUSE_KBD); + litest_set_current_device(d); +} + +static struct input_id input_id = { + .bustype = 0x3, + .vendor = 0x4d9, + .product = 0xfa50, +}; + +static int events[] = { + EV_REL, REL_HWHEEL, + EV_KEY, KEY_ESC, + EV_KEY, KEY_KPMINUS, + EV_KEY, KEY_KPPLUS, + EV_KEY, KEY_UP, + EV_KEY, KEY_PAGEUP, + EV_KEY, KEY_LEFT, + EV_KEY, KEY_RIGHT, + EV_KEY, KEY_END, + EV_KEY, KEY_DOWN, + EV_KEY, KEY_PAGEDOWN, + EV_KEY, KEY_INSERT, + EV_KEY, KEY_DELETE, + EV_KEY, KEY_MUTE, + EV_KEY, KEY_VOLUMEDOWN, + EV_KEY, KEY_VOLUMEUP, + EV_KEY, KEY_POWER, + EV_KEY, KEY_PAUSE, + EV_KEY, KEY_STOP, + EV_KEY, KEY_PROPS, + EV_KEY, KEY_UNDO, + EV_KEY, KEY_COPY, + EV_KEY, KEY_OPEN, + EV_KEY, KEY_PASTE, + EV_KEY, KEY_FIND, + EV_KEY, KEY_CUT, + EV_KEY, KEY_HELP, + EV_KEY, KEY_MENU, + EV_KEY, KEY_CALC, + EV_KEY, KEY_SLEEP, + EV_KEY, KEY_WAKEUP, + EV_KEY, KEY_FILE, + EV_KEY, KEY_WWW, + EV_KEY, KEY_COFFEE, + EV_KEY, KEY_MAIL, + EV_KEY, KEY_BOOKMARKS, + EV_KEY, KEY_BACK, + EV_KEY, KEY_FORWARD, + EV_KEY, KEY_EJECTCD, + EV_KEY, KEY_NEXTSONG, + EV_KEY, KEY_PLAYPAUSE, + EV_KEY, KEY_PREVIOUSSONG, + EV_KEY, KEY_STOPCD, + EV_KEY, KEY_RECORD, + EV_KEY, KEY_REWIND, + EV_KEY, KEY_PHONE, + EV_KEY, KEY_CONFIG, + EV_KEY, KEY_HOMEPAGE, + EV_KEY, KEY_REFRESH, + EV_KEY, KEY_EXIT, + EV_KEY, KEY_EDIT, + EV_KEY, KEY_SCROLLUP, + EV_KEY, KEY_SCROLLDOWN, + EV_KEY, KEY_NEW, + EV_KEY, KEY_REDO, + EV_KEY, KEY_CLOSE, + EV_KEY, KEY_PLAY, + EV_KEY, KEY_FASTFORWARD, + EV_KEY, KEY_BASSBOOST, + EV_KEY, KEY_PRINT, + EV_KEY, KEY_CAMERA, + EV_KEY, KEY_CHAT, + EV_KEY, KEY_SEARCH, + EV_KEY, KEY_FINANCE, + EV_KEY, KEY_BRIGHTNESSDOWN, + EV_KEY, KEY_BRIGHTNESSUP, + EV_KEY, KEY_KBDILLUMTOGGLE, + EV_KEY, KEY_SAVE, + EV_KEY, KEY_DOCUMENTS, + EV_KEY, KEY_UNKNOWN, + EV_KEY, KEY_VIDEO_NEXT, + EV_KEY, KEY_BRIGHTNESS_AUTO, + EV_KEY, BTN_0, + EV_KEY, KEY_SELECT, + EV_KEY, KEY_GOTO, + EV_KEY, KEY_INFO, + EV_KEY, KEY_PROGRAM, + EV_KEY, KEY_PVR, + EV_KEY, KEY_SUBTITLE, + EV_KEY, KEY_ZOOM, + EV_KEY, KEY_KEYBOARD, + EV_KEY, KEY_PC, + EV_KEY, KEY_TV, + EV_KEY, KEY_TV2, + EV_KEY, KEY_VCR, + EV_KEY, KEY_VCR2, + EV_KEY, KEY_SAT, + EV_KEY, KEY_CD, + EV_KEY, KEY_TAPE, + EV_KEY, KEY_TUNER, + EV_KEY, KEY_PLAYER, + EV_KEY, KEY_DVD, + EV_KEY, KEY_AUDIO, + EV_KEY, KEY_VIDEO, + EV_KEY, KEY_MEMO, + EV_KEY, KEY_CALENDAR, + EV_KEY, KEY_RED, + EV_KEY, KEY_GREEN, + EV_KEY, KEY_YELLOW, + EV_KEY, KEY_BLUE, + EV_KEY, KEY_CHANNELUP, + EV_KEY, KEY_CHANNELDOWN, + EV_KEY, KEY_LAST, + EV_KEY, KEY_NEXT, + EV_KEY, KEY_RESTART, + EV_KEY, KEY_SLOW, + EV_KEY, KEY_SHUFFLE, + EV_KEY, KEY_PREVIOUS, + EV_KEY, KEY_VIDEOPHONE, + EV_KEY, KEY_GAMES, + EV_KEY, KEY_ZOOMIN, + EV_KEY, KEY_ZOOMOUT, + EV_KEY, KEY_ZOOMRESET, + EV_KEY, KEY_WORDPROCESSOR, + EV_KEY, KEY_EDITOR, + EV_KEY, KEY_SPREADSHEET, + EV_KEY, KEY_GRAPHICSEDITOR, + EV_KEY, KEY_PRESENTATION, + EV_KEY, KEY_DATABASE, + EV_KEY, KEY_NEWS, + EV_KEY, KEY_VOICEMAIL, + EV_KEY, KEY_ADDRESSBOOK, + EV_KEY, KEY_MESSENGER, + EV_KEY, KEY_DISPLAYTOGGLE, + EV_KEY, KEY_SPELLCHECK, + EV_KEY, KEY_LOGOFF, + EV_KEY, KEY_MEDIA_REPEAT, + EV_KEY, KEY_IMAGES, + EV_KEY, KEY_BUTTONCONFIG, + EV_KEY, KEY_TASKMANAGER, + EV_KEY, KEY_JOURNAL, + EV_KEY, KEY_CONTROLPANEL, + EV_KEY, KEY_APPSELECT, + EV_KEY, KEY_SCREENSAVER, + EV_KEY, KEY_VOICECOMMAND, + EV_KEY, KEY_BRIGHTNESS_MIN, + EV_KEY, KEY_BRIGHTNESS_MAX, + EV_KEY, KEY_KBDINPUTASSIST_PREV, + EV_KEY, KEY_KBDINPUTASSIST_NEXT, + EV_KEY, KEY_KBDINPUTASSIST_PREVGROUP, + EV_KEY, KEY_KBDINPUTASSIST_NEXTGROUP, + EV_KEY, KEY_KBDINPUTASSIST_ACCEPT, + EV_KEY, KEY_KBDINPUTASSIST_CANCEL, + EV_MSC, MSC_SCAN, + -1 , -1, +}; + +static struct input_absinfo absinfo[] = { + { ABS_VOLUME, 0, 4096, 0, 0, 0 }, + { ABS_MISC, 0, 255, 0, 0, 0 }, + { 0x29, 0, 255, 0, 0, 0 }, + { 0x2a, 0, 255, 0, 0, 0 }, + { 0x2b, 0, 255, 0, 0, 0 }, + { 0x2c, 0, 255, 0, 0, 0 }, + { 0x2d, 0, 255, 0, 0, 0 }, + { 0x2e, 0, 255, 0, 0, 0 }, + { ABS_MT_SLOT, 0, 255, 0, 0, 0 }, + { ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0, 0 }, + { ABS_MT_TOUCH_MINOR, 0, 255, 0, 0, 0 }, + { ABS_MT_WIDTH_MINOR, 0, 255, 0, 0, 0 }, + { ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0, 0 }, + { ABS_MT_ORIENTATION, 0, 255, 0, 0, 0 }, + { ABS_MT_POSITION_Y, 0, 255, 0, 0, 0 }, + { .value = -1 }, +}; + +struct litest_test_device litest_anker_mouse_kbd_device = { + .type = LITEST_ANKER_MOUSE_KBD, + .features = LITEST_KEYS | LITEST_WHEEL, + .shortname = "anker_kbd", + .setup = litest_anker_mouse_kbd_setup, + .interface = NULL, + + .name = "USB Laser Game Mouse", + .id = &input_id, + .absinfo = absinfo, + .events = events, +}; diff --git a/test/litest.c b/test/litest.c index fc188b6..e51004e 100644 --- a/test/litest.c +++ b/test/litest.c @@ -367,6 +367,7 @@ extern struct litest_test_device litest_magicpad_device; extern struct litest_test_device litest_elantech_touchpad_device; extern struct litest_test_device litest_mouse_gladius_device; extern struct litest_test_device litest_mouse_wheel_click_angle_device; +extern struct litest_test_device litest_anker_mouse_kbd_device; struct litest_test_device* devices[] = { &litest_synaptics_clickpad_device, @@ -400,6 +401,7 @@ struct litest_test_device* devices[] = { &litest_elantech_touchpad_device, &litest_mouse_gladius_device, &litest_mouse_wheel_click_angle_device, + &litest_anker_mouse_kbd_device, NULL, }; diff --git a/test/litest.h b/test/litest.h index 1268e10..be270ee 100644 --- a/test/litest.h +++ b/test/litest.h @@ -144,6 +144,7 @@ enum litest_device_type { LITEST_ELANTECH_TOUCHPAD = -30, LITEST_MOUSE_GLADIUS = -31, LITEST_MOUSE_WHEEL_CLICK_ANGLE = -32, + LITEST_ANKER_MOUSE_KBD = -33, }; enum litest_device_feature { -- 2.5.0