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

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



Rebased ref, commits from common ancestor:
commit 6460e4fe5f9f640060f1e2ed7b3a0a47a7bf8e68
Author: Andreas Boll <andreas.boll.dev@gmail.com>
Date:   Mon Mar 14 17:52:13 2016 +0100

    control: Fix Vcs-Git field.

diff --git a/debian/changelog b/debian/changelog
index 1857d88..0111e53 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+xserver-xorg-input-libinput (0.18.0-2) UNRELEASED; urgency=medium
+
+  [ Andreas Boll ]
+  * control: Fix Vcs-Git field.
+
+ -- Timo Aaltonen <tjaalton@debian.org>  Fri, 11 Mar 2016 20:58:50 +0200
+
 xserver-xorg-input-libinput (0.18.0-1) unstable; urgency=medium
 
   * New upstream release.
diff --git a/debian/control b/debian/control
index da54cbf..8129a84 100644
--- a/debian/control
+++ b/debian/control
@@ -15,7 +15,7 @@ Build-Depends:
  xserver-xorg-dev (>= 2:1.15.99),
  xutils-dev,
 Standards-Version: 3.9.7
-Vcs-Git: https://anonscm.debian.org/pkg-xorg/driver/xserver-xorg-input-libinput.git
+Vcs-Git: https://anonscm.debian.org/git/pkg-xorg/driver/xserver-xorg-input-libinput.git
 Vcs-Browser: https://anonscm.debian.org/cgit/pkg-xorg/driver/xserver-xorg-input-libinput.git
 
 Package: xserver-xorg-input-libinput

commit cd59dc37414f1f37cd9ff72a5f6541f0424de0ec
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Thu Apr 7 10:20:41 2016 +0300

    release to unstable

diff --git a/debian/changelog b/debian/changelog
index 7797942..1857d88 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-xserver-xorg-input-libinput (0.18.0-1) UNRELEASED; urgency=medium
+xserver-xorg-input-libinput (0.18.0-1) unstable; urgency=medium
 
   * New upstream release.
   * control: Update the description to mention that this driver can
@@ -6,7 +6,7 @@ xserver-xorg-input-libinput (0.18.0-1) UNRELEASED; urgency=medium
   * control: Bump libinput-dev build-dependency.
   * control: Bump Standards-Version to 3.9.7 (no changes).
 
- -- Timo Aaltonen <tjaalton@debian.org>  Fri, 11 Mar 2016 20:58:50 +0200
+ -- Timo Aaltonen <tjaalton@debian.org>  Thu, 07 Apr 2016 10:20:31 +0300
 
 xserver-xorg-input-libinput (0.17.0-1) unstable; urgency=medium
 

commit 4e365c34712e0f520ba567889fab7ae62b0592ce
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Thu Apr 7 10:20:24 2016 +0300

    control: Bump Standards-Version to 3.9.7 (no changes).

diff --git a/debian/changelog b/debian/changelog
index 2d7e03b..7797942 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,7 @@ xserver-xorg-input-libinput (0.18.0-1) UNRELEASED; urgency=medium
   * control: Update the description to mention that this driver can
     replace -evdev and -synaptics.
   * control: Bump libinput-dev build-dependency.
+  * control: Bump Standards-Version to 3.9.7 (no changes).
 
  -- Timo Aaltonen <tjaalton@debian.org>  Fri, 11 Mar 2016 20:58:50 +0200
 
diff --git a/debian/control b/debian/control
index f0a675c..da54cbf 100644
--- a/debian/control
+++ b/debian/control
@@ -14,7 +14,7 @@ Build-Depends:
  x11proto-input-dev (>= 2.2),
  xserver-xorg-dev (>= 2:1.15.99),
  xutils-dev,
-Standards-Version: 3.9.6
+Standards-Version: 3.9.7
 Vcs-Git: https://anonscm.debian.org/pkg-xorg/driver/xserver-xorg-input-libinput.git
 Vcs-Browser: https://anonscm.debian.org/cgit/pkg-xorg/driver/xserver-xorg-input-libinput.git
 

commit b3ce8e800f5240131de831587f0c3fd45f7a99f6
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Thu Apr 7 10:19:32 2016 +0300

    bump version

diff --git a/debian/changelog b/debian/changelog
index 104300b..2d7e03b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,6 @@
-xserver-xorg-input-libinput (0.17.0-2) UNRELEASED; urgency=medium
+xserver-xorg-input-libinput (0.18.0-1) UNRELEASED; urgency=medium
 
