Hello community,

here is the log from the commit of package xf86-input-libinput for 
openSUSE:Factory checked in at 2016-04-11 09:13:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/xf86-input-libinput (Old)
 and      /work/SRC/openSUSE:Factory/.xf86-input-libinput.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "xf86-input-libinput"

Changes:
--------
--- /work/SRC/openSUSE:Factory/xf86-input-libinput/xf86-input-libinput.changes  
2016-03-02 14:18:58.000000000 +0100
+++ 
/work/SRC/openSUSE:Factory/.xf86-input-libinput.new/xf86-input-libinput.changes 
    2016-04-11 09:13:28.000000000 +0200
@@ -1,0 +2,22 @@
+Thu Apr  7 15:29:09 UTC 2016 - [email protected]
+
+- Update to version 0.18.0:
+This release adds support for tablet tool devices. Now, this support should
+be taken with a grain of salt, it works differently to the xf86-input-wacom
+driver and thus some capability differences can be observed:
+First, pad support is still missing, i.e. you cannot use the buttons on the
+tablet bit itself.
+
+There are no specific configuration options just yet, and the way we are
+aiming for libinput support, many of the options you are used to may not
+exist ever.
+
+The most important part: tool support is handled dynamically. As a tool is
+first brought into proximity, a new X device is created for that tool only
+(no multiplexing of tools through the same X device). Clients may expect a
+static list of tools, so for those you will need to bring the tool into
+proximity before starting the client.
+
+In short, do not use this driver for tablets on production workstations yet.
+
+-------------------------------------------------------------------

Old:
----
  xf86-input-libinput-0.17.0.tar.bz2
  xf86-input-libinput-0.17.0.tar.bz2.sig

New:
----
  xf86-input-libinput-0.18.0.tar.bz2
  xf86-input-libinput-0.18.0.tar.bz2.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ xf86-input-libinput.spec ++++++
--- /var/tmp/diff_new_pack.siU3YO/_old  2016-04-11 09:13:29.000000000 +0200
+++ /var/tmp/diff_new_pack.siU3YO/_new  2016-04-11 09:13:29.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           xf86-input-libinput
-Version:        0.17.0
+Version:        0.18.0
 Release:        0
 Summary:        Libinput driver for the Xorg X server
 License:        MIT

++++++ xf86-input-libinput-0.17.0.tar.bz2 -> xf86-input-libinput-0.18.0.tar.bz2 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xf86-input-libinput-0.17.0/ChangeLog 
new/xf86-input-libinput-0.18.0/ChangeLog
--- old/xf86-input-libinput-0.17.0/ChangeLog    2016-02-26 07:00:58.000000000 
+0100
+++ new/xf86-input-libinput-0.18.0/ChangeLog    2016-04-07 05:32:45.000000000 
+0200
@@ -1,3 +1,69 @@
+commit 13726f404f872b8baee507e6b3d4931f1bda2254
+Author: Peter Hutterer <[email protected]>
+Date:   Thu Apr 7 13:31:28 2016 +1000
+
+    xf86-input-libinput 0.18.0
+    
+    Signed-off-by: Peter Hutterer <[email protected]>
+
+commit 5e7ee73fe24d53cba6a915223be53e0abcdaa70d
+Author: Peter Hutterer <[email protected]>
+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 <[email protected]>
+
+commit 4564a92d59be39378170a2254ae1affb151a4757
+Author: Peter Hutterer <[email protected]>
+Date:   Thu Dec 3 15:41:30 2015 +1000
+
+    Support the mouse/lens tool
+    
+    Signed-off-by: Peter Hutterer <[email protected]>
+
+commit 0c2bcd0358d1107bf61ac8ff6dcb156742eb1bc6
+Author: Peter Hutterer <[email protected]>
+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 <[email protected]>
+
+commit b4541e4dff7248f1ce8894d8f950122785353d5b
+Author: Peter Hutterer <[email protected]>
+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 <[email protected]>
+
 commit 8136113139dd2a27fcfa4552da89aa110bc8fbe3
 Author: Peter Hutterer <[email protected]>
 Date:   Fri Feb 26 15:57:48 2016 +1000
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xf86-input-libinput-0.17.0/configure 
new/xf86-input-libinput-0.18.0/configure
--- old/xf86-input-libinput-0.17.0/configure    2016-02-26 06:59:03.000000000 
+0100
+++ new/xf86-input-libinput-0.18.0/configure    2016-04-07 05:32:15.000000000 
+0200
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for xf86-input-libinput 0.17.0.
+# Generated by GNU Autoconf 2.69 for xf86-input-libinput 0.18.0.
 #
 # Report bugs to <https://bugs.freedesktop.org/enter_bug.cgi?product=xorg>.
 #
@@ -591,8 +591,8 @@
 # Identity of this package.
 PACKAGE_NAME='xf86-input-libinput'
 PACKAGE_TARNAME='xf86-input-libinput'
-PACKAGE_VERSION='0.17.0'
-PACKAGE_STRING='xf86-input-libinput 0.17.0'
+PACKAGE_VERSION='0.18.0'
+PACKAGE_STRING='xf86-input-libinput 0.18.0'
 PACKAGE_BUGREPORT='https://bugs.freedesktop.org/enter_bug.cgi?product=xorg'
 PACKAGE_URL=''
 
@@ -1356,7 +1356,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures xf86-input-libinput 0.17.0 to adapt to many kinds of 
systems.
+\`configure' configures xf86-input-libinput 0.18.0 to adapt to many kinds of 
systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1427,7 +1427,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of xf86-input-libinput 0.17.0:";;
+     short | recursive ) echo "Configuration of xf86-input-libinput 0.18.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1561,7 +1561,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-xf86-input-libinput configure 0.17.0
+xf86-input-libinput configure 0.18.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1885,7 +1885,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by xf86-input-libinput $as_me 0.17.0, which was
+It was created by xf86-input-libinput $as_me 0.18.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2753,7 +2753,7 @@
 
 # Define the identity of the package.
  PACKAGE='xf86-input-libinput'
- VERSION='0.17.0'
+ VERSION='0.18.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -19030,7 +19030,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by xf86-input-libinput $as_me 0.17.0, which was
+This file was extended by xf86-input-libinput $as_me 0.18.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -19096,7 +19096,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; 
s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-xf86-input-libinput config.status 0.17.0
+xf86-input-libinput config.status 0.18.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xf86-input-libinput-0.17.0/configure.ac 
new/xf86-input-libinput-0.18.0/configure.ac
--- old/xf86-input-libinput-0.17.0/configure.ac 2016-02-26 06:57:25.000000000 
+0100
+++ new/xf86-input-libinput-0.18.0/configure.ac 2016-04-07 05:31:17.000000000 
+0200
@@ -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])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xf86-input-libinput-0.17.0/src/xf86libinput.c 
new/xf86-input-libinput-0.18.0/src/xf86libinput.c
--- old/xf86-input-libinput-0.17.0/src/xf86libinput.c   2016-02-26 
06:56:57.000000000 +0100
+++ new/xf86-input-libinput-0.18.0/src/xf86libinput.c   2016-02-29 
05:34:43.000000000 +0100
@@ -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 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_device *shared_device;
        struct xorg_list shared_device_link;
+
+       struct libinput_tablet_tool *tablet_tool;
 };
 
 enum hotplug_when {
@@ -142,6 +157,12 @@
        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 @@
        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 @@
        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;
 }
@@ -767,6 +792,171 @@
 }
 
 static int
+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);
+       }
+
+       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;
+}
+
+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
+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;
+       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;
+       if (libinput_tablet_tool_has_slider(tool))
+               naxes++;
+       if (libinput_tablet_tool_has_rotation(tool))
+               naxes++;
+
+       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;
+       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;
+       }
+
+       InitProximityClassDeviceStruct(dev);
+}
+
+static int
 xf86libinput_init(DeviceIntPtr dev)
 {
        InputInfoPtr pInfo = dev->public.devicePrivate;
@@ -789,6 +979,8 @@
        }
        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 +1007,9 @@
 
        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 +1242,11 @@
 
 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 +1255,14 @@
        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 +1271,210 @@
        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);
+       }
+
+       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);
+       }
+
+       if (libinput_tablet_tool_has_rotation(tool)) {
+               int valuator;
+
+               value = libinput_event_tablet_tool_get_rotation(event);
+               value *= TABLET_AXIS_MAX;
+
+               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);
+}
+
+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 +1483,8 @@
 
        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 +1533,20 @@
                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 +2169,28 @@
                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 +2270,8 @@
                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 +2323,38 @@
                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 +2377,7 @@
        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 +2448,14 @@
                        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 via email to