Rebased ref, commits from common ancestor: commit 6460e4fe5f9f640060f1e2ed7b3a0a47a7bf8e68 Author: Andreas Boll <andreas.boll....@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 <tjaal...@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 <tjaal...@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 <tjaal...@debian.org> Fri, 11 Mar 2016 20:58:50 +0200 + -- Timo Aaltonen <tjaal...@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 <tjaal...@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 <tjaal...@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 <tjaal...@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.hutte...@who-t.net> Date: Thu Apr 7 13:31:28 2016 +1000 xf86-input-libinput 0.18.0 Signed-off-by: Peter Hutterer <peter.hutte...@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 <tjaal...@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 <tjaal...@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 <tjaal...@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.hutte...@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.hutte...@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.hutte...@who-t.net> Date: Thu Dec 3 15:41:30 2015 +1000 Support the mouse/lens tool Signed-off-by: Peter Hutterer <peter.hutte...@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.hutte...@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.hutte...@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.hutte...@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.hutte...@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 */