+  * New upstream release.
   * control: Update the description to mention that this driver can
     replace -evdev and -synaptics.
   * control: Bump libinput-dev build-dependency.

commit 13726f404f872b8baee507e6b3d4931f1bda2254
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Thu Apr 7 13:31:28 2016 +1000

    xf86-input-libinput 0.18.0
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

diff --git a/configure.ac b/configure.ac
index cdb8aed..722411b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@
 # Initialize Autoconf
 AC_PREREQ([2.60])
 AC_INIT([xf86-input-libinput],
-        [0.17.0],
+        [0.18.0],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         [xf86-input-libinput])
 AC_CONFIG_SRCDIR([Makefile.am])

commit bd47ea7fb3733401c81beb7d35cc7e1b9da1e105
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Thu Mar 17 12:18:01 2016 +0200

    control: Bump libinput-dev build-dependency.

diff --git a/debian/changelog b/debian/changelog
index cee951b..104300b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,7 @@ xserver-xorg-input-libinput (0.17.0-2) UNRELEASED; urgency=medium
 
   * control: Update the description to mention that this driver can
     replace -evdev and -synaptics.
+  * control: Bump libinput-dev build-dependency.
 
  -- Timo Aaltonen <tjaalton@debian.org>  Fri, 11 Mar 2016 20:58:50 +0200
 
diff --git a/debian/control b/debian/control
index 7fd8cd7..f0a675c 100644
--- a/debian/control
+++ b/debian/control
@@ -6,7 +6,7 @@ Uploaders: Timo Aaltonen <tjaalton@debian.org>,
 Build-Depends:
  debhelper (>= 9),
  dh-autoreconf,
- libinput-dev (>= 1.0.901),
+ libinput-dev (>= 1.1.901),
  libudev-dev,
  pkg-config,
  quilt,

commit 5e7ee73fe24d53cba6a915223be53e0abcdaa70d
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Thu Dec 3 15:58:49 2015 +1000

    Support art pen rotation
    
    The art pen is a normal pen, but it does provide a rotation axis.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

diff --git a/src/xf86libinput.c b/src/xf86libinput.c
index 505c9b6..bc5d685 100644
--- a/src/xf86libinput.c
+++ b/src/xf86libinput.c
@@ -818,6 +818,12 @@ xf86libinput_init_tablet_pen_or_eraser(InputInfoPtr pInfo,
 					   min, max, res * 1000, 0, res * 1000, Absolute);
 	}
 
+	min = -TABLET_AXIS_MAX;
+	max = TABLET_AXIS_MAX;
+	if (libinput_tablet_tool_has_rotation(tool))
+		xf86InitValuatorAxisStruct(dev, axis++,
+					   XIGetKnownProperty(AXIS_LABEL_PROP_ABS_RZ),
+					   min, max, res * 1000, 0, res * 1000, Absolute);
 	return axis;
 }
 
@@ -1358,9 +1364,27 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
 	}
 
 	if (libinput_tablet_tool_has_rotation(tool)) {
+		int valuator;
+
 		value = libinput_event_tablet_tool_get_rotation(event);
 		value *= TABLET_AXIS_MAX;
-		valuator_mask_set_double(mask, 3, value);
+
+		switch (libinput_tablet_tool_get_type(tool)) {
+		case LIBINPUT_TABLET_TOOL_TYPE_PEN:
+		case LIBINPUT_TABLET_TOOL_TYPE_ERASER:
+			valuator = 5;
+			break;
+		case LIBINPUT_TABLET_TOOL_TYPE_MOUSE:
+		case LIBINPUT_TABLET_TOOL_TYPE_LENS:
+			valuator = 3;
+			break;
+		default:
+			xf86IDrvMsg(pInfo, X_ERROR,
+				    "Invalid rotation axis on tool\n");
+			break;
+		}
+
+		valuator_mask_set_double(mask, valuator, value);
 	}
 
 	xf86PostMotionEventM(dev, Absolute, mask);

commit 4564a92d59be39378170a2254ae1affb151a4757
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Thu Dec 3 15:41:30 2015 +1000

    Support the mouse/lens tool
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

diff --git a/src/xf86libinput.c b/src/xf86libinput.c
index 0b7dfaf..505c9b6 100644
--- a/src/xf86libinput.c
+++ b/src/xf86libinput.c
@@ -851,6 +851,39 @@ xf86libinput_init_tablet_airbrush(InputInfoPtr pInfo,
 }
 
 static void
+xf86libinput_init_tablet_mouse(InputInfoPtr pInfo,
+			       struct libinput_tablet_tool *tool)
+{
+	DeviceIntPtr dev = pInfo->dev;
+	int min, max, res;
+	int axis;
+
+	if (!libinput_tablet_tool_has_rotation(tool)) {
+		xf86IDrvMsg(pInfo, X_ERROR, "Mouse tool is missing the rotation axis\n");
+		return;
+	}
+
+	min = 0;
+	max = TABLET_AXIS_MAX;
+	res = 0;
+
+	/* The mouse/lens tool don't have pressure, but for backwards-compat
+	   with the xorg wacom driver we initialize the the axis anyway */
+	axis = 2;
+	xf86InitValuatorAxisStruct(dev, axis,
+				   XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE),
+				   min, max, res * 1000, 0, res * 1000, Absolute);
+
+	axis = 3;
+	min = -TABLET_AXIS_MAX;
+	max = TABLET_AXIS_MAX;
+	xf86InitValuatorAxisStruct(dev, axis,
+				   XIGetKnownProperty(AXIS_LABEL_PROP_ABS_RZ),
+				   min, max, res * 1000, 0, res * 1000, Absolute);
+	return;
+}
+
+static void
 xf86libinput_init_tablet(InputInfoPtr pInfo)
 {
 	DeviceIntPtr dev = pInfo->dev;
@@ -875,6 +908,8 @@ xf86libinput_init_tablet(InputInfoPtr pInfo)
 		naxes += 2;
 	if (libinput_tablet_tool_has_slider(tool))
 		naxes++;
+	if (libinput_tablet_tool_has_rotation(tool))
+		naxes++;
 
 	InitPointerDeviceStruct((DevicePtr)dev,
 				driver_data->options.btnmap,
@@ -903,6 +938,10 @@ xf86libinput_init_tablet(InputInfoPtr pInfo)
 	case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH:
 		xf86libinput_init_tablet_airbrush(pInfo, tool);
 		break;
+	case LIBINPUT_TABLET_TOOL_TYPE_MOUSE:
+	case LIBINPUT_TABLET_TOOL_TYPE_LENS:
+		xf86libinput_init_tablet_mouse(pInfo, tool);
+		break;
 	default:
 		xf86IDrvMsg(pInfo, X_ERROR, "Tool type not supported yet\n");
 		break;
@@ -1318,6 +1357,12 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
 		valuator_mask_set_double(mask, 5, value);
 	}
 
+	if (libinput_tablet_tool_has_rotation(tool)) {
+		value = libinput_event_tablet_tool_get_rotation(event);
+		value *= TABLET_AXIS_MAX;
+		valuator_mask_set_double(mask, 3, value);
+	}
+
 	xf86PostMotionEventM(dev, Absolute, mask);
 }
 

commit 0c2bcd0358d1107bf61ac8ff6dcb156742eb1bc6
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Thu Dec 3 15:24:24 2015 +1000

    Add support for the airbrush tool axes
    
    Same axes as the pen, but axis number 6 is the wheel (which really is a
    slider)
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

diff --git a/src/xf86libinput.c b/src/xf86libinput.c
index 0797968..0b7dfaf 100644
--- a/src/xf86libinput.c
+++ b/src/xf86libinput.c
@@ -791,7 +791,7 @@ xf86libinput_init_touch(InputInfoPtr pInfo)
 
 }
 
-static void
+static int
 xf86libinput_init_tablet_pen_or_eraser(InputInfoPtr pInfo,
 				       struct libinput_tablet_tool *tool)
 {
@@ -817,6 +817,37 @@ xf86libinput_init_tablet_pen_or_eraser(InputInfoPtr pInfo,
 					   XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y),
 					   min, max, res * 1000, 0, res * 1000, Absolute);
 	}
+
+	return axis;
+}
+
+static void
+xf86libinput_init_tablet_airbrush(InputInfoPtr pInfo,
+				  struct libinput_tablet_tool *tool)
+{
+	DeviceIntPtr dev = pInfo->dev;
+	int min, max, res;
+	int axis;
+
+	/* first axes are shared */
+	axis = xf86libinput_init_tablet_pen_or_eraser(pInfo, tool);
+	if (axis < 5) {
+		xf86IDrvMsg(pInfo, X_ERROR, "Airbrush tool has missing pressure or tilt axes\n");
+		return;
+	}
+
+	if (!libinput_tablet_tool_has_slider(tool)) {
+		xf86IDrvMsg(pInfo, X_ERROR, "Airbrush tool is missing the slider axis\n");
+		return;
+	}
+
+	min = -TABLET_AXIS_MAX;
+	max = TABLET_AXIS_MAX;
+	res = 0;
+
+	xf86InitValuatorAxisStruct(dev, axis,
+				   XIGetKnownProperty(AXIS_LABEL_PROP_ABS_THROTTLE),
+				   min, max, res * 1000, 0, res * 1000, Absolute);
 }
 
 static void
@@ -842,6 +873,8 @@ xf86libinput_init_tablet(InputInfoPtr pInfo)
 		naxes++;
 	if (libinput_tablet_tool_has_tilt(tool))
 		naxes += 2;
+	if (libinput_tablet_tool_has_slider(tool))
+		naxes++;
 
 	InitPointerDeviceStruct((DevicePtr)dev,
 				driver_data->options.btnmap,
@@ -867,6 +900,9 @@ xf86libinput_init_tablet(InputInfoPtr pInfo)
 	case LIBINPUT_TABLET_TOOL_TYPE_ERASER:
 		xf86libinput_init_tablet_pen_or_eraser(pInfo, tool);
 		break;
+	case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH:
+		xf86libinput_init_tablet_airbrush(pInfo, tool);
+		break;
 	default:
 		xf86IDrvMsg(pInfo, X_ERROR, "Tool type not supported yet\n");
 		break;
@@ -1276,6 +1312,12 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
 		valuator_mask_set_double(mask, 4, value);
 	}
 
+	if (libinput_tablet_tool_has_slider(tool)) {
+		value = libinput_event_tablet_tool_get_slider_position(event);
+		value *= TABLET_AXIS_MAX;
+		valuator_mask_set_double(mask, 5, value);
+	}
+
 	xf86PostMotionEventM(dev, Absolute, mask);
 }
 

commit b4541e4dff7248f1ce8894d8f950122785353d5b
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Thu Nov 12 11:50:47 2015 +1000

    Add support for tablet tools
    
    Use two new internal capabilities, CAP_TABLET and CAP_TABLET_TOOL. If a
    libinput tablet device is added, add an X device without any classes. This
    device will not send events, but once we have pad support in libinput we
    may be able to this the pad device.
    
    When a tool comes into proximity, create a new X device for that serial number
    and start sending events through it. Since the X device only represents a
    single serial number/type combination, some of the wacom-specific
    configuration options fall away. This only matters in the case of multiple
    tools, in which case a per-tool configuration is preferable anyway, so we
    don't lose anything here.
    
    Gesture support only applied to the touch parts on the device, we don't
    deal with this here specifically - that event node is handled by libinput as
    touchscreen or touchpad.
    
    This already works with GIMP and clients that don't rely on any
    wacom-driver-specific properties. Configuration clients like
    gnome-settings-daemon will need to change to handle new properties, to be
    added as we go along.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

diff --git a/src/xf86libinput.c b/src/xf86libinput.c
index 32bc9f8..0797968 100644
--- a/src/xf86libinput.c
+++ b/src/xf86libinput.c
@@ -55,6 +55,7 @@
 #endif
 
 #define TOUCHPAD_NUM_AXES 4 /* x, y, hscroll, vscroll */
+#define TABLET_NUM_BUTTONS 7 /* we need scroll buttons */
 #define TOUCH_MAX_SLOTS 15
 #define XORG_KEYCODE_OFFSET 8
 
@@ -65,10 +66,15 @@
    do the scaling it usually does.
  */
 #define TOUCH_AXIS_MAX 0xffff
+#define TABLET_AXIS_MAX 0xffffff
+#define TABLET_PRESSURE_AXIS_MAX 2047
+#define TABLET_TILT_AXIS_MAX 64
 
 #define CAP_KEYBOARD	0x1
 #define CAP_POINTER	0x2
 #define CAP_TOUCH	0x4
+#define CAP_TABLET	0x8
+#define CAP_TABLET_TOOL	0x10
 
 struct xf86libinput_driver {
 	struct libinput *libinput;
@@ -84,6 +90,13 @@ struct xf86libinput_device {
 	struct libinput_device *device;
 	struct xorg_list device_list;
 	int server_fd;
+
+	struct xorg_list unclaimed_tablet_tool_list;
+};
+
+struct xf86libinput_tablet_tool {
+	struct xorg_list node;
+	struct libinput_tablet_tool *tool;
 };
 
 struct xf86libinput {
@@ -135,6 +148,8 @@ struct xf86libinput {
 
 	struct xf86libinput_device *shared_device;
 	struct xorg_list shared_device_link;
+
+	struct libinput_tablet_tool *tablet_tool;
 };
 
 enum hotplug_when {
@@ -142,6 +157,12 @@ enum hotplug_when {
 	HOTPLUG_NOW,
 };
 
+static DeviceIntPtr
+xf86libinput_create_subdevice(InputInfoPtr pInfo,
+			      uint32_t capabilities,
+			      enum hotplug_when,
+			      XF86OptionPtr extra_opts);
+
 static inline int
 use_server_fd(const InputInfoPtr pInfo) {
 	return pInfo->fd > -1 && (pInfo->flags & XI86_SERVER_FD);
@@ -157,6 +178,9 @@ btn_linux2xorg(unsigned int b)
 	case BTN_LEFT: button = 1; break;
 	case BTN_MIDDLE: button = 2; break;
 	case BTN_RIGHT: button = 3; break;
+	/* tablet button range */
+	case BTN_STYLUS: button = 2; break;
+	case BTN_STYLUS2: button = 3; break;
 	default:
 		button = 8 + b - BTN_SIDE;
 		break;
@@ -217,6 +241,7 @@ xf86libinput_shared_create(struct libinput_device *device)
 	shared_device->refcount = 1;
 	shared_device->id = ++next_shared_device_id;
 	xorg_list_init(&shared_device->device_list);
+	xorg_list_init(&shared_device->unclaimed_tablet_tool_list);
 
 	return shared_device;
 }
@@ -766,6 +791,90 @@ xf86libinput_init_touch(InputInfoPtr pInfo)
 
 }
 
+static void
+xf86libinput_init_tablet_pen_or_eraser(InputInfoPtr pInfo,
+				       struct libinput_tablet_tool *tool)
+{
+	DeviceIntPtr dev = pInfo->dev;
+	int min, max, res;
+	int axis;
+
+	min = 0;
+	max = TABLET_PRESSURE_AXIS_MAX;
+	res = 0;
+	axis = 2;
+	if (libinput_tablet_tool_has_pressure(tool))
+		xf86InitValuatorAxisStruct(dev, axis++,
+					   XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE),
+					   min, max, res * 1000, 0, res * 1000, Absolute);
+	max = TABLET_TILT_AXIS_MAX;
+	min = -TABLET_TILT_AXIS_MAX;
+	if (libinput_tablet_tool_has_tilt(tool)) {
+		xf86InitValuatorAxisStruct(dev, axis++,
+					   XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X),
+					   min, max, res * 1000, 0, res * 1000, Absolute);
+		xf86InitValuatorAxisStruct(dev, axis++,
+					   XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y),
+					   min, max, res * 1000, 0, res * 1000, Absolute);
+	}
+}
+
+static void
+xf86libinput_init_tablet(InputInfoPtr pInfo)
+{
+	DeviceIntPtr dev = pInfo->dev;
+	struct xf86libinput *driver_data = pInfo->private;
+	struct libinput_tablet_tool *tool;
+	int min, max, res;
+	unsigned char btnmap[TABLET_NUM_BUTTONS];
+	Atom btnlabels[TABLET_NUM_BUTTONS] = {0};
+	Atom axislabels[TOUCHPAD_NUM_AXES] = {0};
+	int nbuttons = TABLET_NUM_BUTTONS;
+	int naxes = 2;
+
+	BUG_RETURN(driver_data->tablet_tool == NULL);
+
+	tool = driver_data->tablet_tool;
+
+	init_button_map(btnmap, ARRAY_SIZE(btnmap));
+
+	if (libinput_tablet_tool_has_pressure(tool))
+		naxes++;
+	if (libinput_tablet_tool_has_tilt(tool))
+		naxes += 2;
+
+	InitPointerDeviceStruct((DevicePtr)dev,
+				driver_data->options.btnmap,
+				nbuttons,
+				btnlabels,
+				xf86libinput_ptr_ctl,
+				GetMotionHistorySize(),
+				naxes,
+				axislabels);
+
+	min = 0;
+	max = TABLET_AXIS_MAX;
+	res = 0;
+	xf86InitValuatorAxisStruct(dev, 0,
+			           XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X),
+				   min, max, res * 1000, 0, res * 1000, Absolute);
+	xf86InitValuatorAxisStruct(dev, 1,
+			           XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y),
+				   min, max, res * 1000, 0, res * 1000, Absolute);
+
+	switch (libinput_tablet_tool_get_type(tool)) {
+	case LIBINPUT_TABLET_TOOL_TYPE_PEN:
+	case LIBINPUT_TABLET_TOOL_TYPE_ERASER:
+		xf86libinput_init_tablet_pen_or_eraser(pInfo, tool);
+		break;
+	default:
+		xf86IDrvMsg(pInfo, X_ERROR, "Tool type not supported yet\n");
+		break;
+	}
+
+	InitProximityClassDeviceStruct(dev);
+}
+
 static int
 xf86libinput_init(DeviceIntPtr dev)
 {
@@ -789,6 +898,8 @@ xf86libinput_init(DeviceIntPtr dev)
 	}
 	if (driver_data->capabilities & CAP_TOUCH)
 		xf86libinput_init_touch(pInfo);
