Rebased ref, commits from common ancestor: commit cd02040a5d4a8f120d225a4c09f5d1dfc751c0a8 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Fri Sep 30 17:01:21 2016 +1000
xf86-input-libinput 0.20.0 Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/configure.ac b/configure.ac index 4158e57..a1f80fe 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-input-libinput], - [0.19.0], + [0.20.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xf86-input-libinput]) AC_CONFIG_SRCDIR([Makefile.am]) commit 0cfe9ec6c23e73507fd0797bae24c5ed6fcce033 Author: Michel Dänzer <michel.daen...@amd.com> Date: Fri Sep 16 17:26:06 2016 +0900 Fix --with-xorg-conf-dir default value If --prefix isn't specified on the command line, $prefix contains "NONE" at this point, not the default prefix value. So make install would attempt to install the xorg.conf.d snippet to ${DESTDIR}NONE/share/X11/xorg.conf.d/. Avoid this by leaving ${prefix} verbatim in the default value, to be resolved by make. Signed-off-by: Michel Dänzer <michel.daen...@amd.com> Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/configure.ac b/configure.ac index 4c72c75..4158e57 100644 --- a/configure.ac +++ b/configure.ac @@ -58,9 +58,9 @@ AC_SUBST(inputdir) AC_ARG_WITH(xorg-conf-dir, AC_HELP_STRING([--with-xorg-conf-dir=DIR], - [Default xorg.conf.d directory [[default=$prefix/share/X11/xorg.conf.d/]]]), + [Default xorg.conf.d directory [[default=${prefix}/share/X11/xorg.conf.d]]]), [xorgconfdir="$withval"], - [xorgconfdir="$prefix/share/X11/xorg.conf.d"]) + [xorgconfdir='${prefix}/share/X11/xorg.conf.d']) AC_SUBST(xorgconfdir) # X Server SDK location is required to install header files commit b87d2530db46a08de15376722873295e01bef16f Author: Keith Packard <kei...@keithp.com> Date: Fri Sep 16 10:18:31 2016 -0700 Initializing strip association with wrong index This looks like a cut&paste coding error to me, and it generated a compiler warning about possibly uninitialized value. Signed-off-by: Keith Packard <kei...@keithp.com> Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/src/xf86libinput.c b/src/xf86libinput.c index 888ba21..21f87f5 100644 --- a/src/xf86libinput.c +++ b/src/xf86libinput.c @@ -4537,7 +4537,7 @@ LibinputInitModeGroupProperties(DeviceIntPtr dev, nstrips = libinput_device_tablet_pad_get_num_strips(device); if (nstrips) { for (s = 0; s < nstrips; s++) { - associations[r] = -1; + associations[s] = -1; for (g = 0; g < ngroups; g++) { group = libinput_device_tablet_pad_get_mode_group(device, g); if (libinput_tablet_pad_mode_group_has_strip(group, s)) { commit 2f1df46ba9ef91c079f6485c04ac7c5515d6057a Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Tue Sep 13 14:37:07 2016 +1000 Correct the horizontal scroll property name Clear typo. Not bothering to be backwards compatible here, anything that uses the #define will update on rebuild, anyone using the string directly should've told me about the typo... Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> Reviewed-by: Hans de Goede <hdego...@redhat.com> diff --git a/include/libinput-properties.h b/include/libinput-properties.h index e405453..8c6942d 100644 --- a/include/libinput-properties.h +++ b/include/libinput-properties.h @@ -147,7 +147,7 @@ /* Horizontal scroll events enabled: BOOL, 1 value (0 or 1). * If disabled, horizontal scroll events are discarded */ -#define LIBINPUT_PROP_HORIZ_SCROLL_ENABLED "libinput Horizonal Scroll Enabled" +#define LIBINPUT_PROP_HORIZ_SCROLL_ENABLED "libinput Horizontal Scroll Enabled" /* Number of modes each pad mode group has available: CARD8, one for each * pad mode group, read-only. commit fa69bb1bc244f378507e1ef2fbcb3ea343a59a32 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Thu Aug 18 15:13:09 2016 +1000 Always delay hotplugging subdevices Avoid creating new devices from within the input thread which was the case for tablet tools. It requires a lot more care about locking and has a potential to mess up things. Instead, schedule a WorkProc and buffer all events until we have the device created. Once that's done, replay the event sequence so far. If the device comes into proximity and out again before we manage to create the new device we just ditch the whole sequence and wait for the next proximity in. Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/src/xf86libinput.c b/src/xf86libinput.c index acca537..888ba21 100644 --- a/src/xf86libinput.c +++ b/src/xf86libinput.c @@ -102,6 +102,16 @@ struct xf86libinput_device { struct xorg_list unclaimed_tablet_tool_list; }; +struct xf86libinput_tablet_tool_queued_event { + struct xorg_list node; + struct libinput_event_tablet_tool *event; +}; + +struct xf86libinput_tablet_tool_event_queue { + bool need_to_queue; + struct xorg_list event_list; +}; + struct xf86libinput_tablet_tool { struct xorg_list node; struct libinput_tablet_tool *tool; @@ -165,20 +175,22 @@ struct xf86libinput { bool allow_mode_group_updates; }; -enum hotplug_when { - HOTPLUG_LATER, - HOTPLUG_NOW, +enum event_handling { + EVENT_QUEUED, + EVENT_HANDLED, }; -static DeviceIntPtr +static void xf86libinput_create_subdevice(InputInfoPtr pInfo, uint32_t capabilities, - enum hotplug_when, XF86OptionPtr extra_opts); static inline void update_mode_prop(InputInfoPtr pInfo, struct libinput_event_tablet_pad *event); +static enum event_handling +xf86libinput_handle_event(struct libinput_event *event); + static inline int use_server_fd(const InputInfoPtr pInfo) { return pInfo->fd > -1 && (pInfo->flags & XI86_SERVER_FD); @@ -1412,27 +1424,120 @@ xf86libinput_pick_device(struct xf86libinput_device *shared_device, } static void +xf86libinput_tool_destroy_queued_event(struct xf86libinput_tablet_tool_queued_event *qe) +{ + struct libinput_event *e; + + e = libinput_event_tablet_tool_get_base_event(qe->event); + libinput_event_destroy(e); + xorg_list_del(&qe->node); + free(qe); +} + +static void +xf86libinput_tool_replay_events(struct xf86libinput_tablet_tool_event_queue *queue) +{ + struct xf86libinput_tablet_tool_queued_event *qe, *tmp; + + xorg_list_for_each_entry_safe(qe, tmp, &queue->event_list, node) { + struct libinput_event *e; + + e = libinput_event_tablet_tool_get_base_event(qe->event); + xf86libinput_handle_event(e); + xf86libinput_tool_destroy_queued_event(qe); + } +} + +static bool +xf86libinput_tool_queue_event(struct libinput_event_tablet_tool *event) +{ + struct libinput_event *e; + struct libinput_tablet_tool *tool; + struct xf86libinput_tablet_tool_event_queue *queue; + struct xf86libinput_tablet_tool_queued_event *qe; + + tool = libinput_event_tablet_tool_get_tool(event); + if (!tool) + return true; + + queue = libinput_tablet_tool_get_user_data(tool); + if (!queue) + return false; + + if (!queue->need_to_queue) { + if (!xorg_list_is_empty(&queue->event_list)) { + libinput_tablet_tool_set_user_data(tool, NULL); + xf86libinput_tool_replay_events(queue); + free(queue); + } + + return false; + } + + /* We got the prox out while still queuing, just ditch the whole + * series of events and the event queue with it. */ + if (libinput_event_tablet_tool_get_proximity_state(event) == + LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT) { + struct xf86libinput_tablet_tool_queued_event *tmp; + + xorg_list_for_each_entry_safe(qe, tmp, &queue->event_list, node) + xf86libinput_tool_destroy_queued_event(qe); + + libinput_tablet_tool_set_user_data(tool, NULL); + free(queue); + + /* we destroy the event here but return true + * to make sure the event looks like it got queued and the + * caller doesn't destroy it for us + */ + e = libinput_event_tablet_tool_get_base_event(event); + libinput_event_destroy(e); + return true; + } + + qe = calloc(1, sizeof(*qe)); + if (!qe) { + e = libinput_event_tablet_tool_get_base_event(event); + libinput_event_destroy(e); + return true; + } + + qe->event = event; + xorg_list_append(&qe->node, &queue->event_list); + + return true; +} + +static enum event_handling xf86libinput_handle_tablet_tip(InputInfoPtr pInfo, struct libinput_event_tablet_tool *event) { enum libinput_tablet_tool_tip_state state; const BOOL is_absolute = TRUE; + if (xf86libinput_tool_queue_event(event)) + return EVENT_QUEUED; + state = libinput_event_tablet_tool_get_tip_state(event); xf86PostButtonEventP(pInfo->dev, is_absolute, 1, state == LIBINPUT_TABLET_TOOL_TIP_DOWN ? 1 : 0, 0, 0, NULL); + + return EVENT_HANDLED; } -static void +static enum event_handling xf86libinput_handle_tablet_button(InputInfoPtr pInfo, struct libinput_event_tablet_tool *event) { enum libinput_button_state state; uint32_t button, b; + if (xf86libinput_tool_queue_event(event)) + return EVENT_QUEUED; + button = libinput_event_tablet_tool_get_button(event); state = libinput_event_tablet_tool_get_button_state(event); @@ -1443,9 +1548,11 @@ xf86libinput_handle_tablet_button(InputInfoPtr pInfo, b, state == LIBINPUT_BUTTON_STATE_PRESSED ? 1 : 0, 0, 0, NULL); + + return EVENT_HANDLED; } -static void +static enum event_handling xf86libinput_handle_tablet_axis(InputInfoPtr pInfo, struct libinput_event_tablet_tool *event) { @@ -1455,6 +1562,9 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo, struct libinput_tablet_tool *tool; double value; + if (xf86libinput_tool_queue_event(event)) + return EVENT_QUEUED; + value = libinput_event_tablet_tool_get_x_transformed(event, TABLET_AXIS_MAX); valuator_mask_set_double(mask, 0, value); @@ -1502,13 +1612,15 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo, default: xf86IDrvMsg(pInfo, X_ERROR, "Invalid rotation axis on tool\n"); - return; + return EVENT_HANDLED; } valuator_mask_set_double(mask, valuator, value); } xf86PostMotionEventM(dev, Absolute, mask); + + return EVENT_HANDLED; } static inline const char * @@ -1532,47 +1644,35 @@ tool_type_to_str(enum libinput_tablet_tool_type type) return str; } -static void -xf86libinput_handle_tablet_proximity(InputInfoPtr pInfo, - struct libinput_event_tablet_tool *event) +static inline void +xf86libinput_create_tool_subdevice(InputInfoPtr pInfo, + struct libinput_event_tablet_tool *event) { struct xf86libinput *driver_data = pInfo->private; struct xf86libinput_device *shared_device = driver_data->shared_device; - struct xf86libinput *dev = pInfo->private; - struct libinput_tablet_tool *tool; struct xf86libinput_tablet_tool *t; + struct xf86libinput_tablet_tool_event_queue *queue; + struct libinput_tablet_tool *tool; uint64_t serial, tool_id; XF86OptionPtr options = NULL; - DeviceIntPtr pDev = pInfo->dev; char name[64]; - ValuatorMask *mask = driver_data->valuators; - double x, y; - BOOL in_prox; - x = libinput_event_tablet_tool_get_x_transformed(event, TABLET_AXIS_MAX); - y = libinput_event_tablet_tool_get_y_transformed(event, TABLET_AXIS_MAX); - valuator_mask_set_double(mask, 0, x); - valuator_mask_set_double(mask, 1, y); + t = calloc(1, sizeof *t); + if (!t) + return; + + queue = calloc(1, sizeof(*queue)); + if (!queue) { + free(t); + return; + } + queue->need_to_queue = true; + xorg_list_init(&queue->event_list); tool = libinput_event_tablet_tool_get_tool(event); serial = libinput_tablet_tool_get_serial(tool); tool_id = libinput_tablet_tool_get_tool_id(tool); - xorg_list_for_each_entry(dev, - &shared_device->device_list, - shared_device_link) { - if (dev->tablet_tool && - libinput_tablet_tool_get_serial(dev->tablet_tool) == serial && - libinput_tablet_tool_get_tool_id(dev->tablet_tool) == tool_id) { - pDev = dev->pInfo->dev; - goto out; - } - } - - t = calloc(1, sizeof *t); - if (!t) - return; - t->tool = libinput_tablet_tool_ref(tool); xorg_list_append(&t->node, &shared_device->unclaimed_tablet_tool_list); @@ -1587,12 +1687,70 @@ xf86libinput_handle_tablet_proximity(InputInfoPtr pInfo, (uint32_t)serial) > strlen(pInfo->name)) options = xf86ReplaceStrOption(options, "Name", name); - pDev = xf86libinput_create_subdevice(pInfo, CAP_TABLET_TOOL, HOTPLUG_NOW, options); + libinput_tablet_tool_set_user_data(tool, queue); + xf86libinput_tool_queue_event(event); + + xf86libinput_create_subdevice(pInfo, CAP_TABLET_TOOL, options); +} + +static inline DeviceIntPtr +xf86libinput_find_device_for_tool(InputInfoPtr pInfo, + struct libinput_tablet_tool *tool) +{ + struct xf86libinput *dev = pInfo->private; + struct xf86libinput *driver_data = pInfo->private; + struct xf86libinput_device *shared_device = driver_data->shared_device; + uint64_t serial = libinput_tablet_tool_get_serial(tool); + uint64_t tool_id = libinput_tablet_tool_get_tool_id(tool); + + xorg_list_for_each_entry(dev, + &shared_device->device_list, + shared_device_link) { + if (dev->tablet_tool && + libinput_tablet_tool_get_serial(dev->tablet_tool) == serial && + libinput_tablet_tool_get_tool_id(dev->tablet_tool) == tool_id) { + return dev->pInfo->dev; + } + } + + return NULL; +} + +static enum event_handling +xf86libinput_handle_tablet_proximity(InputInfoPtr pInfo, + struct libinput_event_tablet_tool *event) +{ + struct xf86libinput *driver_data = pInfo->private; + struct libinput_tablet_tool *tool; + DeviceIntPtr pDev; + ValuatorMask *mask = driver_data->valuators; + double x, y; + BOOL in_prox; + + tool = libinput_event_tablet_tool_get_tool(event); + pDev = xf86libinput_find_device_for_tool(pInfo, tool); -out: in_prox = libinput_event_tablet_tool_get_proximity_state(event) == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN; + + if (pDev == NULL && in_prox) { + xf86libinput_create_tool_subdevice(pInfo, event); + return EVENT_QUEUED; + } + + if (xf86libinput_tool_queue_event(event)) + return EVENT_QUEUED; + + BUG_RETURN_VAL(pDev == NULL, EVENT_HANDLED); + + x = libinput_event_tablet_tool_get_x_transformed(event, TABLET_AXIS_MAX); + y = libinput_event_tablet_tool_get_y_transformed(event, TABLET_AXIS_MAX); + valuator_mask_set_double(mask, 0, x); + valuator_mask_set_double(mask, 1, y); + xf86PostProximityEventM(pDev, in_prox, mask); + + return EVENT_HANDLED; } static void @@ -1671,12 +1829,13 @@ xf86libinput_handle_tablet_pad_ring(InputInfoPtr pInfo, xf86PostMotionEventM(dev, Absolute, mask); } -static void +static enum event_handling xf86libinput_handle_event(struct libinput_event *event) { struct libinput_device *device; enum libinput_event_type type; InputInfoPtr pInfo; + enum event_handling event_handling = EVENT_HANDLED; type = libinput_event_get_type(event); device = libinput_event_get_device(event); @@ -1684,7 +1843,7 @@ xf86libinput_handle_event(struct libinput_event *event) event); if (!pInfo || !pInfo->dev->public.on) - return; + goto out; switch (type) { case LIBINPUT_EVENT_NONE: @@ -1730,19 +1889,19 @@ xf86libinput_handle_event(struct libinput_event *event) case LIBINPUT_EVENT_GESTURE_PINCH_END: break; case LIBINPUT_EVENT_TABLET_TOOL_AXIS: - xf86libinput_handle_tablet_axis(pInfo, + event_handling = xf86libinput_handle_tablet_axis(pInfo, libinput_event_get_tablet_tool_event(event)); break; case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: - xf86libinput_handle_tablet_button(pInfo, + event_handling = xf86libinput_handle_tablet_button(pInfo, libinput_event_get_tablet_tool_event(event)); break; case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: - xf86libinput_handle_tablet_proximity(pInfo, + event_handling = xf86libinput_handle_tablet_proximity(pInfo, libinput_event_get_tablet_tool_event(event)); break; case LIBINPUT_EVENT_TABLET_TOOL_TIP: - xf86libinput_handle_tablet_tip(pInfo, + event_handling = xf86libinput_handle_tablet_tip(pInfo, libinput_event_get_tablet_tool_event(event)); break; case LIBINPUT_EVENT_TABLET_PAD_BUTTON: @@ -1758,6 +1917,9 @@ xf86libinput_handle_event(struct libinput_event *event) libinput_event_get_tablet_pad_event(event)); break; } + +out: + return event_handling; } static void @@ -1779,8 +1941,8 @@ xf86libinput_read_input(InputInfoPtr pInfo) } while ((event = libinput_get_event(libinput))) { - xf86libinput_handle_event(event); - libinput_event_destroy(event); + if (xf86libinput_handle_event(event) == EVENT_HANDLED) + libinput_event_destroy(event); } } @@ -2526,10 +2688,9 @@ xf86libinput_hotplug_device_cb(ClientPtr client, pointer closure) return TRUE; } -static DeviceIntPtr +static void xf86libinput_create_subdevice(InputInfoPtr pInfo, uint32_t capabilities, - enum hotplug_when when, XF86OptionPtr extra_options) { struct xf86libinput *driver_data = pInfo->private; @@ -2570,18 +2731,14 @@ xf86libinput_create_subdevice(InputInfoPtr pInfo, hotplug = calloc(1, sizeof(*hotplug)); if (!hotplug) - return NULL; + return; hotplug->input_options = iopts; hotplug->attrs = DuplicateInputAttributes(pInfo->attrs); xf86IDrvMsg(pInfo, X_INFO, "needs a virtual subdevice\n"); - if (when == HOTPLUG_LATER) - QueueWorkProc(xf86libinput_hotplug_device_cb, serverClient, hotplug); - else - return xf86libinput_hotplug_device(hotplug); - return NULL; + QueueWorkProc(xf86libinput_hotplug_device_cb, serverClient, hotplug); } static inline uint32_t @@ -2606,6 +2763,7 @@ claim_tablet_tool(InputInfoPtr pInfo) { struct xf86libinput *driver_data = pInfo->private; struct xf86libinput_device *shared_device = driver_data->shared_device; + struct xf86libinput_tablet_tool_event_queue *queue; struct xf86libinput_tablet_tool *t; uint64_t serial, tool_id; @@ -2618,6 +2776,9 @@ claim_tablet_tool(InputInfoPtr pInfo) if (libinput_tablet_tool_get_serial(t->tool) == serial && libinput_tablet_tool_get_tool_id(t->tool) == tool_id) { driver_data->tablet_tool = t->tool; + queue = libinput_tablet_tool_get_user_data(t->tool); + if (queue) + queue->need_to_queue = false; xorg_list_del(&t->node); free(t); return TRUE; @@ -2749,7 +2910,6 @@ xf86libinput_pre_init(InputDriverPtr drv, driver_data->capabilities &= ~CAP_KEYBOARD; xf86libinput_create_subdevice(pInfo, CAP_KEYBOARD, - HOTPLUG_LATER, NULL); } commit af4fa36884b1945a231b2f7ebe011726b5a604c1 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Tue Aug 16 09:06:27 2016 +1000 Add support for configurable tap button mapping Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> Reviewed-by: Hans de Goede <hdego...@redhat.com> diff --git a/configure.ac b/configure.ac index 8647dfa..4c72c75 100644 --- a/configure.ac +++ b/configure.ac @@ -45,7 +45,7 @@ XORG_DEFAULT_OPTIONS # Obtain compiler/linker options from server and required extensions PKG_CHECK_MODULES(XORG, [xorg-server >= 1.10] xproto [inputproto >= 2.2]) -PKG_CHECK_MODULES(LIBINPUT, [libinput >= 1.3.901]) +PKG_CHECK_MODULES(LIBINPUT, [libinput >= 1.4.901]) # Define a configure option for an alternate input module directory AC_ARG_WITH(xorg-module-dir, diff --git a/include/libinput-properties.h b/include/libinput-properties.h index b186cb3..e405453 100644 --- a/include/libinput-properties.h +++ b/include/libinput-properties.h @@ -42,6 +42,13 @@ /* Tap drag lock default enabled/disabled: BOOL, 1 value, read-only */ #define LIBINPUT_PROP_TAP_DRAG_LOCK_DEFAULT "libinput Tapping Drag Lock Enabled Default" +/* Tap button order: BOOL, 2 values in order LRM, LMR, only one may be set + at any time */ +#define LIBINPUT_PROP_TAP_BUTTONMAP "libinput Tapping Button Mapping Enabled" + +/* Tap button default order: BOOL, 2 values in order LRM, LMR, read-only */ +#define LIBINPUT_PROP_TAP_BUTTONMAP_DEFAULT "libinput Tapping Button Mapping Default" + /* Calibration matrix: FLOAT, 9 values of a 3x3 matrix, in rows */ #define LIBINPUT_PROP_CALIBRATION "libinput Calibration Matrix" diff --git a/man/libinput.man b/man/libinput.man index 563628a..92e181e 100644 --- a/man/libinput.man +++ b/man/libinput.man @@ -133,6 +133,10 @@ clockwise. The angle must be between 0.0 (inclusive) and 360.0 (exclusive). .BI "Option \*qTapping\*q \*q" bool \*q Enables or disables tap-to-click behavior. .TP 7 +.BI "Option \*qTappingButtonMap\*q \*q" (lrm|lmr) \*q +Set the button mapping for 1/2/3-finger taps to left/right/middle or +left/middle/right, respectively. +.TP 7 .BI "Option \*qTappingDrag\*q \*q" bool \*q Enables or disables drag during tapping behavior ("tap-and-drag"). When enabled, a tap followed by a finger held down causes a single button down @@ -188,6 +192,10 @@ driver. .BI "libinput Tapping Enabled" 1 boolean value (8 bit, 0 or 1). 1 enables tapping .TP 7 +.BI "libinput Tapping Button Mapping Enabled" +2 boolean value (8 bit, 0 or 1), in order "lrm" and "lmr". Indicates which +button mapping is currently enabled on this device. +.TP 7 .BI "libinput Tapping Drag Lock Enabled" 1 boolean value (8 bit, 0 or 1). 1 enables drag lock during tapping .TP 7 diff --git a/src/xf86libinput.c b/src/xf86libinput.c index 61a70a4..acca537 100644 --- a/src/xf86libinput.c +++ b/src/xf86libinput.c @@ -135,6 +135,7 @@ struct xf86libinput { BOOL tapping; BOOL tap_drag; BOOL tap_drag_lock; + enum libinput_config_tap_button_map tap_button_map; BOOL natural_scrolling; BOOL left_handed; BOOL middle_emulation; @@ -434,6 +435,21 @@ LibinputApplyConfig(DeviceIntPtr dev) driver_data->options.tapping); if (libinput_device_config_tap_get_finger_count(device) > 0 && + libinput_device_config_tap_set_button_map(device, + driver_data->options.tap_button_map) != LIBINPUT_CONFIG_STATUS_SUCCESS) { + const char *map; + + switch(driver_data->options.tap_button_map) { + case LIBINPUT_CONFIG_TAP_MAP_LRM: map = "lrm"; break; + case LIBINPUT_CONFIG_TAP_MAP_LMR: map = "lmr"; break; + default: map = "unknown"; break; + } + xf86IDrvMsg(pInfo, X_ERROR, + "Failed to set Tapping ButtonMap to %s\n", + map); + } + + if (libinput_device_config_tap_get_finger_count(device) > 0 && libinput_device_config_tap_set_drag_lock_enabled(device, driver_data->options.tap_drag_lock) != LIBINPUT_CONFIG_STATUS_SUCCESS) xf86IDrvMsg(pInfo, X_ERROR, @@ -1942,6 +1958,43 @@ xf86libinput_parse_tap_drag_lock_option(InputInfoPtr pInfo, return drag_lock; } +static inline enum libinput_config_tap_button_map +xf86libinput_parse_tap_buttonmap_option(InputInfoPtr pInfo, + struct libinput_device *device) +{ + enum libinput_config_tap_button_map map; + char *str; + + if (libinput_device_config_tap_get_finger_count(device) == 0) + return FALSE; + + map = libinput_device_config_tap_get_button_map(device); + str = xf86SetStrOption(pInfo->options, + "TappingButtonMap", + NULL); + if (str) { + if (strcmp(str, "lmr") == 0) + map = LIBINPUT_CONFIG_TAP_MAP_LMR; + else if (strcmp(str, "lrm") == 0) + map = LIBINPUT_CONFIG_TAP_MAP_LRM; + else + xf86IDrvMsg(pInfo, X_ERROR, + "Invalid TapButtonMap: %s\n", + str); + free(str); + } + + if (libinput_device_config_send_events_set_mode(device, map) != + LIBINPUT_CONFIG_STATUS_SUCCESS) { + xf86IDrvMsg(pInfo, X_ERROR, + "Failed to set Tapping Drag Lock to %d\n", + map); + map = libinput_device_config_tap_get_button_map(device); + } + + return map; +} + static inline double xf86libinput_parse_accel_option(InputInfoPtr pInfo, struct libinput_device *device) @@ -2350,6 +2403,7 @@ xf86libinput_parse_options(InputInfoPtr pInfo, options->tapping = xf86libinput_parse_tap_option(pInfo, device); options->tap_drag = xf86libinput_parse_tap_drag_option(pInfo, device); options->tap_drag_lock = xf86libinput_parse_tap_drag_lock_option(pInfo, device); + options->tap_button_map = xf86libinput_parse_tap_buttonmap_option(pInfo, device); options->speed = xf86libinput_parse_accel_option(pInfo, device); options->accel_profile = xf86libinput_parse_accel_profile_option(pInfo, device); options->natural_scrolling = xf86libinput_parse_natscroll_option(pInfo, device); @@ -2780,6 +2834,8 @@ static Atom prop_tap_drag; static Atom prop_tap_drag_default; static Atom prop_tap_drag_lock; static Atom prop_tap_drag_lock_default; +static Atom prop_tap_buttonmap; +static Atom prop_tap_buttonmap_default; static Atom prop_calibration; static Atom prop_calibration_default; static Atom prop_accel; @@ -2983,6 +3039,39 @@ LibinputSetPropertyTapDragLock(DeviceIntPtr dev, } static inline int +LibinputSetPropertyTapButtonmap(DeviceIntPtr dev, + Atom atom, + XIPropertyValuePtr val, + BOOL checkonly) +{ + InputInfoPtr pInfo = dev->public.devicePrivate; + struct xf86libinput *driver_data = pInfo->private; + BOOL* data; + enum libinput_config_tap_button_map map; + + if (val->format != 8 || val->size != 2 || val->type != XA_INTEGER) + return BadMatch; + + data = (BOOL*)val->data; + + if (checkonly && + ((data[0] && data[1]) || (!data[0] && !data[1]))) + return BadValue; + + if (data[0]) + map = LIBINPUT_CONFIG_TAP_MAP_LRM; + else if (data[1]) + map = LIBINPUT_CONFIG_TAP_MAP_LMR; + else + return BadValue; + + if (!checkonly) + driver_data->options.tap_button_map = map; + + return Success; +} + +static inline int LibinputSetPropertyCalibration(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, @@ -3525,6 +3614,8 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, rc = LibinputSetPropertyTapDrag(dev, atom, val, checkonly); else if (atom == prop_tap_drag_lock) rc = LibinputSetPropertyTapDragLock(dev, atom, val, checkonly); + else if (atom == prop_tap_buttonmap) + rc = LibinputSetPropertyTapButtonmap(dev, atom, val, checkonly); else if (atom == prop_calibration) rc = LibinputSetPropertyCalibration(dev, atom, val, checkonly); @@ -3567,6 +3658,7 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, atom == prop_tap_default || atom == prop_tap_drag_default || atom == prop_tap_drag_lock_default || + atom == prop_tap_buttonmap_default || atom == prop_calibration_default || atom == prop_accel_default || atom == prop_accel_profile_default || @@ -3693,6 +3785,57 @@ LibinputInitTapDragLockProperty(DeviceIntPtr dev, } static void +LibinputInitTapButtonmapProperty(DeviceIntPtr dev, + struct xf86libinput *driver_data, + struct libinput_device *device) +{ + enum libinput_config_tap_button_map map; + BOOL data[2] = {0}; + + map = driver_data->options.tap_button_map; + + if (libinput_device_config_tap_get_finger_count(device) == 0) + return; + + switch (map) { + case LIBINPUT_CONFIG_TAP_MAP_LRM: + data[0] = 1; + break; + case LIBINPUT_CONFIG_TAP_MAP_LMR: + data[1] = 1; + break; + default: + break; + } + + prop_tap_buttonmap = LibinputMakeProperty(dev, + LIBINPUT_PROP_TAP_BUTTONMAP, + XA_INTEGER, 8, + 2, data); + if (!prop_tap_buttonmap) + return; + + map = libinput_device_config_tap_get_default_button_map(device); + memset(data, 0, sizeof(data)); + + switch (map) { + case LIBINPUT_CONFIG_TAP_MAP_LRM: + data[0] = 1; + break; + case LIBINPUT_CONFIG_TAP_MAP_LMR: + data[1] = 1; + break; + default: + break; + } + + prop_tap_buttonmap_default = LibinputMakeProperty(dev, + LIBINPUT_PROP_TAP_BUTTONMAP_DEFAULT, + XA_INTEGER, 8, + 2, data); +} + +static void LibinputInitCalibrationProperty(DeviceIntPtr dev, struct xf86libinput *driver_data, struct libinput_device *device) @@ -4344,6 +4487,7 @@ LibinputInitProperty(DeviceIntPtr dev) LibinputInitTapProperty(dev, driver_data, device); LibinputInitTapDragProperty(dev, driver_data, device); LibinputInitTapDragLockProperty(dev, driver_data, device); + LibinputInitTapButtonmapProperty(dev, driver_data, device); LibinputInitCalibrationProperty(dev, driver_data, device); LibinputInitAccelProperty(dev, driver_data, device); LibinputInitNaturalScrollProperty(dev, driver_data, device); commit a5b3c209fc8619dea6ac57420fb7837cf6e0e8bf Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Mon May 30 15:27:52 2016 +1000 Add support for the rotation configuration Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/configure.ac b/configure.ac index 64886f6..8647dfa 100644 --- a/configure.ac +++ b/configure.ac @@ -45,7 +45,7 @@ XORG_DEFAULT_OPTIONS # Obtain compiler/linker options from server and required extensions PKG_CHECK_MODULES(XORG, [xorg-server >= 1.10] xproto [inputproto >= 2.2]) -PKG_CHECK_MODULES(LIBINPUT, [libinput >= 1.2.901]) +PKG_CHECK_MODULES(LIBINPUT, [libinput >= 1.3.901]) # Define a configure option for an alternate input module directory AC_ARG_WITH(xorg-module-dir, diff --git a/include/libinput-properties.h b/include/libinput-properties.h index 7335c3f..b186cb3 100644 --- a/include/libinput-properties.h +++ b/include/libinput-properties.h @@ -170,4 +170,10 @@ */ #define LIBINPUT_PROP_TABLET_PAD_MODE_GROUP_RINGS "libinput Pad Mode Group Rings" +/* Device rotation: FLOAT, 1 value, 32 bit */ +#define LIBINPUT_PROP_ROTATION_ANGLE "libinput Rotation Angle" + +/* Device rotation: FLOAT, 1 value, 32 bit, read-only */ +#define LIBINPUT_PROP_ROTATION_ANGLE_DEFAULT "libinput Rotation Angle Default" + #endif /* _LIBINPUT_PROPERTIES_H_ */ diff --git a/man/libinput.man b/man/libinput.man index a11e21f..563628a 100644 --- a/man/libinput.man +++ b/man/libinput.man @@ -126,6 +126,10 @@ events. Sets the send events mode to disabled, enabled, or "disable when an external mouse is connected". .TP 7 +.BI "Option \*qRotationAngle\*q \*q" float \*q +Sets the rotation angle of the device to the given angle, in degrees +clockwise. The angle must be between 0.0 (inclusive) and 360.0 (exclusive). +.TP 7 .BI "Option \*qTapping\*q \*q" bool \*q Enables or disables tap-to-click behavior. .TP 7 @@ -239,6 +243,10 @@ disabled. .BI "libinput Disable While Typing Enabled" 1 boolean value (8 bit, 0 or 1). Indicates if disable while typing is enabled or disabled. +.TP 7 +.BI "libinput Rotation Angle" +1 32-bit float value [0.0 to 360.0). Sets the rotation angle of the device, +clockwise of its natural neutral position. .PP The above properties have a .BI "libinput <property name> Default" diff --git a/src/xf86libinput.c b/src/xf86libinput.c index e1ca405..61a70a4 100644 --- a/src/xf86libinput.c +++ b/src/xf86libinput.c @@ -150,6 +150,8 @@ struct xf86libinput { unsigned char btnmap[MAX_BUTTONS + 1]; BOOL horiz_scrolling_enabled; + + float rotation_angle; } options; struct draglock draglock; @@ -520,6 +522,13 @@ LibinputApplyConfig(DeviceIntPtr dev) xf86IDrvMsg(pInfo, X_ERROR, "Failed to set DisableWhileTyping to %d\n", driver_data->options.disable_while_typing); + + if (libinput_device_config_rotation_is_available(device) && + libinput_device_config_rotation_set_angle(device, driver_data->options.rotation_angle) != LIBINPUT_CONFIG_STATUS_SUCCESS) + xf86IDrvMsg(pInfo, X_ERROR, + "Failed to set RotationAngle to %.2f\n", + driver_data->options.rotation_angle); + } static int @@ -2307,6 +2316,29 @@ xf86libinput_parse_horiz_scroll_option(InputInfoPtr pInfo) return xf86SetBoolOption(pInfo->options, "HorizontalScrolling", TRUE); } +static inline double +xf86libinput_parse_rotation_angle_option(InputInfoPtr pInfo, + struct libinput_device *device) +{ + double angle; + + if (!libinput_device_config_rotation_is_available(device)) + return 0.0; + + angle = xf86SetRealOption(pInfo->options, + "RotationAngle", + libinput_device_config_rotation_get_default_angle(device)); + if (libinput_device_config_rotation_set_angle(device, angle) != + LIBINPUT_CONFIG_STATUS_SUCCESS) { + xf86IDrvMsg(pInfo, X_ERROR, + "Invalid angle %.2f, using 0.0 instead\n", + angle); + angle = libinput_device_config_rotation_get_angle(device);