[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-input-libinput: Changes to 'debian-unstable'



 Makefile.am                   |    2 
 conf/40-libinput.conf         |   28 +
 conf/60-libinput.conf         |   28 -
 configure.ac                  |    8 
 debian/changelog              |    7 
 debian/control                |   19 
 debian/rules                  |    4 
 include/libinput-properties.h |   41 +
 man/libinput.man              |   22 
 src/xf86libinput.c            |  951 ++++++++++++++++++++++++++++++++++++++----
 10 files changed, 969 insertions(+), 141 deletions(-)

New commits:
commit 8b7f5255a2b3d5451228a85ecc030cedcc428337
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Fri Sep 30 15:05:35 2016 +0300

    release to unstable

diff --git a/debian/changelog b/debian/changelog
index 7e1ef41..827ff47 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,9 @@
-xserver-xorg-input-libinput (0.20.0-1) UNRELEASED; urgency=medium
+xserver-xorg-input-libinput (0.20.0-1) unstable; urgency=medium
 
   * New upstream release.
   * control, rules: Drop -dbg package.
 
- -- Timo Aaltonen <tjaalton@debian.org>  Fri, 30 Sep 2016 14:56:53 +0300
+ -- Timo Aaltonen <tjaalton@debian.org>  Fri, 30 Sep 2016 15:05:19 +0300
 
 xserver-xorg-input-libinput (0.19.0-1) unstable; urgency=medium
 

commit 881f33c0eeca662fe7303670938a8b68cb96959c
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Fri Sep 30 15:05:07 2016 +0300

    control, rules: Drop -dbg package.

diff --git a/debian/changelog b/debian/changelog
index 1ca7944..7e1ef41 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,7 @@
 xserver-xorg-input-libinput (0.20.0-1) UNRELEASED; urgency=medium
 
   * New upstream release.
+  * control, rules: Drop -dbg package.
 
  -- Timo Aaltonen <tjaalton@debian.org>  Fri, 30 Sep 2016 14:56:53 +0300
 
diff --git a/debian/control b/debian/control
index 8129a84..b31afe1 100644
--- a/debian/control
+++ b/debian/control
@@ -66,22 +66,3 @@ Provides:
  ${xinpdriver:Provides}
 Description: X.Org X server -- libinput input driver
  This is a udeb, or a microdeb, for the debian-installer.
-
-Package: xserver-xorg-input-libinput-dbg
-Architecture: linux-any
-Depends:
- ${misc:Depends},
- xserver-xorg-input-libinput (= ${binary:Version}),
-Section: debug
-Priority: extra
-Description: X.Org X server -- libinput input driver (debug symbols)
- This package provides the development headers for the libinput input driver
- found in xserver-xorg-input-libinput. Non-developers likely have little use
- for this package.
- .
- More information about X.Org can be found at:
- <URL:http://www.X.org>
- .
- This package is built from the X.org xf86-input-libinput driver module.
- .
- This package provides debugging symbols for this Xorg X driver.
diff --git a/debian/rules b/debian/rules
index 63cf94b..d19a5b2 100755
--- a/debian/rules
+++ b/debian/rules
@@ -19,7 +19,3 @@ override_dh_shlibdeps:
 
 %:
 	dh $@ --with quilt,autoreconf,xsf --builddirectory=build/
-
-# Debug package:
-override_dh_strip:
-	dh_strip --dbg-package=xserver-xorg-input-libinput-dbg

commit c983750b575ce93ee5ad9972258f7a0e38cf3f44
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Fri Sep 30 15:00:30 2016 +0300

    update changelog

diff --git a/debian/changelog b/debian/changelog
index 52f98ad..1ca7944 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+xserver-xorg-input-libinput (0.20.0-1) UNRELEASED; urgency=medium
+
+  * New upstream release.
+
+ -- Timo Aaltonen <tjaalton@debian.org>  Fri, 30 Sep 2016 14:56:53 +0300
+
 xserver-xorg-input-libinput (0.19.0-1) unstable; urgency=medium
 
   [ Andreas Boll ]

commit cd02040a5d4a8f120d225a4c09f5d1dfc751c0a8
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Fri Sep 30 17:01:21 2016 +1000

    xf86-input-libinput 0.20.0
    
    Signed-off-by: Peter Hutterer <peter.hutterer@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.daenzer@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.daenzer@amd.com>
    Signed-off-by: Peter Hutterer <peter.hutterer@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 <keithp@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 <keithp@keithp.com>
    Signed-off-by: Peter Hutterer <peter.hutterer@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.hutterer@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.hutterer@who-t.net>
    Reviewed-by: Hans de Goede <hdegoede@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.hutterer@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.hutterer@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.hutterer@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.hutterer@who-t.net>
    Reviewed-by: Hans de Goede <hdegoede@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);


Reply to: