libinput: Changes to 'ubuntu'
README.txt | 14
configure.ac | 33
debian/changelog | 22
debian/libinput10.symbols | 4
debian/patches/0001-libinput-add-orientation-and-size-of-touch-point-and.patch | 1601 ++++++++++
debian/patches/0002-extend-tools-to-print-and-display-touch-event-proper.patch | 141
debian/patches/0003-Fix-premature-flushing-of-evdev-event-on-mx4-touchsc.patch | 171 +
debian/patches/0004-Keep-stanza-for-new-symbols-on-version-0.22.0.patch | 61
debian/patches/fix-premature-flushing-of-evdev-event-on-mx4.patch | 164 -
debian/patches/series | 6
debian/patches/touch-point-orientation-size.patch | 1587 ---------
debian/upstream/signing-key.asc | 24
debian/watch | 2
doc/Makefile.am | 3
doc/building.dox | 100
doc/contributing.dox | 18
doc/libinput.doxygen.in | 1
doc/middle-button-emulation.dox | 34
doc/page-hierarchy.dox | 6
doc/pointer-acceleration.dox | 25
doc/reporting-bugs.dox | 113
doc/tablet-support.dox | 13
doc/test-suite.dox | 21
src/evdev-mt-touchpad-buttons.c | 113
src/evdev-mt-touchpad-edge-scroll.c | 21
src/evdev-mt-touchpad-gestures.c | 5
src/evdev-mt-touchpad-tap.c | 82
src/evdev-mt-touchpad.c | 280 +
src/evdev-mt-touchpad.h | 27
src/evdev-tablet-pad.c | 1
src/evdev-tablet.c | 94
src/evdev-tablet.h | 5
src/evdev.c | 1232 ++++---
src/evdev.h | 156
src/libinput-private.h | 26
src/libinput-uninstalled.pc.in | 10
src/libinput-util.c | 34
src/libinput-util.h | 17
src/libinput.c | 47
src/libinput.h | 105
src/libinput.sym | 6
test/Makefile.am | 109
test/device.c | 129
test/gestures.c | 4
test/keyboard.c | 2
test/litest-device-mouse-wheel-click-angle.c | 3
test/litest-device-mouse-wheel-click-count.c | 77
test/litest-device-synaptics.c | 4
test/litest-device-wacom-cintiq-13hdt-finger.c | 10
test/litest-device-wacom-cintiq-13hdt-pad.c | 3
test/litest-device-wacom-cintiq-13hdt-pen.c | 10
test/litest-device-wacom-intuos-finger.c | 10
test/litest-device-wacom-intuos-tablet.c | 10
test/litest-device-wacom-intuos5-pad.c | 1
test/litest.c | 588 ++-
test/litest.h | 43
test/log.c | 4
test/misc.c | 37
test/pad.c | 2
test/path.c | 14
test/pointer.c | 62
test/tablet.c | 367 ++
test/touch.c | 2
test/touchpad-buttons.c | 2
test/touchpad-tap.c | 290 +
test/touchpad.c | 439 ++
test/trackball.c | 2
test/trackpoint.c | 2
test/udev.c | 14
tools/event-debug.c | 12
tools/event-gui.c | 2
tools/shared.c | 22
tools/shared.h | 1
udev/90-libinput-model-quirks.hwdb | 9
udev/Makefile.am | 16
udev/libinput-device-group.c | 64
udev/parse_hwdb.py | 178 +
77 files changed, 5973 insertions(+), 2996 deletions(-)
New commits:
commit ff567def94f21b75c216ae7ecf2d252d02e512ee
Author: Timo Aaltonen <tjaalton@debian.org>
Date: Tue Nov 22 15:48:29 2016 +0200
updload to zesty
diff --git a/debian/changelog b/debian/changelog
index 2c1c2d4..a96109c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,10 +1,10 @@
-libinput (1.5.1-1ubuntu1) UNRELEASED; urgency=medium
+libinput (1.5.1-1ubuntu1) zesty; urgency=medium
* Merge from Debian.
* Split, rename & refresh patches for touch point orientation and
event flushing on MX4.
- -- Timo Aaltonen <tjaalton@debian.org> Tue, 22 Nov 2016 15:41:10 +0200
+ -- Timo Aaltonen <tjaalton@debian.org> Tue, 22 Nov 2016 15:48:09 +0200
libinput (1.5.1-1) unstable; urgency=medium
commit 8788dc2f6c254422da919be4121f1f028021a30a
Author: Timo Aaltonen <tjaalton@debian.org>
Date: Tue Nov 22 15:48:06 2016 +0200
update changelog
diff --git a/debian/changelog b/debian/changelog
index 482a542..2c1c2d4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,11 +1,4 @@
-libinput (1.5.1-1) unstable; urgency=medium
-
- * New upstream release.
- * watch: Let uscan verify tarball signatures.
-
- -- Timo Aaltonen <tjaalton@debian.org> Fri, 18 Nov 2016 15:58:09 +0200
-
-libinput (1.5.0-1ubuntu1) UNRELEASED; urgency=medium
+libinput (1.5.1-1ubuntu1) UNRELEASED; urgency=medium
* Merge from Debian.
* Split, rename & refresh patches for touch point orientation and
@@ -13,6 +6,13 @@ libinput (1.5.0-1ubuntu1) UNRELEASED; urgency=medium
-- Timo Aaltonen <tjaalton@debian.org> Tue, 22 Nov 2016 15:41:10 +0200
+libinput (1.5.1-1) unstable; urgency=medium
+
+ * New upstream release.
+ * watch: Let uscan verify tarball signatures.
+
+ -- Timo Aaltonen <tjaalton@debian.org> Fri, 18 Nov 2016 15:58:09 +0200
+
libinput (1.5.0-1) unstable; urgency=medium
* New upstream release.
commit 418b33c635613c7251ad5c00554844b33e4a5315
Author: Timo Aaltonen <tjaalton@debian.org>
Date: Tue Nov 22 15:42:01 2016 +0200
split and update patches
diff --git a/debian/changelog b/debian/changelog
index 1fcdd8f..f01483f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+libinput (1.5.0-1ubuntu1) UNRELEASED; urgency=medium
+
+ * Merge from Debian.
+ * Split, rename & refresh patches for touch point orientation and
+ event flushing on MX4.
+
+ -- Timo Aaltonen <tjaalton@debian.org> Tue, 22 Nov 2016 15:41:10 +0200
+
libinput (1.5.0-1) unstable; urgency=medium
* New upstream release.
diff --git a/debian/patches/0001-libinput-add-orientation-and-size-of-touch-point-and.patch b/debian/patches/0001-libinput-add-orientation-and-size-of-touch-point-and.patch
new file mode 100644
index 0000000..e31ebc8
--- /dev/null
+++ b/debian/patches/0001-libinput-add-orientation-and-size-of-touch-point-and.patch
@@ -0,0 +1,1601 @@
+From a50c0a226d769fade483104c95fb55ebba6ca0de Mon Sep 17 00:00:00 2001
+From: Andreas Pokorny <andreas.pokorny@canonical.com>
+Date: Mon, 2 Nov 2015 16:13:40 +0100
+Subject: [PATCH libinput 1/4] libinput: add orientation and size of touch
+ point and pressure to the API
+
+This change adds four new properties to touch events:
+* major: diameter of the touch ellipse along the major axis
+* minor: diameter perpendicular to major axis
+* pressure: a pressure value mapped into the range [0, 1]
+* orientation: the angle between major and the x axis [0, 360]
+
+Those values are optionally supported by multi-touch drivers, so default values
+are used if the information is missing. The existance of each of the properties
+can be queried at the event using another set of libinput_event_touch_has_*
+functions.
+
+Explanation of those values was added to the touch screen page.
+
+Signed-off-by: Andreas Pokorny <andreas.pokorny@canonical.com>
+---
+ doc/Makefile.am | 2 +
+ doc/page-hierarchy.dox | 1 +
+ doc/svg/touchscreen-touch-event-properties.svg | 347 +++++++++++++++++++++++++
+ doc/touch-event-properties.dox | 42 +++
+ src/evdev.c | 169 +++++++++++-
+ src/evdev.h | 25 ++
+ src/libinput-private.h | 13 +-
+ src/libinput.c | 212 ++++++++++++++-
+ src/libinput.h | 222 ++++++++++++++++
+ src/libinput.sym | 13 +
+ test/touch.c | 242 +++++++++++++++++
+ 11 files changed, 1278 insertions(+), 10 deletions(-)
+ create mode 100644 doc/svg/touchscreen-touch-event-properties.svg
+ create mode 100644 doc/touch-event-properties.dox
+
+diff --git a/doc/Makefile.am b/doc/Makefile.am
+index 698a316..5a346fc 100644
+--- a/doc/Makefile.am
++++ b/doc/Makefile.am
+@@ -28,6 +28,7 @@ header_files = \
+ $(srcdir)/test-suite.dox \
+ $(srcdir)/tools.dox \
+ $(srcdir)/touchpad-jumping-cursors.dox \
++ $(srcdir)/touch-event-properties.dox \
+ $(srcdir)/touchpads.dox
+
+ diagram_files = \
+@@ -62,6 +63,7 @@ diagram_files = \
+ $(srcdir)/svg/thumb-detection.svg \
+ $(srcdir)/svg/top-software-buttons.svg \
+ $(srcdir)/svg/touchscreen-gestures.svg \
++ $(srcdir)/svg/touchscreen-touch-event-properties.svg \
+ $(srcdir)/svg/twofinger-scrolling.svg
+
+ style_files = \
+diff --git a/doc/page-hierarchy.dox b/doc/page-hierarchy.dox
+index 6f1a4bc..3beb04f 100644
+--- a/doc/page-hierarchy.dox
++++ b/doc/page-hierarchy.dox
+@@ -13,6 +13,7 @@
+ @page touchscreens Touchscreens
+
+ - @subpage absolute_axes
++- @subpage touch_event_properties
+
+ @page pointers Mice, Trackballs, etc.
+
+diff --git a/doc/svg/touchscreen-touch-event-properties.svg b/doc/svg/touchscreen-touch-event-properties.svg
+new file mode 100644
+index 0000000..b728f40
+--- /dev/null
++++ b/doc/svg/touchscreen-touch-event-properties.svg
+@@ -0,0 +1,347 @@
++<?xml version="1.0" encoding="UTF-8" standalone="no"?>
++<!-- Created with Inkscape (http://www.inkscape.org/) -->
++
++<svg
++ xmlns:dc="http://purl.org/dc/elements/1.1/"
++ xmlns:cc="http://creativecommons.org/ns#"
++ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
++ xmlns:svg="http://www.w3.org/2000/svg"
++ xmlns="http://www.w3.org/2000/svg"
++ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
++ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
++ width="81.778557mm"
++ height="107.62305mm"
++ viewBox="0 0 289.76655 381.34154"
++ id="svg2"
++ version="1.1"
++ inkscape:version="0.91 r13725"
++ sodipodi:docname="touchscreen-touch-event-properties.svg">
++ <defs
++ id="defs4">
++ <marker
++ inkscape:stockid="DotL"
++ orient="auto"
++ refY="0"
++ refX="0"
++ id="DotL"
++ style="overflow:visible"
++ inkscape:isstock="true">
++ <path
++ id="path4259"
++ d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
++ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
++ transform="matrix(0.8,0,0,0.8,5.92,0.8)"
++ inkscape:connector-curvature="0" />
++ </marker>
++ <marker
++ inkscape:stockid="CurveOut"
++ orient="auto"
++ refY="0"
++ refX="0"
++ id="CurveOut"
++ style="overflow:visible"
++ inkscape:isstock="true">
++ <path
++ id="path4385"
++ d="m -5.4129913,-5.0456926 c 2.76,0 4.99999999,2.24 4.99999999,5.00000002 0,2.75999998 -2.23999999,4.99999998 -4.99999999,4.99999998"
++ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
++ transform="scale(0.6,0.6)"
++ inkscape:connector-curvature="0" />
++ </marker>
++ <marker
++ inkscape:stockid="StopL"
++ orient="auto"
++ refY="0"
++ refX="0"
++ id="StopL"
++ style="overflow:visible"
++ inkscape:isstock="true">
++ <path
++ id="path4367"
++ d="M 0,5.65 0,-5.65"
++ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
++ transform="scale(0.8,0.8)"
++ inkscape:connector-curvature="0" />
++ </marker>
++ <marker
++ style="overflow:visible"
++ id="DistanceStart"
++ refX="0"
++ refY="0"
++ orient="auto"
++ inkscape:stockid="DistanceStart"
++ inkscape:isstock="true">
++ <g
++ id="g2300"
++ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1">
++ <path
++ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.14999998;stroke-linecap:square;stroke-opacity:1"
++ d="M 0,0 2,0"
++ id="path2306"
++ inkscape:connector-curvature="0" />
++ <path
++ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-opacity:1"
++ d="M 0,0 13,4 9,0 13,-4 0,0 Z"
++ id="path2302"
++ inkscape:connector-curvature="0" />
++ <path
++ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-opacity:1"
++ d="M 0,-4 0,40"
++ id="path2304"
++ inkscape:connector-curvature="0" />
++ </g>
++ </marker>
++ <marker
++ inkscape:stockid="Arrow2Mend"
++ orient="auto"
++ refY="0"
++ refX="0"
++ id="Arrow2Mend"
++ style="overflow:visible"
++ inkscape:isstock="true">
++ <path
++ id="path4225"
++ style="fill:#cb004e;fill-opacity:1;fill-rule:evenodd;stroke:#cb004e;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
++ transform="scale(-0.6,-0.6)"
++ inkscape:connector-curvature="0" />
++ </marker>
++ <marker
++ inkscape:stockid="Arrow2Lend"
++ orient="auto"
++ refY="0"
++ refX="0"
++ id="Arrow2Lend"
++ style="overflow:visible"
++ inkscape:isstock="true">
++ <path
++ id="path4219"
++ style="fill:#cb004e;fill-opacity:1;fill-rule:evenodd;stroke:#cb004e;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
++ inkscape:connector-curvature="0" />
++ </marker>
++ <marker
++ inkscape:stockid="TriangleInL"
++ orient="auto"
++ refY="0"
++ refX="0"
++ id="TriangleInL"
++ style="overflow:visible"
++ inkscape:isstock="true">
++ <path
++ id="path4331"
++ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
++ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:#b3b3b3;stroke-width:1pt;stroke-opacity:1"
++ transform="scale(-0.8,-0.8)"
++ inkscape:connector-curvature="0" />
++ </marker>
++ <marker
++ inkscape:stockid="Arrow2Lstart"
++ orient="auto"
++ refY="0"
++ refX="0"
++ id="Arrow2Lstart"
++ style="overflow:visible"
++ inkscape:isstock="true">
++ <path
++ id="path4216"
++ style="fill:#cb004e;fill-opacity:1;fill-rule:evenodd;stroke:#cb004e;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
++ transform="matrix(1.1,0,0,1.1,1.1,0)"
++ inkscape:connector-curvature="0" />
++ </marker>
++ <inkscape:path-effect
++ effect="powerstroke"
++ id="path-effect4140"
++ is_visible="true"
++ offset_points="0,0.5"
++ sort_points="true"
++ interpolator_type="Linear"
++ interpolator_beta="0.2"
++ start_linecap_type="zerowidth"
++ linejoin_type="round"
++ miter_limit="4"
++ end_linecap_type="zerowidth"
++ cusp_linecap_type="round" />
++ <marker
++ inkscape:stockid="TriangleInL"
++ orient="auto"
++ refY="0"
++ refX="0"
++ id="TriangleInL-1"
++ style="overflow:visible"
++ inkscape:isstock="true">
++ <path
++ inkscape:connector-curvature="0"
++ id="path4331-8"
++ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
++ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:#b3b3b3;stroke-width:1pt;stroke-opacity:1"
++ transform="scale(-0.8,-0.8)" />
++ </marker>
++ <marker
++ inkscape:stockid="TriangleInL"
++ orient="auto"
++ refY="0"
++ refX="0"
++ id="TriangleInL-1-3"
++ style="overflow:visible"
++ inkscape:isstock="true">
++ <path
++ inkscape:connector-curvature="0"
++ id="path4331-8-7"
++ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
++ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:#b3b3b3;stroke-width:1pt;stroke-opacity:1"
++ transform="scale(-0.8,-0.8)" />
++ </marker>
++ </defs>
++ <sodipodi:namedview
++ id="base"
++ pagecolor="#ffffff"
++ bordercolor="#666666"
++ borderopacity="1.0"
++ inkscape:pageopacity="0.0"
++ inkscape:pageshadow="2"
++ inkscape:zoom="0.99999999"
++ inkscape:cx="123.83444"
++ inkscape:cy="279.21547"
++ inkscape:document-units="px"
++ inkscape:current-layer="layer1"
++ showgrid="false"
++ showguides="false"
++ inkscape:window-width="2560"
++ inkscape:window-height="1056"
++ inkscape:window-x="0"
++ inkscape:window-y="24"
++ inkscape:window-maximized="1"
++ fit-margin-top="0"
++ fit-margin-left="0"
++ fit-margin-right="0"
++ fit-margin-bottom="0" />
++ <metadata
++ id="metadata7">
++ <rdf:RDF>
++ <cc:Work
++ rdf:about="">
++ <dc:format>image/svg+xml</dc:format>
++ <dc:type
++ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
++ <dc:title></dc:title>
++ </cc:Work>
++ </rdf:RDF>
++ </metadata>
++ <g
++ inkscape:label="Layer 1"
++ inkscape:groupmode="layer"
++ id="layer1"
++ transform="translate(-99.549825,-70.836892)">
++ <path
++ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:#b3b3b3;stroke-width:1.79780054px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#TriangleInL-1-3)"
++ d="m 231.28087,80.931744 -0.008,371.246666"
++ id="path4144-1-8-1"
++ inkscape:connector-curvature="0"
++ sodipodi:nodetypes="cc" />
++ <g
++ id="g6309"
++ inkscape:transform-center-x="-9.527809"
++ inkscape:transform-center-y="-8.1612127"
++ transform="matrix(1.171972,1.3632932,-1.3632932,1.171972,275.33248,-179.00364)">
++ <path
++ sodipodi:nodetypes="cc"
++ inkscape:connector-curvature="0"
++ id="path4144-1-8"
++ d="m 172.88767,70.631028 -0.004,206.500482"
++ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:#b3b3b3;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#TriangleInL-1)" />
++ <ellipse
++ ry="77.321434"
++ rx="45.89286"
++ cy="180.93364"
++ cx="172.85715"
++ id="path4136"
++ style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
++ <path
++ sodipodi:nodetypes="cc"
++ inkscape:connector-curvature="0"
++ id="path4142"
++ d="m 126.9449,180.93396 91.84596,0.007"
++ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
++ <path
++ sodipodi:nodetypes="cc"
++ inkscape:connector-curvature="0"
++ id="path4144"
++ d="m 172.84766,103.6564 -0.004,154.59727"
++ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
++ <text
++ sodipodi:linespacing="125%"
++ id="text4146"
++ y="188.01213"
++ x="128.08986"
++ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.5px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
++ xml:space="preserve"><tspan
++ y="188.01213"
++ x="128.08986"
++ id="tspan4148"
++ sodipodi:role="line">minor axis</tspan></text>
++ <text
++ transform="matrix(0,-1,1,0,0,0)"
++ sodipodi:linespacing="125%"
++ id="text4150"
++ y="169.33234"
++ x="-256.35562"
++ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.5px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
++ xml:space="preserve"><tspan
++ y="169.33234"
++ x="-256.35562"
++ id="tspan4152"
++ sodipodi:role="line">major axis</tspan></text>
++ </g>
++ <text
++ xml:space="preserve"
++ style="font-style:normal;font-weight:normal;font-size:71.91202545px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
++ x="44.285629"
++ y="369.12045"
++ id="text6877"
++ sodipodi:linespacing="125%"
++ transform="matrix(0.76306478,-0.64632201,0.64632201,0.76306478,0,0)"><tspan
++ sodipodi:role="line"
++ id="tspan6879"
++ x="44.285629"
++ y="369.12045"
++ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13.4835043px;font-family:sans-serif;-inkscape-font-specification:sans-serif;fill:#b3b3b3;fill-opacity:1">pointing direction</tspan></text>
++ <text
++ xml:space="preserve"
++ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13.4835043px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
++ x="237.00804"
++ y="99.788658"
++ id="text6887"
++ sodipodi:linespacing="125%"><tspan
++ sodipodi:role="line"
++ id="tspan6889"
++ x="237.00804"
++ y="99.788658">y axis</tspan></text>
++ <path
++ style="fill:none;fill-opacity:1;stroke:#cb004e;stroke-width:1.79780054;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend)"
++ id="path7011"
++ sodipodi:type="arc"
++ sodipodi:cx="231.14914"
++ sodipodi:cy="268.54077"
++ sodipodi:rx="79.092262"
++ sodipodi:ry="79.092262"
++ sodipodi:start="4.7157629"
++ sodipodi:end="5.5461565"
++ d="m 231.41599,189.44896 a 79.092262,79.092262 0 0 1 58.2985,25.93463"
++ sodipodi:open="true" />
++ <text
++ xml:space="preserve"
++ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.98900318px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cb004e;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
++ x="232.66777"
++ y="184.40468"
++ id="text7119"
++ sodipodi:linespacing="125%"><tspan
++ sodipodi:role="line"
++ id="tspan7121"
++ x="232.66777"
++ y="184.40468"
++ style="font-size:13.4835043px;fill:#cb004e;fill-opacity:1">orientation</tspan></text>
++ </g>
++</svg>
+diff --git a/doc/touch-event-properties.dox b/doc/touch-event-properties.dox
+new file mode 100644
+index 0000000..bf326f7
+--- /dev/null
++++ b/doc/touch-event-properties.dox
+@@ -0,0 +1,42 @@
++/**
++@page touch_event_properties Properties of a touch event
++
++This page gives some overview on touchscreen events. With libinput touchscreens
++provide the event types @ref LIBINPUT_EVENT_TOUCH_DOWN, @ref LIBINPUT_EVENT_TOUCH_UP,
++@ref LIBINPUT_EVENT_TOUCH_MOTION and @ref LIBINPUT_EVENT_TOUCH_CANCEL. The
++touchscreen events @ref LIBINPUT_EVENT_TOUCH_DOWN and
++@ref LIBINPUT_EVENT_TOUCH_MOTION provide alongside the actual state change and
++the absolute coordinates (@ref absolute_axes_handling) additional information
++about the touch contact.
++
++@image html touchscreen-touch-event-properties.svg "Properties of a touch screen contact"
++
++Assuming the interaction of fingers with a touch screen, touch contacts are
++approximated with an ellipse. The major axis of the ellipse describes the
++pointing direction of the finger. The minor axis is the perpendicular
++extent of the touching shape. The orientation angle is the clockwise rotation of
++the pointing direction against the y-axis of the touchscreen.
++
++Additionally to the values shown in the drawing above, most touchscreens also
++provide a pressure value to indicate the force applied with the contact point.
++
++The support for those contact properties varies between the different
++available touchscreens. In the case of pressure libinput will return the
++maximum pressure value, which is 1.0. If only the major axis but no minor axis
++is present, libinput will assume a circular shape and return the major axis
++value for convenience. If also no major axis value is known 0.0 is returned.
++If the orientation is not available libinput will return 0.0 degrees.
++
++For querying the touch properties see:
++- libinput_event_touch_get_major_transformed()
++- libinput_event_touch_get_minor_transformed()
++- libinput_event_touch_get_orientation()
++- libinput_event_touch_get_pressure()
++
++For testing which of the touch properties are available see:
++- libinput_event_touch_has_major()
++- libinput_event_touch_has_minor()
++- libinput_event_touch_has_orientation()
++- libinput_event_touch_has_pressure()
++
++*/
+diff --git a/src/evdev.c b/src/evdev.c
+index fac8fcb..86a93eb 100644
+--- a/src/evdev.c
++++ b/src/evdev.c
+@@ -49,6 +49,10 @@
+
+ #define DEFAULT_WHEEL_CLICK_ANGLE 15
+ #define DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT ms2us(200)
++#define DEFAULT_TOUCH_PRESSURE 1.0
++#define DEFAULT_TOUCH_ORIENTATION 0.0
++#define DEFAULT_TOUCH_MAJOR 0.0
++#define DEFAULT_TOUCH_MINOR 0.0
+
+ enum evdev_key_type {
+ EVDEV_KEY_TYPE_NONE,
+@@ -321,6 +325,100 @@ evdev_device_transform_y(struct evdev_device *device,
+ return scale_axis(device->abs.absinfo_y, y, height);
+ }
+
++double
++evdev_device_transform_ellipse_diameter_to_mm(struct evdev_device *device,
++ int diameter,
++ double axis_angle)
++{
++ double x_res = device->abs.absinfo_x->resolution;
++ double y_res = device->abs.absinfo_y->resolution;
++
++ if (x_res == y_res)
++ return diameter / x_res;
++
++ /* resolution differs but no orientation available
++ * -> estimate resolution using the average */
++ if (device->abs.absinfo_orientation == NULL) {
++ return diameter * 2.0 / (x_res + y_res);
++ } else {
++ /* Why scale x using sine of angle?
++ * axis_angle = 0 indicates that the given diameter
++ * is aligned with the y-axis. */
++ double x_scaling_ratio = fabs(sin(deg2rad(axis_angle)));
++ double y_scaling_ratio = fabs(cos(deg2rad(axis_angle)));
++
++ return diameter / hypotf(y_res * y_scaling_ratio,
++ x_res * x_scaling_ratio);
++ }
++}
++
++double
++evdev_device_transform_ellipse_diameter(struct evdev_device *device,
++ int diameter,
++ double axis_angle,
++ uint32_t width,
++ uint32_t height)
++{
++ double x_res = device->abs.absinfo_x->resolution;
++ double y_res = device->abs.absinfo_y->resolution;
++ double x_scale = width / (device->abs.dimensions.x + 1.0);
++ double y_scale = height / (device->abs.dimensions.y + 1.0);
++
++ if (x_res == y_res)
++ return diameter * x_scale;
++
++ /* no orientation available -> estimate resolution using the
++ * average */
++ if (device->abs.absinfo_orientation == NULL) {
++ return diameter * (x_scale + y_scale) / 2.0;
++ } else {
++ /* Why scale x using sine of angle?
++ * axis_angle = 0 indicates that the given diameter
++ * is aligned with the y-axis. */
++ double x_scaling_ratio = fabs(sin(deg2rad(axis_angle)));
++ double y_scaling_ratio = fabs(cos(deg2rad(axis_angle)));
++
++ return diameter * (y_scale * y_scaling_ratio +
++ x_scale * x_scaling_ratio);
++ }
++}
++
++double
++evdev_device_transform_orientation(struct evdev_device *device,
++ int32_t orientation)
++{
++ const struct input_absinfo *orientation_info =
++ device->abs.absinfo_orientation;
++
++ double angle = DEFAULT_TOUCH_ORIENTATION;
++
++ /* ABS_MT_ORIENTATION is defined as a clockwise rotation - zero
++ * (instead of minimum) is mapped to the y-axis, and maximum is
++ * mapped to the x-axis. So minimum is likely to be negative but
++ * plays no role in scaling the value to degrees.*/
++ if (orientation_info)
++ angle = (90.0 * orientation) / orientation_info->maximum;
++
++ return fmod(360.0 + angle, 360.0);
++}
++
++double
++evdev_device_transform_pressure(struct evdev_device *device,
++ int32_t pressure)
++{
++ const struct input_absinfo *pressure_info =
++ device->abs.absinfo_pressure;
++
++ if (pressure_info) {
++ double max_pressure = pressure_info->maximum;
++ double min_pressure = pressure_info->minimum;
++ return (pressure - min_pressure) /
++ (max_pressure - min_pressure);
++ } else {
++ return DEFAULT_TOUCH_PRESSURE;
++ }
++}
++
+ static inline void
+ normalize_delta(struct evdev_device *device,
+ const struct device_coords *delta,
+@@ -462,6 +560,7 @@ fallback_flush_mt_down(struct fallback_dispatch *dispatch,
+ struct libinput_seat *seat = base->seat;
+ struct device_coords point;
+ struct mt_slot *slot;
++
+ int seat_slot;
+
+ if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
+@@ -490,7 +589,8 @@ fallback_flush_mt_down(struct fallback_dispatch *dispatch,
+ evdev_transform_absolute(device, &point);
+
+ touch_notify_touch_down(base, time, slot_idx, seat_slot,
+- &point);
++ &point, &slot->area, slot->pressure);
++
+
+ return true;
+ }
+@@ -521,7 +621,7 @@ fallback_flush_mt_motion(struct fallback_dispatch *dispatch,
+
+ evdev_transform_absolute(device, &point);
+ touch_notify_touch_motion(base, time, slot_idx, seat_slot,
+- &point);
++ &point, &slot->area, slot->pressure);
+
+ return true;
+ }
+@@ -562,6 +662,11 @@ fallback_flush_st_down(struct fallback_dispatch *dispatch,
+ struct libinput_device *base = &device->base;
+ struct libinput_seat *seat = base->seat;
+ struct device_coords point;
++ struct ellipse default_area = {
++ .major = DEFAULT_TOUCH_MAJOR,
++ .minor = DEFAULT_TOUCH_MINOR,
++ .orientation = DEFAULT_TOUCH_ORIENTATION,
++ };
+ int seat_slot;
+
+ if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
+@@ -588,7 +693,8 @@ fallback_flush_st_down(struct fallback_dispatch *dispatch,
+ point = dispatch->abs.point;
+ evdev_transform_absolute(device, &point);
+
+- touch_notify_touch_down(base, time, -1, seat_slot, &point);
++ touch_notify_touch_down(base, time, -1, seat_slot, &point,
++ &default_area, DEFAULT_TOUCH_PRESSURE);
+
+ return true;
+ }
+@@ -600,6 +706,11 @@ fallback_flush_st_motion(struct fallback_dispatch *dispatch,
+ {
+ struct libinput_device *base = &device->base;
+ struct device_coords point;
++ struct ellipse default_area = {
++ .major = DEFAULT_TOUCH_MAJOR,
++ .minor = DEFAULT_TOUCH_MINOR,
++ .orientation = DEFAULT_TOUCH_ORIENTATION,
++ };
+ int seat_slot;
+
+ point = dispatch->abs.point;
+@@ -610,7 +721,8 @@ fallback_flush_st_motion(struct fallback_dispatch *dispatch,
+ if (seat_slot == -1)
+ return false;
+
+- touch_notify_touch_motion(base, time, -1, seat_slot, &point);
++ touch_notify_touch_motion(base, time, -1, seat_slot, &point,
++ &default_area, DEFAULT_TOUCH_PRESSURE);
+
+ return true;
+ }
+@@ -829,6 +941,9 @@ fallback_process_touch(struct fallback_dispatch *dispatch,
+ struct input_event *e,
+ uint64_t time)
+ {
++ struct mt_slot *current_slot = &dispatch->mt.slots[dispatch->mt.slot];
++ int pending_event = EVDEV_NONE;
++
+ switch (e->code) {
+ case ABS_MT_SLOT:
+ if ((size_t)e->value >= dispatch->mt.slots_len) {
+@@ -858,10 +973,28 @@ fallback_process_touch(struct fallback_dispatch *dispatch,
+ break;
+ case ABS_MT_POSITION_Y:
+ dispatch->mt.slots[dispatch->mt.slot].point.y = e->value;
+- if (dispatch->pending_event == EVDEV_NONE)
+- dispatch->pending_event = EVDEV_ABSOLUTE_MT_MOTION;
++ pending_event = EVDEV_ABSOLUTE_MT_MOTION;
++ break;
++ case ABS_MT_TOUCH_MAJOR:
++ current_slot->area.major = e->value;
++ pending_event = EVDEV_ABSOLUTE_MT_MOTION;
++ break;
++ case ABS_MT_TOUCH_MINOR:
++ current_slot->area.minor = e->value;
++ pending_event = EVDEV_ABSOLUTE_MT_MOTION;
++ break;
++ case ABS_MT_ORIENTATION:
++ current_slot->area.orientation = e->value;
++ pending_event = EVDEV_ABSOLUTE_MT_MOTION;
++ break;
++ case ABS_MT_PRESSURE:
++ current_slot->pressure = e->value;
++ pending_event = EVDEV_ABSOLUTE_MT_MOTION;
+ break;
+ }
++
++ if (dispatch->pending_event == EVDEV_NONE && pending_event != EVDEV_NONE)
++ dispatch->pending_event = pending_event;;
+ }
+ static inline void
+ fallback_process_absolute_motion(struct fallback_dispatch *dispatch,
+@@ -1684,6 +1817,21 @@ fallback_dispatch_init_slots(struct fallback_dispatch *dispatch,
+ slots[slot].point.y = libevdev_get_slot_value(evdev,
+ slot,
+ ABS_MT_POSITION_Y);
++ slots[slot].area.major =
++ libevdev_get_slot_value(evdev,
++ slot,
++ ABS_MT_TOUCH_MAJOR);
++ slots[slot].area.minor =
++ libevdev_get_slot_value(evdev,
++ slot,
++ ABS_MT_TOUCH_MINOR);
++ slots[slot].area.orientation =
++ libevdev_get_slot_value(evdev,
++ slot,
++ ABS_MT_ORIENTATION);
++ slots[slot].pressure =
++ libevdev_get_slot_value(evdev, slot, ABS_MT_PRESSURE);
++
+ }
+ dispatch->mt.slots = slots;
+ dispatch->mt.slots_len = num_slots;
+@@ -2518,6 +2666,15 @@ evdev_configure_device(struct evdev_device *device)
+ return NULL;
+ }
+
++ device->abs.absinfo_orientation =
++ libevdev_get_abs_info(evdev, ABS_MT_ORIENTATION);
++ device->abs.absinfo_pressure =
++ libevdev_get_abs_info(evdev, ABS_MT_PRESSURE);
++ device->abs.absinfo_major =
++ libevdev_get_abs_info(evdev, ABS_MT_TOUCH_MAJOR);
++ device->abs.absinfo_minor =
++ libevdev_get_abs_info(evdev, ABS_MT_TOUCH_MINOR);
++
+ if (!evdev_is_fake_mt_device(device))
+ evdev_fix_android_mt(device);
+
+diff --git a/src/evdev.h b/src/evdev.h
+index b811f51..51521de 100644
+--- a/src/evdev.h
++++ b/src/evdev.h
+@@ -127,6 +127,8 @@ struct mt_slot {
+ int32_t seat_slot;
+ struct device_coords point;
+ struct device_coords hysteresis_center;
++ struct ellipse area;
++ int32_t pressure;
+ };
+
+ struct evdev_device {
+@@ -153,6 +155,8 @@ struct evdev_device {
+
+ struct {
+ const struct input_absinfo *absinfo_x, *absinfo_y;
++ const struct input_absinfo *absinfo_major, *absinfo_minor,
++ *absinfo_pressure, *absinfo_orientation;
+ bool is_fake_resolution;
+
+ int apply_calibration;
+@@ -432,6 +436,27 @@ double
+ evdev_device_transform_y(struct evdev_device *device,
+ double y,
+ uint32_t height);
++
++double
++evdev_device_transform_ellipse_diameter_to_mm(struct evdev_device *device,
++ int32_t diameter,
++ double axis_angle);
++
++double
++evdev_device_transform_ellipse_diameter(struct evdev_device *device,
++ int32_t diameter,
++ double axis_angle,
++ uint32_t width,
++ uint32_t height);
++
++double
++evdev_device_transform_orientation(struct evdev_device *device,
++ int32_t orientation);
++
++double
++evdev_device_transform_pressure(struct evdev_device *device,
++ int32_t pressure);
++
+ void
+ evdev_device_suspend(struct evdev_device *device);
+
+diff --git a/src/libinput-private.h b/src/libinput-private.h
+index 52f129a..d259b8b 100644
+--- a/src/libinput-private.h
++++ b/src/libinput-private.h
+@@ -48,6 +48,11 @@ struct device_coords {
+ int x, y;
+ };
+
++/* Ellipse parameters in device coordinates */
++struct ellipse {
++ int major, minor, orientation;
++};
++
+ /*
+ * A coordinate pair in device coordinates, capable of holding non discrete
+ * values, this is necessary e.g. when device coordinates get averaged.
+@@ -514,14 +519,18 @@ touch_notify_touch_down(struct libinput_device *device,
+ uint64_t time,
+ int32_t slot,
+ int32_t seat_slot,
+- const struct device_coords *point);
++ const struct device_coords *point,
++ const struct ellipse *area,
++ int32_t pressure);
+
+ void
+ touch_notify_touch_motion(struct libinput_device *device,
+ uint64_t time,
+ int32_t slot,
+ int32_t seat_slot,
+- const struct device_coords *point);
++ const struct device_coords *point,
++ const struct ellipse *area,
++ int32_t pressure);
+
+ void
+ touch_notify_touch_up(struct libinput_device *device,
+diff --git a/src/libinput.c b/src/libinput.c
+index 1e97ad1..f3df972 100644
+--- a/src/libinput.c
++++ b/src/libinput.c
+@@ -112,6 +112,8 @@ struct libinput_event_touch {
+ int32_t slot;
+ int32_t seat_slot;
+ struct device_coords point;
Reply to: