Hello community,
here is the log from the commit of package xf86-input-libinput for
openSUSE:Factory checked in at 2017-02-26 17:01:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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-12-14 10:48:40.679541443 +0100
+++
/work/SRC/openSUSE:Factory/.xf86-input-libinput.new/xf86-input-libinput.changes
2017-02-26 17:01:15.816643477 +0100
@@ -1,0 +2,12 @@
+Mon Feb 20 21:37:53 UTC 2017 - [email protected]
+
+- Update to version 0.24.0:
+ + Tablets now support a configurable pressure curve.
+ + Tablets now have a 'area ratio' setting to be able to match the
+ tablet aspect ratio with that of the screen.
+ + The mouse wheel's click angle now (correctly) affects how fast
+ the scroll wheel triggers. In particular, if you have a wheel
+ with a very small click angle, it won't trigger for every click
+ anymore.
+
+-------------------------------------------------------------------
Old:
----
xf86-input-libinput-0.23.0.tar.bz2
xf86-input-libinput-0.23.0.tar.bz2.sig
New:
----
xf86-input-libinput-0.24.0.tar.bz2
xf86-input-libinput-0.24.0.tar.bz2.sig
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ xf86-input-libinput.spec ++++++
--- /var/tmp/diff_new_pack.tgzsF2/_old 2017-02-26 17:01:16.204584633 +0100
+++ /var/tmp/diff_new_pack.tgzsF2/_new 2017-02-26 17:01:16.204584633 +0100
@@ -1,7 +1,7 @@
#
# spec file for package xf86-input-libinput
#
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
Name: xf86-input-libinput
-Version: 0.23.0
+Version: 0.24.0
Release: 0
Summary: Libinput driver for the Xorg X server
License: MIT
++++++ xf86-input-libinput-0.23.0.tar.bz2 -> xf86-input-libinput-0.24.0.tar.bz2
++++++
++++ 1677 lines of diff (skipped)
++++ retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh
old/xf86-input-libinput-0.23.0/ChangeLog
new/xf86-input-libinput-0.24.0/ChangeLog
--- old/xf86-input-libinput-0.23.0/ChangeLog 2016-12-12 06:00:47.000000000
+0100
+++ new/xf86-input-libinput-0.24.0/ChangeLog 2017-02-09 07:17:09.000000000
+0100
@@ -1,3 +1,156 @@
+commit 2eb5a2f0c08747df44eba6faff95cc9ce24b78ed
+Author: Peter Hutterer <[email protected]>
+Date: Thu Feb 9 16:16:34 2017 +1000
+
+ xf86-input-libinput 0.24.0
+
+ Signed-off-by: Peter Hutterer <[email protected]>
+
+commit 19ceef972e76bc491438198659748786d9457668
+Author: Peter Hutterer <[email protected]>
+Date: Fri Jan 27 10:24:08 2017 +1000
+
+ Drop unnecessary function declaration
+
+ Signed-off-by: Peter Hutterer <[email protected]>
+
+commit 07f30ea049303739bf6006d23ac924971a19d778
+Author: Mihail Konev <[email protected]>
+Date: Thu Jan 26 14:00:21 2017 +1000
+
+ autogen: add default patch prefix
+
+ Signed-off-by: Mihail Konev <[email protected]>
+
+commit 6187ed0450e68aaf727779ad61b50b0b70a1122e
+Author: Emil Velikov <[email protected]>
+Date: Mon Mar 9 12:00:52 2015 +0000
+
+ autogen.sh: use quoted string variables
+
+ Place quotes around the $srcdir, $ORIGDIR and $0 variables to prevent
+ fall-outs, when they contain space.
+
+ Signed-off-by: Emil Velikov <[email protected]>
+ Reviewed-by: Peter Hutterer <[email protected]>
+ Signed-off-by: Peter Hutterer <[email protected]>
+
+commit 974ab6b62bd2af97e1556314df28fe9f3b816e54
+Author: Peter Hutterer <[email protected]>
+Date: Fri Oct 28 11:20:22 2016 +1000
+
+ Add tablet tool area ratio property
+
+ By default, the X server maps the tablet axes to the available screen area.
+ When a tablet is mapped to the screen but has a different aspect ratio than
+ the screen, input data is skewed. Expose an area ratio property to map the
+ a subsection of the available tablet area into the desired ratio.
+
+ Differences to the wacom driver: there the x/y min/max values must be
+ specified manually and in device coordinates. For this driver we merely
+ provide the area ratio (e.g. 4:3) and let the driver work out the rest.
+
+ Signed-off-by: Peter Hutterer <[email protected]>
+ Reviewed-by: Jason Gerecke <[email protected]>
+
+commit 5d0470738125243c98f7a8cc40d62f53604a8051
+Author: Peter Hutterer <[email protected]>
+Date: Mon Oct 24 14:41:51 2016 +1000
+
+ Implement stylus pressure curve support
+
+ Takes a 4-point cubic bezier curve as input and maps the pressure
coordinates
+ to the values outlined by this curve. This is an extension of the current
+ implementation in the xf86-input-wacom driver which only allows the two
center
+ control points to be modified.
+
+ Over the years a few users have noted that the wacom driver's pressure
curve
+ makes it impossible to cap the pressure at a given value. Given our bezier
+ implementation here, it's effectively a freebie to add configurability of
the
+ first and last control points. We do require all control points' x
coordinates
+ to be in ascending order.
+
+ Signed-off-by: Peter Hutterer <[email protected]>
+
+commit f65a5c50224efc34414f44c86700e15392b7039b
+Author: Peter Hutterer <[email protected]>
+Date: Wed Oct 26 11:57:49 2016 +1000
+
+ Add a bezier curve implementation
+
+ Needed for the wacom stylus pressure curve
+
+ Signed-off-by: Peter Hutterer <[email protected]>
+
+commit 0dad7408fac3b69c4b6ab7705f39f790d7ba20c2
+Author: Peter Hutterer <[email protected]>
+Date: Mon Nov 28 14:09:06 2016 +1000
+
+ Calculate the required scroll distance based on the angle
+
+ For a mouse with a click angle of 15 degrees things are unchanged. For
devices
+ with angles less than 10, the current code scrolled way too fast. Because
the
+ angle wasn't used anywhere, each tick would count as full scroll wheel
event,
+ a slight movement of the wheel would thus scroll as much as a large
movement
+ on a normal mouse.
+
+ Fix this by taking the actual click angle of the device into account. We
+ calculate some multiple of the angle that's close enough to the default 15
+ degrees of the wheel and then require that many click events to hit the
full
+ scroll distance. For example, a mouse with a click angle of 3 degrees now
+ requires 5 clicks to trigger a full legacy scroll button event.
+
+ XI2.1 clients get the intermediate events (i.e. in this case five times
+ one-fifth of the scroll distance) and can thus scroll smoothly, or more
+ specifically in smaller events than usual.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=92772
+
+ Signed-off-by: Peter Hutterer <[email protected]>
+ Reviewed-by: Hans de Goede <[email protected]>
+
+commit ea02578a4e888d9908eb6bed6dcb858f78acb8bb
+Author: Peter Hutterer <[email protected]>
+Date: Tue Nov 29 08:31:32 2016 +1000
+
+ Move axis value calculation into a helper function
+
+ The only difference here is the axis number.
+
+ Signed-off-by: Peter Hutterer <[email protected]>
+ Reviewed-by: Hans de Goede <[email protected]>
+
+commit 2ceb2e1b18b6f971706230d16a2a5665d87aabd4
+Author: Peter Hutterer <[email protected]>
+Date: Tue Nov 29 09:21:24 2016 +1000
+
+ Add a comment regarding scroll dist default values
+
+ Changed this during development because I forgot that the value actually
+ matters (for touchpads anyway).
+
+ Signed-off-by: Peter Hutterer <[email protected]>
+ Reviewed-by: Hans de Goede <[email protected]>
+
+commit f47f78eb0bd9fba455f01c8c6dead3bd75242b2b
+Author: Peter Hutterer <[email protected]>
+Date: Tue Dec 20 15:36:55 2016 +1000
+
+ Ignore LED updates for disabled devices
+
+ If an XKB AccessX timeout is set and a VT switch is triggered, the
+ AccessXTimeoutExpire function may be called after the device has already
been
+ disabled. This can cause a null-pointer dereference as our shared libinput
+ device may have been released by then.
+
+ In the legacy drivers this would've simply caused a write to an invalid fd
+ (-1), not a crash. Here we need to be more careful.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=98464
+
+ Signed-off-by: Peter Hutterer <[email protected]>
+ Reviewed-by: Hans de Goede <[email protected]>
+
commit 1c3ce3ce3c315213511735db1b0fdd74ca8442d0
Author: Peter Hutterer <[email protected]>
Date: Mon Dec 12 14:54:00 2016 +1000
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh
old/xf86-input-libinput-0.23.0/configure.ac
new/xf86-input-libinput-0.24.0/configure.ac
--- old/xf86-input-libinput-0.23.0/configure.ac 2016-12-12 05:53:55.000000000
+0100
+++ new/xf86-input-libinput-0.24.0/configure.ac 2017-02-09 07:17:00.000000000
+0100
@@ -23,7 +23,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-input-libinput],
- [0.23.0],
+ [0.24.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' --exclude Makefile.in --exclude configure --exclude
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh
old/xf86-input-libinput-0.23.0/include/libinput-properties.h
new/xf86-input-libinput-0.24.0/include/libinput-properties.h
--- old/xf86-input-libinput-0.23.0/include/libinput-properties.h
2016-11-28 04:25:03.000000000 +0100
+++ new/xf86-input-libinput-0.24.0/include/libinput-properties.h
2017-02-09 07:17:00.000000000 +0100
@@ -183,4 +183,14 @@
/* Device rotation: FLOAT, 1 value, 32 bit, read-only */
#define LIBINPUT_PROP_ROTATION_ANGLE_DEFAULT "libinput Rotation Angle Default"
+/* Tablet tool pressure curve: float, 8 values, 32 bit
+ * Value range is [0.0, 1.0], the values specify the x/y of the four
+ * control points for a cubic bezier curve.
+ * Default value: 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
+ */
+#define LIBINPUT_PROP_TABLET_TOOL_PRESSURECURVE "libinput Tablet Tool
Pressurecurve"
+
+/* Tablet tool area ratio: CARD32, 2 values, w and h */
+#define LIBINPUT_PROP_TABLET_TOOL_AREA_RATIO "libinput Tablet Tool Area Ratio"
+
#endif /* _LIBINPUT_PROPERTIES_H_ */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh
old/xf86-input-libinput-0.23.0/man/libinput.man
new/xf86-input-libinput-0.24.0/man/libinput.man
--- old/xf86-input-libinput-0.23.0/man/libinput.man 2016-11-28
04:25:03.000000000 +0100
+++ new/xf86-input-libinput-0.24.0/man/libinput.man 2017-02-09
07:17:00.000000000 +0100
@@ -155,6 +155,20 @@
Sets the send events mode to disabled, enabled, or "disable when an external
mouse is connected".
.TP 7
+.BI "Option \*qTabletToolPressureCurve\*q \*q" "x0/y0 x1/y1 x2/y2 x3/y3" \*q
+Set the pressure curve for a tablet stylus to the bezier formed by the four
+points. The respective x/y coordinate must be in the [0.0, 1.0] range. For
+more information see section
+.B TABLET STYLUS PRESSURE CURVE.
+.TP 7
+.BI "Option \*qTabletToolAreaRatio\*q \*q" "w:h" \*q
+Sets the area ratio for a tablet tool. The area always starts at the
+origin (0/0) and expands to the largest available area with the specified
+aspect ratio. Events outside this area are cropped to the area. The special
+value "default" is used for the default mapping (i.e. the device-native
+mapping). For more information see section
+.B TABLET TOOL AREA RATIO.
+.TP 7
.BI "Option \*qTapping\*q \*q" bool \*q
Enables or disables tap-to-click behavior.
.TP 7
@@ -252,6 +266,16 @@
"disabled-on-external-mouse". Indicates which send-event modes is currently
enabled on this device.
.TP 7
+.BI "libinput Tablet Tool Pressurecurve"
+4 32-bit float values [0.0 to 1.0]. See section
+.B TABLET TOOL PRESSURE CURVE
+.TP7
+.BI "libinput Tablet Tool Area Ratio"
+2 32-bit values, corresponding to width and height. Special value 0, 0
+resets to the default ratio. See section
+.B TABLET TOOL AREA RATIO
+for more information.
+.TP 7
.BI "libinput Tapping Enabled"
1 boolean value (8 bit, 0 or 1). 1 enables tapping
.TP 7
@@ -313,6 +337,42 @@
.TP
This feature is provided by this driver, not by libinput.
+.SH TABLET TOOL PRESSURECURVE
+The pressure curve affects how stylus pressure is reported. By default, the
+hardware pressure is reported as-is. By setting a pressure curve, the feel
+of the stylus can be adjusted to be more like e.g. a pencil or a brush.
+.PP
+The pressure curve is a cubic Bezier curve, drawn within a normalized range
+of 0.0 to 1.0 between the four points provided. This normalized range is
+applied to the tablet's pressure input so that the highest pressure maps to
+1.0. The points must have increasing x coordinates, if x0 is larger than 0.0
+all pressure values lower than x0 are equivalent to y0. If x3 is less than
+1.0, all pressure values higher than x3 are equivalent to y3.
+
+The input for a linear curve (default) is "0.0/0.0 0.0/0.0 1.0/1.0 1.0/1.0";
+a slightly
+depressed curve (firmer) might be "0.0/0.0 0.05/0.0 1.0/0.95 1.0/1.0"; a
slightly raised
+curve (softer) might be "0.0/0.0 0.0/0.05 0.95/1.0 1.0/1.0".
+.TP
+This feature is provided by this driver, not by libinput.
+
+.SH TABLET TOOL AREA RATIO
+By default, a tablet tool can access the whole sensor area and the tablet
+area is mapped to the available screen area. For external tablets like
+the Wacom Intuos series, the height:width ratio of the tablet may be
+different to that of the monitor, causing the skew of input data.
+.PP
+To avoid this skew of input data, an area ratio may be set to match the
+ratio of the screen device. For example, a ratio of 4:3 will reduce the
+available area of the tablet to the largest available area with a ratio of
+4:3. Events within this area will scale to the tablet's announced axis
+range, the area ratio is thus transparent to the X server. Any events
+outside this area will send events equal to the maximum value of that axis.
+The area always starts at the device's origin in it's current rotation, i.e.
+it takes left-handed-ness into account.
+.TP
+This feature is provided by this driver, not by libinput.
+
.SH AUTHORS
Peter Hutterer
.SH "SEE ALSO"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh
old/xf86-input-libinput-0.23.0/src/Makefile.am
new/xf86-input-libinput-0.24.0/src/Makefile.am
--- old/xf86-input-libinput-0.23.0/src/Makefile.am 2016-11-14
04:27:06.000000000 +0100
+++ new/xf86-input-libinput-0.24.0/src/Makefile.am 2017-02-09
07:17:00.000000000 +0100
@@ -30,10 +30,11 @@
@DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
-@DRIVER_NAME@_drv_la_LIBADD = $(LIBINPUT_LIBS) libdraglock.la
+@DRIVER_NAME@_drv_la_LIBADD = $(LIBINPUT_LIBS) libdraglock.la libbezier.la -lm
@DRIVER_NAME@_drv_ladir = @inputdir@
@DRIVER_NAME@_drv_la_SOURCES = xf86libinput.c
-noinst_LTLIBRARIES = libdraglock.la
+noinst_LTLIBRARIES = libdraglock.la libbezier.la
libdraglock_la_SOURCES = draglock.c draglock.h
+libbezier_la_SOURCES = bezier.c bezier.h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh
old/xf86-input-libinput-0.23.0/src/bezier.c
new/xf86-input-libinput-0.24.0/src/bezier.c
--- old/xf86-input-libinput-0.23.0/src/bezier.c 1970-01-01 01:00:00.000000000
+0100
+++ new/xf86-input-libinput-0.24.0/src/bezier.c 2017-02-09 07:17:00.000000000
+0100
@@ -0,0 +1,177 @@
+/*
+ * Copyright © 2016 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission. Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+
+#include "bezier.h"
+
+const struct bezier_control_point bezier_defaults[4] = {
+ { 0.0, 0.0 },
+ { 0.0, 0.0 },
+ { 1.0, 1.0 },
+ { 1.0, 1.0 },
+};
+
+struct point {
+ int x, y;
+};
+
+/**
+ * de Casteljau's algorithm. See this page here
+ * https://pomax.github.io/bezierinfo/#extended
+ *
+ * To play with bezier curve shapes, I used
+ * http://cubic-bezier.com/
+ */
+static struct point
+decasteljau(const struct point *controls,
+ size_t ncontrols,
+ double t)
+{
+ struct point new_controls[ncontrols];
+
+ if (ncontrols == 1)
+ return controls[0];
+
+ for (int i = 0; i < ncontrols - 1; i++) {
+ new_controls[i].x = (1.0 - t) * controls[i].x + t * controls[i
+ 1].x;
+ new_controls[i].y = (1.0 - t) * controls[i].y + t * controls[i
+ 1].y;
+ }
+
+ return decasteljau(new_controls, ncontrols - 1, t);
+}
+
+/**
+ * Given a Bézier curve defined by the control points, reduce the curve to
+ * one with ncurve_points.
+ */
+static void
+flatten_curve(const struct point *controls,
+ size_t ncontrols,
+ struct point *curve,
+ size_t ncurve_points)
+{
+ ncurve_points--; /* make sure we end up with 100/100 as last point */
+
+ for (int i = 0; i <= ncurve_points; i++) {
+ double t = 1.0 * i/ncurve_points;
+ struct point p;
+
+ p = decasteljau(controls, ncontrols, t);
+ curve[i] = p;
+ }
+}
+
+/**
+ * Calculate line through a and b, set curve[x] for each x between
+ * [a.x, b.x].
+ *
+ * Note: pcurve must be at least b.x size.
+ */
+static void
+line_between(struct point a, struct point b,
+ struct point *curve, size_t curve_sz)
+{
+ double slope;
+ double offset;
+
+ assert(b.x < curve_sz);
+
+ if (a.x == b.x) {
+ curve[a.x].x = a.x;
+ curve[a.x].y = a.y;
+ return;
+ }
+
+ slope = (double)(b.y - a.y)/(b.x - a.x);
+ offset = a.y - slope * a.x;
+
+ for (int x = a.x; x <= b.x; x++) {
+ struct point p;
+ p.x = x;
+ p.y = slope * x + offset;
+ curve[x] = p;
+ }
+}
+
+bool
+cubic_bezier(const struct bezier_control_point controls[4],
+ int *bezier_out,
+ size_t bezier_sz)
+{
+ const int nsegments = 50;
+ const int range = bezier_sz - 1;
+ struct point curve[nsegments];
+ struct point bezier[bezier_sz];
+ struct point zero = { 0, 0 },
+ max = { range, range};
+
+ /* Scale control points into the [0, bezier_sz) range */
+ struct point ctrls[4];
+
+ for (int i = 0; i < 4; i++) {
+ if (controls[i].x < 0.0 || controls[i].x > 1.0 ||
+ controls[i].y < 0.0 || controls[i].y > 1.0)
+ return false;
+
+ ctrls[i].x = controls[i].x * range;
+ ctrls[i].y = controls[i].y * range;
+ }
+
+ for (int i = 0; i < 3; i++) {
+ if (ctrls[i].x > ctrls[i+1].x)
+ return false;
+ }
+
+ /* Reduce curve to nsegments, because this isn't a drawing program */
+ flatten_curve(ctrls, 4, curve, nsegments);
+
+ /* we now have nsegments points in curve that represent the bezier
+ curve (already in the [0, bezier_sz) range). Run through the
+ points and draw a straight line between each point and voila, we
+ have our curve.
+
+ If the first control points (x0/y0) is not at x == 0 or the last
+ control point (x3/y3) is not at the max value, draw a line
+ between from 0/0 to x0/y0 and from x3/y3 to xmax/y3.
+ */
+
+ line_between(zero, curve[0], bezier, bezier_sz);
+
+ for (int i = 0; i < nsegments - 1; i++)
+ line_between(curve[i], curve[i+1], bezier, bezier_sz);
+
+ if (curve[nsegments - 1].x < max.x)
+ line_between(curve[nsegments - 1], max, bezier, bezier_sz);
+
+ for (int i = 0; i < bezier_sz; i++)
+ bezier_out[i] = bezier[i].y;
+
+ return true;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh
old/xf86-input-libinput-0.23.0/src/bezier.h
new/xf86-input-libinput-0.24.0/src/bezier.h
--- old/xf86-input-libinput-0.23.0/src/bezier.h 1970-01-01 01:00:00.000000000
+0100
+++ new/xf86-input-libinput-0.24.0/src/bezier.h 2017-02-09 07:17:00.000000000
+0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2016 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission. Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef BEZIER_H
+#define BEZIER_H
+
+#include <stdlib.h>
+#include <stdbool.h>
+
+struct bezier_control_point {
+ double x, y;
+};
+
+extern const struct bezier_control_point bezier_defaults[4];
+
+/**
+ * Given four control points in the range [(0.0/0.0), (1.0/1.0)]
+ * construct a Bézier curve.
+ *
+ * ^
+ *1.0 | c2 ______ c3
+ * | _/
+ * | /
+ * |c1 /
+ * | /
+ * | /
+ * |/_________________>
+ * c0 1.0
+ *
+ * This function requires that c[i].x <= c[i+1].x
+ *
+ * The curve is mapped into a canvas size [0, bezier_sz)². For each x
+ * coordiante in [0, bezier_sz), the matching y coordinate is thus
+ * bezier[x].
+ *
+ * In other words, if you have a range [0,2048) input possible values,
+ * the output is a list of 2048 points in a [0, 2048) range.
+ *
+ * @return true on success, false otherwise
+ */
+bool
+cubic_bezier(const struct bezier_control_point controls[4],
+ int *bezier,
+ size_t bezier_sz);
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh
old/xf86-input-libinput-0.23.0/src/xf86libinput.c
new/xf86-input-libinput-0.24.0/src/xf86libinput.c
--- old/xf86-input-libinput-0.23.0/src/xf86libinput.c 2016-12-05
05:26:14.000000000 +0100
+++ new/xf86-input-libinput-0.24.0/src/xf86libinput.c 2017-02-09
07:17:00.000000000 +0100
@@ -42,6 +42,7 @@
#include <X11/Xatom.h>
+#include "bezier.h"
#include "draglock.h"
#include "libinput-properties.h"
@@ -126,6 +127,9 @@
struct {
int vdist;
int hdist;
+
+ double vdist_fraction;
+ double hdist_fraction;
} scroll;
struct {
@@ -162,6 +166,10 @@
BOOL horiz_scrolling_enabled;
float rotation_angle;
+ struct bezier_control_point pressurecurve[4];
+ struct ratio {
+ int x, y;
+ } area;
} options;
struct draglock draglock;
@@ -172,6 +180,17 @@
struct libinput_tablet_tool *tablet_tool;
bool allow_mode_group_updates;
+
+ /* Pre-calculated pressure curve.
+ In the 0...TABLET_AXIS_MAX range */
+ struct {
+ int *values;
+ size_t sz;
+ } pressurecurve;
+
+ struct scale_factor {
+ double x, y;
+ } area_scale_factor;
};
enum event_handling {
@@ -382,6 +401,59 @@
return shared_device->enabled_count > 0;
}
+static inline bool
+xf86libinput_set_pressurecurve(struct xf86libinput *driver_data,
+ const struct bezier_control_point controls[4])
+{
+ if (memcmp(controls, bezier_defaults, sizeof(bezier_defaults)) == 0) {
+ free(driver_data->pressurecurve.values);
+ driver_data->pressurecurve.values = NULL;
+ return true;
+ }
+
+ if (!driver_data->pressurecurve.values) {
+ int *vals = calloc(TABLET_PRESSURE_AXIS_MAX + 1, sizeof(int));
+ if (!vals)
+ return false;
+
+ driver_data->pressurecurve.values = vals;
+ driver_data->pressurecurve.sz = TABLET_PRESSURE_AXIS_MAX + 1;
+ }
+
+ return cubic_bezier(controls,
+ driver_data->pressurecurve.values,
+ driver_data->pressurecurve.sz);
+}
+
+static inline void
+xf86libinput_set_area_ratio(struct xf86libinput *driver_data,
+ const struct ratio *ratio)
+{
+ double f;
+ double w, h;
+
+ if (libinput_device_get_size(driver_data->shared_device->device, &w,
&h) != 0)
+ return;
+
+ driver_data->options.area = *ratio;
+
+ if (ratio->y == 0) {
+ driver_data->area_scale_factor.x = 1.0;
+ driver_data->area_scale_factor.y = 1.0;
+ return;
+ }
+
+ f = 1.0 * (ratio->x * h)/(ratio->y * w);
+
+ if (f <= 1.0) {
+ driver_data->area_scale_factor.x = 1.0/f;
+ driver_data->area_scale_factor.y = 1.0;
+ } else {
+ driver_data->area_scale_factor.x = 1.0;
+ driver_data->area_scale_factor.y = f;
+ }
+}
+
static int
LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly);
@@ -785,6 +857,9 @@
struct xf86libinput *driver_data = pInfo->private;
struct libinput_device *ldevice = driver_data->shared_device->device;
+ if (!device->enabled)
+ return;
+
while (bits[i].xbit) {
if (ctrl->leds & bits[i].xbit)
leds |= bits[i].code;
@@ -1320,6 +1395,92 @@
xf86PostKeyboardEvent(dev, key, is_press);
}
+/*
+ * The scroll fraction is the value we divide the scroll dist with to
+ * accommodate for wheels with a small click angle. On these devices,
+ * multiple clicks of small angle accumulate to the XI 2.1 scroll distance.
+ * This gives us smooth scrolling on those wheels for small movements, the
+ * legacy button events are generated whenever the full distance is reached.
+ * e.g. a 2 degree click angle requires 8 clicks before a legacy event is
+ * sent, but each of those clicks will send XI2.1 smooth scroll data for
+ * compatible clients.
+ */
+static inline double
+get_scroll_fraction(struct xf86libinput *driver_data,
+ struct libinput_event_pointer *event,
+ enum libinput_pointer_axis axis)
+{
+ double *fraction;
+ double f;
+ double angle;
+ int discrete;
+
+ switch (axis) {
+ case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
+ fraction = &driver_data->scroll.hdist_fraction;
+ break;
+ case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
+ fraction = &driver_data->scroll.vdist_fraction;
+ break;
+ default:
+ return 0.0;
+ }
+
+ if (*fraction != 0.0)
+ return *fraction;
+
+ /* Calculate the angle per single scroll event */
+ angle = libinput_event_pointer_get_axis_value(event, axis);
+ discrete = libinput_event_pointer_get_axis_value_discrete(event, axis);
+ angle /= discrete;
+
+ /* We only do magic for click angles smaller than 10 degrees */
+ if (angle >= 10) {
+ *fraction = 1.0;
+ return 1.0;
+ }
+
+ /* Figure out something that gets close to 15 degrees (the general
+ * wheel default) with a number of clicks. This formula gives us
+ * between 12 and and 20 degrees for the range of 1-10. See
+ * https://bugs.freedesktop.org/attachment.cgi?id=128256 for a
+ * graph.
+ */
+ f = round(15.0/angle);
+
+ *fraction = f;
+
+ return f;
+}
+
+static inline bool
+calculate_axis_value(struct xf86libinput *driver_data,
+ enum libinput_pointer_axis axis,
+ struct libinput_event_pointer *event,
+ double *value_out)
+{
+ enum libinput_pointer_axis_source source;
+ double value;
+
+ if (!libinput_event_pointer_has_axis(event, axis))
+ return false;
+
+ source = libinput_event_pointer_get_axis_source(event);
+ if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL) {
+ double scroll_fraction;
+
+ value = libinput_event_pointer_get_axis_value_discrete(event,
axis);
+ scroll_fraction = get_scroll_fraction(driver_data, event, axis);
+ value *= driver_data->scroll.vdist/scroll_fraction;
+ } else {
+ value = libinput_event_pointer_get_axis_value(event, axis);
+ }
+
+ *value_out = value;
+
+ return true;
+}
+
static void
xf86libinput_handle_axis(InputInfoPtr pInfo, struct libinput_event_pointer
*event)
{
@@ -1327,7 +1488,6 @@
struct xf86libinput *driver_data = pInfo->private;
ValuatorMask *mask = driver_data->valuators;
double value;
- enum libinput_pointer_axis axis;
enum libinput_pointer_axis_source source;
if ((driver_data->capabilities & CAP_POINTER) == 0)
@@ -1345,30 +1505,20 @@
return;
}
- axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
- if (libinput_event_pointer_has_axis(event, axis)) {
- if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL) {
- value =
libinput_event_pointer_get_axis_value_discrete(event, axis);
- value *= driver_data->scroll.vdist;
- } else {
- value = libinput_event_pointer_get_axis_value(event,
axis);
- }
+ if (calculate_axis_value(driver_data,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ event,
+ &value))
valuator_mask_set_double(mask, 3, value);
- }
if (!driver_data->options.horiz_scrolling_enabled)
goto out;
- axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
- if (libinput_event_pointer_has_axis(event, axis)) {
- if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL) {
- value =
libinput_event_pointer_get_axis_value_discrete(event, axis);
- value *= driver_data->scroll.hdist;
- } else {
- value = libinput_event_pointer_get_axis_value(event,
axis);
- }
+ if (calculate_axis_value(driver_data,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ event,
+ &value))
valuator_mask_set_double(mask, 2, value);
- }
out:
xf86PostMotionEventM(dev, Relative, mask);
@@ -1603,6 +1753,26 @@
return EVENT_HANDLED;
}
+static void
+xf86libinput_apply_area(InputInfoPtr pInfo, double *x, double *y)
+{
+ struct xf86libinput *driver_data = pInfo->private;
+ const struct scale_factor *f = &driver_data->area_scale_factor;
+ double sx, sy;
+
+ if (driver_data->options.area.x == 0)
+ return;
+
+ /* In left-handed mode, libinput already gives us transformed
+ * coordinates, so we can clip the same way. */
+
+ sx = min(*x * f->x, TABLET_AXIS_MAX);
+ sy = min(*y * f->y, TABLET_AXIS_MAX);
+
+ *x = sx;
+ *y = sy;
+}
+
static enum event_handling
xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
struct libinput_event_tablet_tool *event)
@@ -1612,22 +1782,25 @@
ValuatorMask *mask = driver_data->valuators;
struct libinput_tablet_tool *tool;
double value;
+ double x, y;
if (xf86libinput_tool_queue_event(event))
return EVENT_QUEUED;
- value = libinput_event_tablet_tool_get_x_transformed(event,
- TABLET_AXIS_MAX);
- valuator_mask_set_double(mask, 0, value);
- value = libinput_event_tablet_tool_get_y_transformed(event,
- TABLET_AXIS_MAX);
- valuator_mask_set_double(mask, 1, value);
+ x = libinput_event_tablet_tool_get_x_transformed(event,
+ TABLET_AXIS_MAX);
+ y = libinput_event_tablet_tool_get_y_transformed(event,
+ TABLET_AXIS_MAX);
+ xf86libinput_apply_area(pInfo, &x, &y);
+ valuator_mask_set_double(mask, 0, x);
+ valuator_mask_set_double(mask, 1, y);
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;
+ value = TABLET_PRESSURE_AXIS_MAX *
libinput_event_tablet_tool_get_pressure(event);
+ if (driver_data->pressurecurve.values)
+ value = driver_data->pressurecurve.values[(int)value];
valuator_mask_set_double(mask, 2, value);
}
@@ -2060,13 +2233,7 @@
.close_restricted = close_restricted,
};
-static void
-xf86libinput_log_handler(struct libinput *libinput,
- enum libinput_log_priority priority,
- const char *format,
- va_list args)
- _X_ATTRIBUTE_PRINTF(3, 0);
-
+_X_ATTRIBUTE_PRINTF(3, 0)
static void
xf86libinput_log_handler(struct libinput *libinput,
enum libinput_log_priority priority,
@@ -2609,6 +2776,111 @@
}
static void
+xf86libinput_parse_pressurecurve_option(InputInfoPtr pInfo,
+ struct xf86libinput *driver_data,
+ struct bezier_control_point pcurve[4])
+{
+ struct bezier_control_point controls[4] = {
+ { 0.0, 0.0 },
+ { 0.0, 0.0 },
+ { 1.0, 1.0 },
+ { 1.0, 1.0 },
+ };
+ float points[8];
+ char *str;
+ int rc = 0;
+ int test_bezier[64];
+ struct libinput_tablet_tool *tool = driver_data->tablet_tool;
+
+ if ((driver_data->capabilities & CAP_TABLET_TOOL) == 0)
+ return;
+
+ if (!tool || !libinput_tablet_tool_has_pressure(tool))
+ return;
+
+ str = xf86SetStrOption(pInfo->options,
+ "TabletToolPressureCurve",
+ NULL);
+ if (!str)
+ goto out;
+
+ rc = sscanf(str, "%f/%f %f/%f %f/%f %f/%f",
+ &points[0], &points[1], &points[2], &points[3],
+ &points[4], &points[5], &points[6], &points[7]);
+ if (rc != 8)
+ goto out;
+
+ for (int i = 0; i < 4; i++) {
+ if (points[i] < 0.0 || points[i] > 1.0)
+ goto out;
+ }
+
+ controls[0].x = points[0];
+ controls[0].y = points[1];
+ controls[1].x = points[2];
+ controls[1].y = points[3];
+ controls[2].x = points[4];
+ controls[2].y = points[5];
+ controls[3].x = points[6];
+ controls[3].y = points[7];
+
+ if (!cubic_bezier(controls, test_bezier, ARRAY_SIZE(test_bezier))) {
+ memcpy(controls, bezier_defaults, sizeof(controls));
+ goto out;
+ }
+
+ rc = 0;
+out:
+ if (rc != 0)
+ xf86IDrvMsg(pInfo, X_ERROR, "Invalid pressure curve: %s\n",
str);
+ free(str);
+ memcpy(pcurve, controls, sizeof(controls));
+ xf86libinput_set_pressurecurve(driver_data, controls);
+}
+
+static inline bool
+want_area_handling(struct xf86libinput *driver_data)
+{
+ struct libinput_device *device = driver_data->shared_device->device;
+
+ if ((driver_data->capabilities & CAP_TABLET_TOOL) == 0)
+ return false;
+
+ /* If we have a calibration matrix, it's a built-in tablet and we
+ * don't need to set the area ratio on those */
+ return !libinput_device_config_calibration_has_matrix(device);
+}
+
+static void
+xf86libinput_parse_tablet_area_option(InputInfoPtr pInfo,
+ struct xf86libinput *driver_data,
+ struct ratio *area_out)
+{
+ char *str;
+ int rc;
+ struct ratio area;
+
+ if (!want_area_handling(driver_data))
+ return;
+
+ str = xf86SetStrOption(pInfo->options,
+ "TabletToolAreaRatio",
+ NULL);
+ if (!str || strcmp(str, "default") == 0)
+ goto out;
+
+ rc = sscanf(str, "%d:%d", &area.x, &area.y);
+ if (rc != 2 || area.x <= 0 || area.y <= 0) {
+ xf86IDrvMsg(pInfo, X_ERROR, "Invalid tablet tool area ratio:
%s\n", str);
+ } else {
+ *area_out = area;
+ }
+
+out:
+ free(str);
+}
+
+static void
xf86libinput_parse_options(InputInfoPtr pInfo,
struct xf86libinput *driver_data,
struct libinput_device *device)
@@ -2641,6 +2913,13 @@
xf86libinput_parse_draglock_option(pInfo, driver_data);
options->horiz_scrolling_enabled =
xf86libinput_parse_horiz_scroll_option(pInfo);
}
+
+ xf86libinput_parse_pressurecurve_option(pInfo,
+ driver_data,
+ options->pressurecurve);
+ xf86libinput_parse_tablet_area_option(pInfo,
+ driver_data,
+ &options->area);
}
static const char*
@@ -2928,13 +3207,19 @@
pInfo->private = driver_data;
driver_data->pInfo = pInfo;
- driver_data->scroll.vdist = 15;
- driver_data->scroll.hdist = 15;
driver_data->path = path;
driver_data->shared_device = shared_device;
xorg_list_append(&driver_data->shared_device_link,
&shared_device->device_list);
+ /* Scroll dist value matters for source finger/continuous. For those
+ * devices libinput provides pixel-like data, changing this will
+ * affect touchpad scroll speed. For wheels it doesn't matter as
+ * we're using the discrete value only.
+ */
+ driver_data->scroll.vdist = 15;
+ driver_data->scroll.hdist = 15;
+
if (!is_subdevice) {
if (libinput_device_has_capability(device,
LIBINPUT_DEVICE_CAP_POINTER))
driver_data->capabilities |= CAP_POINTER;
@@ -3093,6 +3378,8 @@
/* driver properties */
static Atom prop_draglock;
static Atom prop_horiz_scroll;
+static Atom prop_pressurecurve;
+static Atom prop_area_ratio;
/* general properties */
static Atom prop_float;
@@ -3843,6 +4130,108 @@
return Success;
}
+static inline int
+LibinputSetPropertyPressureCurve(DeviceIntPtr dev,
+ Atom atom,
+ XIPropertyValuePtr val,
+ BOOL checkonly)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ struct xf86libinput *driver_data = pInfo->private;
+ float *vals;
+ struct bezier_control_point controls[4];
+
+ if (val->format != 32 || val->size != 8 || val->type != prop_float)
+ return BadMatch;
+
+ vals = val->data;
+ controls[0].x = vals[0];
+ controls[0].y = vals[1];
+ controls[1].x = vals[2];
+ controls[1].y = vals[3];
+ controls[2].x = vals[4];
+ controls[2].y = vals[5];
+ controls[3].x = vals[6];
+ controls[3].y = vals[7];
+
+ if (checkonly) {
+ int test_bezier[64];
+
+ for (int i = 0; i < val->size; i++) {
+ if (vals[i] < 0.0 || vals[i] > 1.0)
+ return BadValue;
+ }
+
+ if (!xf86libinput_check_device (dev, atom))
+ return BadMatch;
+
+ if (!cubic_bezier(controls, test_bezier,
ARRAY_SIZE(test_bezier)))
+ return BadValue;
+ } else {
+ xf86libinput_set_pressurecurve(driver_data, controls);
+ memcpy(driver_data->options.pressurecurve, controls,
+ sizeof(controls));
+ }
+
+ return Success;
+}
+
+static inline int
+LibinputSetPropertyAreaRatio(DeviceIntPtr dev,
+ Atom atom,
+ XIPropertyValuePtr val,
+ BOOL checkonly)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ struct xf86libinput *driver_data = pInfo->private;
+ uint32_t *vals;
+ struct ratio area = { 0, 0 };
+
+ if (val->format != 32 || val->size != 2 || val->type != XA_CARDINAL)
+ return BadMatch;
+
+ vals = val->data;
+ area.x = vals[0];
+ area.y = vals[1];
+
+ if (checkonly) {
+ if (area.x < 0 || area.y < 0)
+ return BadValue;
+
+ if ((area.x != 0 && area.y == 0) ||
+ (area.x == 0 && area.y != 0))
+ return BadValue;
+
+ if (!xf86libinput_check_device (dev, atom))
+ return BadMatch;
+ } else {
+ struct xf86libinput *other;
+
+ xf86libinput_set_area_ratio(driver_data, &area);
+
+ xorg_list_for_each_entry(other,
+
&driver_data->shared_device->device_list,
+ shared_device_link) {
+ DeviceIntPtr other_device = other->pInfo->dev;
+
+ if (other->options.area.x == area.x &&
+ other->options.area.y == area.y)
+ continue;
+
+ XIChangeDeviceProperty(other_device,
+ atom,
+ val->type,
+ val->format,
+ PropModeReplace,
+ val->size,
+ val->data,
+ TRUE);
+ }
+ }
+
+ return Success;
+}
+
static int
LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly)
@@ -3895,6 +4284,10 @@
}
else if (atom == prop_rotation_angle)
rc = LibinputSetPropertyRotationAngle(dev, atom, val,
checkonly);
+ else if (atom == prop_pressurecurve)
+ rc = LibinputSetPropertyPressureCurve(dev, atom, val,
checkonly);
+ else if (atom == prop_area_ratio)
+ rc = LibinputSetPropertyAreaRatio(dev, atom, val, checkonly);
else if (atom == prop_device || atom == prop_product_id ||
atom == prop_tap_default ||
atom == prop_tap_drag_default ||
@@ -4720,6 +5113,54 @@
}
static void
+LibinputInitPressureCurveProperty(DeviceIntPtr dev,
+ struct xf86libinput *driver_data)
+{
+ const struct bezier_control_point *curve =
driver_data->options.pressurecurve;
+ struct libinput_tablet_tool *tool = driver_data->tablet_tool;
+ float data[8];
+
+ if ((driver_data->capabilities & CAP_TABLET_TOOL) == 0)
+ return;
+
+ if (!tool || !libinput_tablet_tool_has_pressure(tool))
+ return;
+
+ data[0] = curve[0].x;
+ data[1] = curve[0].y;
+ data[2] = curve[1].x;
+ data[3] = curve[1].y;
+ data[4] = curve[2].x;
+ data[5] = curve[2].y;
+ data[6] = curve[3].x;
+ data[7] = curve[3].y;
+
+ prop_pressurecurve = LibinputMakeProperty(dev,
+
LIBINPUT_PROP_TABLET_TOOL_PRESSURECURVE,
+ prop_float, 32,
+ 8, data);
+}
+
+static void
+LibinputInitTabletAreaRatioProperty(DeviceIntPtr dev,
+ struct xf86libinput *driver_data)
+{
+ const struct ratio *ratio = &driver_data->options.area;
+ uint32_t data[2];
+
+ if (!want_area_handling(driver_data))
+ return;
+
+ data[0] = ratio->x;
+ data[1] = ratio->y;
+
+ prop_area_ratio = LibinputMakeProperty(dev,
+
LIBINPUT_PROP_TABLET_TOOL_AREA_RATIO,
+ XA_CARDINAL, 32,
+ 2, data);
+}
+
+static void
LibinputInitProperty(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
@@ -4775,4 +5216,6 @@
LibinputInitDragLockProperty(dev, driver_data);
LibinputInitHorizScrollProperty(dev, driver_data);
+ LibinputInitPressureCurveProperty(dev, driver_data);
+ LibinputInitTabletAreaRatioProperty(dev, driver_data);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh
old/xf86-input-libinput-0.23.0/test/Makefile.am
new/xf86-input-libinput-0.24.0/test/Makefile.am
--- old/xf86-input-libinput-0.23.0/test/Makefile.am 2016-11-14
04:27:06.000000000 +0100
+++ new/xf86-input-libinput-0.24.0/test/Makefile.am 2017-02-09
07:17:00.000000000 +0100
@@ -3,11 +3,14 @@
-I$(top_srcdir)/include \
-I$(top_srcdir)/src
-tests = test-draglock
+tests = test-draglock test-bezier
noinst_PROGRAMS = $(tests)
test_draglock_SOURCES = test-draglock.c
test_draglock_LDADD = ../src/libdraglock.la
+test_bezier_SOURCES = test-bezier.c
+test_bezier_LDADD = ../src/libbezier.la -lm
+
TESTS = $(tests)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh
old/xf86-input-libinput-0.23.0/test/test-bezier.c
new/xf86-input-libinput-0.24.0/test/test-bezier.c
--- old/xf86-input-libinput-0.23.0/test/test-bezier.c 1970-01-01
01:00:00.000000000 +0100
+++ new/xf86-input-libinput-0.24.0/test/test-bezier.c 2017-02-09
07:17:00.000000000 +0100
@@ -0,0 +1,199 @@
+/*
+ * Copyright © 2016 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission. Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "bezier.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+static inline void
+print_curve(int *bezier, size_t size)
+{
+ /* look at it with gnuplot, "plot 'output-file.txt'" */
+ for (int i = 0; i < size; i++)
+ printf("%d %d\n", i, bezier[i]);
+}
+
+static void
+test_linear(void)
+{
+ const int size = 2048;
+ int bezier[size];
+
+ struct bezier_control_point controls[] = {
+ { 0.0, 0.0 },
+ { 0.0, 0.0 },
+ { 1.0, 1.0 },
+ { 1.0, 1.0 }
+ };
+
+ cubic_bezier(controls, bezier, size);
+
+ assert(bezier[0] == 0);
+ assert(bezier[size - 1] == size - 1);
+
+ for (int x = 1; x < size; x++)
+ assert(bezier[x] == x);
+}
+
+/* Center point pulled down towards X axis */
+static void
+test_flattened(void)
+{
+ const int size = 2048;
+ int bezier[size];
+
+ struct bezier_control_point controls[] = {
+ { 0.0, 0.0 },
+ { 0.1, 0.0 },
+ { 1.0, 0.9 },
+ { 1.0, 1.0 }
+ };
+
+ cubic_bezier(controls, bezier, size);
+
+ assert(bezier[0] == 0);
+ assert(bezier[size - 1] == size - 1);
+
+ for (int x = 1; x < size - 1; x++) {
+ assert(bezier[x] < x);
+ }
+}
+
+/* Center point pulled up from X axis */
+static void
+test_raised(void)
+{
+ const int size = 2048;
+ int bezier[size];
+
+ struct bezier_control_point controls[] = {
+ { 0.0, 0.0 },
+ { 0.1, 0.4 },
+ { 0.4, 1.0 },
+ { 1.0, 1.0 }
+ };
+
+ cubic_bezier(controls, bezier, size);
+
+ assert(bezier[0] == 0);
+ assert(bezier[size - 1] == size - 1);
+
+ for (int x = 1; x < size; x++)
+ assert(bezier[x] >= x);
+
+ for (int x = 10; x < size - 10; x++)
+ assert(bezier[x] > x);
+}
+
+static void
+test_windy(void)
+{
+ const int size = 2048;
+ int bezier[size];
+
+ struct bezier_control_point controls[] = {
+ { 0.0, 0.0 },
+ { 0.0, 0.3 },
+ { 1.0, 0.7 },
+ { 1.0, 1.0 }
+ };
+
+ cubic_bezier(controls, bezier, size);
+
+ assert(bezier[0] == 0);
+ assert(bezier[size - 1] == size - 1);
+
+ for (int x = 1; x < size/2 - 20; x++)
+ assert(bezier[x] > x);
+
+ for (int x = size/2 + 20; x < size - 1; x++)
+ assert(bezier[x] < x);
+}
+
+static void
+test_nonzero_x_linear(void)
+{
+ const int size = 2048;
+ int bezier[size];
+ int x;
+
+ struct bezier_control_point controls[] = {
+ { 0.2, 0.0 },
+ { 0.2, 0.0 },
+ { 0.8, 1.0 },
+ { 0.8, 1.0 }
+ };
+
+ cubic_bezier(controls, bezier, size);
+
+ x = 0;
+ do {
+ assert(bezier[x] == 0);
+ } while (++x < size * 0.2 - 1);
+
+ do {
+ assert(bezier[x] > bezier[x-1]);
+ } while (++x < size * 0.8 - 1);
+
+ do {
+ assert(bezier[x] == size - 1);
+ } while (++x < size);
+}
+
+static void
+test_nonzero_y_linear(void)
+{
+ const int size = 2048;
+ int bezier[size];
+
+ struct bezier_control_point controls[] = {
+ { 0.0, 0.2 },
+ { 0.0, 0.2 },
+ { 1.0, 0.8 },
+ { 1.0, 0.8 }
+ };
+
+ cubic_bezier(controls, bezier, size);
+
+ assert(bezier[0] == (int)(size * 0.2));
+
+ for (int x = 1; x < size; x++) {
+ assert(bezier[x - 1] <= bezier[x]);
+ assert(bezier[x] >= (int)(size * 0.2));
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ test_linear();
+ test_flattened();
+ test_raised();
+ test_windy();
+ test_nonzero_x_linear();
+ test_nonzero_y_linear();
+
+ return 0;
+}