+	if (driver_data->capabilities & CAP_TABLET_TOOL)
+		xf86libinput_init_tablet(pInfo);
 
 	LibinputApplyConfig(dev);
 	LibinputInitProperty(dev);
@@ -815,6 +926,9 @@ xf86libinput_destroy(DeviceIntPtr dev)
 
 	xorg_list_del(&driver_data->shared_device_link);
 
+	if (driver_data->tablet_tool)
+		libinput_tablet_tool_unref(driver_data->tablet_tool);
+
 	xf86libinput_shared_unref(shared_device);
 }
 
@@ -1047,10 +1161,11 @@ xf86libinput_handle_touch(InputInfoPtr pInfo,
 
 static InputInfoPtr
 xf86libinput_pick_device(struct xf86libinput_device *shared_device,
-			 enum libinput_event_type type)
+			 struct libinput_event *event)
 {
 	struct xf86libinput *driver_data;
 	uint32_t needed_cap;
+	enum libinput_event_type type = libinput_event_get_type(event);
 
 	if (shared_device == NULL)
 		return NULL;
@@ -1059,6 +1174,14 @@ xf86libinput_pick_device(struct xf86libinput_device *shared_device,
 	case LIBINPUT_EVENT_KEYBOARD_KEY:
 		needed_cap = CAP_KEYBOARD;
 		break;
+	case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
+		needed_cap = CAP_TABLET;
+		break;
+	case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
+	case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
+	case LIBINPUT_EVENT_TABLET_TOOL_TIP:
+		needed_cap = CAP_TABLET_TOOL;
+		break;
 	default:
 		needed_cap = ~CAP_KEYBOARD;
 		break;
@@ -1067,14 +1190,180 @@ xf86libinput_pick_device(struct xf86libinput_device *shared_device,
 	xorg_list_for_each_entry(driver_data,
 				 &shared_device->device_list,
 				 shared_device_link) {
-		if (driver_data->capabilities & needed_cap)
-			return driver_data->pInfo;
+		if (driver_data->capabilities & needed_cap) {
+			struct libinput_tablet_tool *tool;
+
+			if (needed_cap != CAP_TABLET_TOOL)
+				return driver_data->pInfo;
+
+			tool = libinput_event_tablet_tool_get_tool(
+					   libinput_event_get_tablet_tool_event(event));
+			if (libinput_tablet_tool_get_serial(driver_data->tablet_tool) ==
+			    libinput_tablet_tool_get_serial(tool) &&
+			    libinput_tablet_tool_get_tool_id(driver_data->tablet_tool) ==
+			    libinput_tablet_tool_get_tool_id(tool))
+				return driver_data->pInfo;
+		}
 	}
 
 	return NULL;
 }
 
 static void
+xf86libinput_handle_tablet_tip(InputInfoPtr pInfo,
+			       struct libinput_event_tablet_tool *event)
+{
+	enum libinput_tablet_tool_tip_state state;
+	const BOOL is_absolute = TRUE;
+
+	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);
+}
+
+static void
+xf86libinput_handle_tablet_button(InputInfoPtr pInfo,
+				  struct libinput_event_tablet_tool *event)
+{
+	enum libinput_button_state state;
+	uint32_t button, b;
+
+	button = libinput_event_tablet_tool_get_button(event);
+	state = libinput_event_tablet_tool_get_button_state(event);
+
+	b = btn_linux2xorg(button);
+
+	xf86PostButtonEventP(pInfo->dev,
+			     TRUE,
+			     b,
+			     state == LIBINPUT_BUTTON_STATE_PRESSED ? 1 : 0,
+			     0, 0, NULL);
+}
+
+static void
+xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
+				struct libinput_event_tablet_tool *event)
+{
+	DeviceIntPtr dev = pInfo->dev;
+	struct xf86libinput *driver_data = pInfo->private;
+	ValuatorMask *mask = driver_data->valuators;
+	struct libinput_tablet_tool *tool;
+	double value;
+
+	value = libinput_event_tablet_tool_get_x_transformed(event,
+							TABLET_AXIS_MAX);
+	valuator_mask_set_double(mask, 0, value);
+	value = libinput_event_tablet_tool_get_y_transformed(event,
+							TABLET_AXIS_MAX);
+	valuator_mask_set_double(mask, 1, value);
+
+	tool = libinput_event_tablet_tool_get_tool(event);
+
+	if (libinput_tablet_tool_has_pressure(tool)) {
+		value = libinput_event_tablet_tool_get_pressure(event);
+		value *= TABLET_PRESSURE_AXIS_MAX;
+		valuator_mask_set_double(mask, 2, value);
+	}
+
+	if (libinput_tablet_tool_has_tilt(tool)) {
+		value = libinput_event_tablet_tool_get_tilt_x(event);
+		valuator_mask_set_double(mask, 3, value);
+
+		value = libinput_event_tablet_tool_get_tilt_y(event);
+		valuator_mask_set_double(mask, 4, value);
+	}
+
+	xf86PostMotionEventM(dev, Absolute, mask);
+}
+
+static inline const char *
+tool_type_to_str(enum libinput_tablet_tool_type type)
+{
+	const char *str;
+
+	switch (type) {
+	case LIBINPUT_TABLET_TOOL_TYPE_PEN: str = "Pen"; break;
+	case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: str = "Brush"; break;
+	case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: str = "Pencil"; break;
+	case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: str = "Airbrush"; break;
+	case LIBINPUT_TABLET_TOOL_TYPE_ERASER: str = "Eraser"; break;
+	case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: str = "Mouse"; break;
+	case LIBINPUT_TABLET_TOOL_TYPE_LENS: str = "Lens"; break;
+	default:
+		str = "unknown tool";
+		break;
+	}
+
+	return str;
+}
+
+static void
+xf86libinput_handle_tablet_proximity(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;
+	uint64_t serial, tool_id;
+	XF86OptionPtr options = NULL;
+	DeviceIntPtr pDev = pInfo->dev;
+	char name[64];
+	ValuatorMask *mask = driver_data->valuators;
+	double x, y;
+
+	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);
+
+	if (libinput_event_tablet_tool_get_proximity_state(event) ==
+	    LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT) {
+		xf86PostProximityEventM(pDev, FALSE, mask);
+		return;
+	}
+
+	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)
+			return;
+	}
+
+	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);
+
+	options = xf86ReplaceIntOption(options, "_libinput/tablet-tool-serial", serial);
+	options = xf86ReplaceIntOption(options, "_libinput/tablet-tool-id", tool_id);
+	/* Convert the name to "<base name> <tool type> (serial number)" */
+	if (snprintf(name,
+		     sizeof(name),
+		     "%s %s (%#x)",
+		     pInfo->name,
+		     tool_type_to_str(libinput_tablet_tool_get_type(tool)),
+		     (uint32_t)serial) > strlen(pInfo->name))
+		options = xf86ReplaceStrOption(options, "Name", name);
+
+	pDev = xf86libinput_create_subdevice(pInfo, CAP_TABLET_TOOL, HOTPLUG_NOW, options);
+
+	xf86PostProximityEventM(pDev, TRUE, mask);
+}
+
+static void
 xf86libinput_handle_event(struct libinput_event *event)
 {
 	struct libinput_device *device;
@@ -1083,7 +1372,8 @@ xf86libinput_handle_event(struct libinput_event *event)
 
 	type = libinput_event_get_type(event);
 	device = libinput_event_get_device(event);
-	pInfo = xf86libinput_pick_device(libinput_device_get_user_data(device), type);
+	pInfo = xf86libinput_pick_device(libinput_device_get_user_data(device),
+					 event);
 
 	if (!pInfo || !pInfo->dev->public.on)
 		return;
@@ -1132,9 +1422,20 @@ 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,
+							libinput_event_get_tablet_tool_event(event));
+			break;
 		case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
+			xf86libinput_handle_tablet_button(pInfo,
+							  libinput_event_get_tablet_tool_event(event));
+			break;
 		case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
+			xf86libinput_handle_tablet_proximity(pInfo,
+							     libinput_event_get_tablet_tool_event(event));
+			break;
 		case LIBINPUT_EVENT_TABLET_TOOL_TIP:
+			xf86libinput_handle_tablet_tip(pInfo,
+						       libinput_event_get_tablet_tool_event(event));
 			break;
 	}
 }
@@ -1757,7 +2058,28 @@ xf86libinput_get_type_name(struct libinput_device *device,
 		type_name = XI_TOUCHSCREEN;
 	else if (driver_data->capabilities & CAP_POINTER)
 		type_name = XI_MOUSE;
-	else
+	else if (driver_data->capabilities & CAP_TABLET)
+		type_name = XI_TABLET;
+	else if (driver_data->capabilities & CAP_TABLET_TOOL){
+		switch (libinput_tablet_tool_get_type(driver_data->tablet_tool)) {
+		case LIBINPUT_TABLET_TOOL_TYPE_PEN:
+		case LIBINPUT_TABLET_TOOL_TYPE_BRUSH:
+		case LIBINPUT_TABLET_TOOL_TYPE_PENCIL:
+		case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH:
+			type_name = "STYLUS";
+			break;
+		case LIBINPUT_TABLET_TOOL_TYPE_ERASER:
+			type_name = "ERASER";
+			break;
+		case LIBINPUT_TABLET_TOOL_TYPE_MOUSE:
+		case LIBINPUT_TABLET_TOOL_TYPE_LENS:
+			type_name = "CURSOR";
+			break;
+		default:
+			type_name = XI_TABLET;
+			break;
+		}
+	} else
 		type_name = XI_KEYBOARD;
 
 	return type_name;
@@ -1837,6 +2159,8 @@ xf86libinput_create_subdevice(InputInfoPtr pInfo,
 		options = xf86ReplaceBoolOption(options, "_libinput/cap-pointer", 1);
 	if (capabilities & CAP_TOUCH)
 		options = xf86ReplaceBoolOption(options, "_libinput/cap-touch", 1);
+	if (capabilities & CAP_TABLET_TOOL)
+		options = xf86ReplaceBoolOption(options, "_libinput/cap-tablet-tool", 1);
 
 	/* need convert from one option list to the other. woohoo. */
 	o = options;
@@ -1888,10 +2212,38 @@ caps_from_options(InputInfoPtr pInfo)
 		capabilities |= CAP_POINTER;
 	if (xf86CheckBoolOption(pInfo->options, "_libinput/cap-touch", 0))
 		capabilities |= CAP_TOUCH;
+	if (xf86CheckBoolOption(pInfo->options, "_libinput/cap-tablet-tool", 0))
+		capabilities |= CAP_TABLET_TOOL;
 
 	return capabilities;
 }
 
+static inline Bool
+claim_tablet_tool(InputInfoPtr pInfo)
+{
+	struct xf86libinput *driver_data = pInfo->private;
+	struct xf86libinput_device *shared_device = driver_data->shared_device;
+	struct xf86libinput_tablet_tool *t;
+	uint64_t serial, tool_id;
+
+	serial = (uint32_t)xf86CheckIntOption(pInfo->options, "_libinput/tablet-tool-serial", 0);
+	tool_id = (uint32_t)xf86CheckIntOption(pInfo->options, "_libinput/tablet-tool-id", 0);
+
+	xorg_list_for_each_entry(t,
+				 &shared_device->unclaimed_tablet_tool_list,
+				 node) {
+		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;
+			xorg_list_del(&t->node);
+			free(t);
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
 static int
 xf86libinput_pre_init(InputDriverPtr drv,
 		      InputInfoPtr pInfo,
@@ -1914,7 +2266,7 @@ xf86libinput_pre_init(InputDriverPtr drv,
 	if (!driver_data)
 		goto fail;
 
-	driver_data->valuators = valuator_mask_new(2);
+	driver_data->valuators = valuator_mask_new(6);
 	if (!driver_data->valuators)
 		goto fail;
 
@@ -1985,8 +2337,14 @@ xf86libinput_pre_init(InputDriverPtr drv,
 			driver_data->capabilities |= CAP_KEYBOARD;
 		if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH))
 			driver_data->capabilities |= CAP_TOUCH;
+		if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_TOOL))
+			driver_data->capabilities |= CAP_TABLET;
 	} else {
+
 		driver_data->capabilities = caps_from_options(pInfo);
+
+		if (driver_data->capabilities & CAP_TABLET_TOOL)
+			claim_tablet_tool(pInfo);
 	}
 
 	/* Disable acceleration in the server, libinput does it for us */


Reply to: