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

libinput: Changes to 'ubuntu'



 debian/changelog                                  |   10 
 debian/libinput10.symbols                         |   11 
 debian/patches/fix-litest.patch                   |   44 
 debian/patches/series                             |    2 
 debian/patches/touch-point-orientation-size.patch | 1675 ++++++++++++++++++++++
 5 files changed, 1742 insertions(+)

New commits:
commit 28c3fd8ff064ee5ec7f2f2644e5a493c7d91add4
Author: Robert Ancell <robert.ancell@canonical.com>
Date:   Mon Aug 24 15:56:17 2015 +0100

    * debian/patches/touch-point-orientation-size.patch:
    * debian/patches/fix-litest.patch:
      - Add support for touchscreen contact properties (LP: #1488064)
    * debian/libinput10.symbols:
      - Updated

diff --git a/debian/changelog b/debian/changelog
index 6f96377..8159edb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
+libinput (0.21.0-1ubuntu1) wily; urgency=medium
+
+  * debian/patches/touch-point-orientation-size.patch:
+  * debian/patches/fix-litest.patch:
+    - Add support for touchscreen contact properties (LP: #1488064)
+  * debian/libinput10.symbols:
+    - Updated
+
+ -- Robert Ancell <robert.ancell@canonical.com>  Mon, 24 Aug 2015 13:13:32 +0100
+
 libinput (0.21.0-1) unstable; urgency=medium
 
   * New upstream release.
diff --git a/debian/libinput10.symbols b/debian/libinput10.symbols
index 406f01e..eb427b6 100644
--- a/debian/libinput10.symbols
+++ b/debian/libinput10.symbols
@@ -6,6 +6,7 @@ libinput.so.10 libinput10 #MINVER#
  LIBINPUT_0.19.0@LIBINPUT_0.19.0 0.21.0
  LIBINPUT_0.20.0@LIBINPUT_0.20.0 0.21.0
  LIBINPUT_0.21.0@LIBINPUT_0.21.0 0.21.0
+ LIBINPUT_0.22.0@LIBINPUT_0.22.0 0.21.0-1ubuntu1
  libinput_config_status_to_str@LIBINPUT_0.12.0 0.15.0
  libinput_device_config_accel_get_default_speed@LIBINPUT_0.12.0 0.15.0
  libinput_device_config_accel_get_speed@LIBINPUT_0.12.0 0.15.0
@@ -123,6 +124,12 @@ libinput.so.10 libinput10 #MINVER#
  libinput_event_pointer_get_time_usec@LIBINPUT_0.21.0 0.21.0
  libinput_event_pointer_has_axis@LIBINPUT_0.12.0 0.15.0
  libinput_event_touch_get_base_event@LIBINPUT_0.12.0 0.15.0
+ libinput_event_touch_get_major@LIBINPUT_0.22.0 0.21.0-1ubuntu1
+ libinput_event_touch_get_major_transformed@LIBINPUT_0.22.0 0.21.0-1ubuntu1
+ libinput_event_touch_get_minor@LIBINPUT_0.22.0 0.21.0-1ubuntu1
+ libinput_event_touch_get_minor_transformed@LIBINPUT_0.22.0 0.21.0-1ubuntu1
+ libinput_event_touch_get_orientation@LIBINPUT_0.22.0 0.21.0-1ubuntu1
+ libinput_event_touch_get_pressure@LIBINPUT_0.22.0 0.21.0-1ubuntu1
  libinput_event_touch_get_seat_slot@LIBINPUT_0.12.0 0.15.0
  libinput_event_touch_get_slot@LIBINPUT_0.12.0 0.15.0
  libinput_event_touch_get_time@LIBINPUT_0.12.0 0.15.0
@@ -131,6 +138,10 @@ libinput.so.10 libinput10 #MINVER#
  libinput_event_touch_get_x_transformed@LIBINPUT_0.12.0 0.15.0
  libinput_event_touch_get_y@LIBINPUT_0.12.0 0.15.0
  libinput_event_touch_get_y_transformed@LIBINPUT_0.12.0 0.15.0
+ libinput_event_touch_has_major@LIBINPUT_0.22.0 0.21.0-1ubuntu1
+ libinput_event_touch_has_minor@LIBINPUT_0.22.0 0.21.0-1ubuntu1
+ libinput_event_touch_has_orientation@LIBINPUT_0.22.0 0.21.0-1ubuntu1
+ libinput_event_touch_has_pressure@LIBINPUT_0.22.0 0.21.0-1ubuntu1
  libinput_get_event@LIBINPUT_0.12.0 0.15.0
  libinput_get_fd@LIBINPUT_0.12.0 0.15.0
  libinput_get_user_data@LIBINPUT_0.12.0 0.15.0
diff --git a/debian/patches/fix-litest.patch b/debian/patches/fix-litest.patch
new file mode 100644
index 0000000..e476d8d
--- /dev/null
+++ b/debian/patches/fix-litest.patch
@@ -0,0 +1,44 @@
+With this change auto assign events will be skipped if no replacement value
+is provided. This behavior is practical when emitting mt events, as those
+only contain the axis values that changed.
+
+Signed-off-by: Andreas Pokorny <andreas.pokorny at canonical.com>
+---
+ test/litest.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/test/litest.c b/test/litest.c
+index 26c5e43..8fc7bca 100644
+--- a/test/litest.c
++++ b/test/litest.c
+@@ -1292,7 +1292,6 @@ litest_auto_assign_value(struct litest_device *d,
+ 		value = touching ? 0 : 1;
+ 		break;
+ 	default:
+-		value = -1;
+ 		if (!axis_replacement_value(axes, ev->code, &value) &&
+ 		    d->interface->get_axis_default)
+ 			d->interface->get_axis_default(d, ev->code, &value);
+@@ -1342,8 +1341,8 @@ litest_slot_start(struct litest_device *d,
+ 						     y,
+ 						     axes,
+ 						     touching);
+-
+-		litest_event(d, ev->type, ev->code, value);
++		if (value != LITEST_AUTO_ASSIGN)
++			litest_event(d, ev->type, ev->code, value);
+ 		ev++;
+ 	}
+ }
+@@ -1428,7 +1427,8 @@ litest_slot_move(struct litest_device *d,
+ 						     y,
+ 						     axes,
+ 						     touching);
+-		litest_event(d, ev->type, ev->code, value);
++		if (value != LITEST_AUTO_ASSIGN)
++			litest_event(d, ev->type, ev->code, value);
+ 		ev++;
+ 	}
+ }
+-- 
+2.1.4
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..cc360d0
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,2 @@
+fix-litest.patch
+touch-point-orientation-size.patch
diff --git a/debian/patches/touch-point-orientation-size.patch b/debian/patches/touch-point-orientation-size.patch
new file mode 100644
index 0000000..24505a6
--- /dev/null
+++ b/debian/patches/touch-point-orientation-size.patch
@@ -0,0 +1,1675 @@
+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 querried 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 at 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                                    | 218 ++++++++++++++--
+ src/evdev.h                                    |  25 ++
+ src/libinput-private.h                         |  25 +-
+ src/libinput-util.h                            |   6 +
+ src/libinput.c                                 | 205 ++++++++++++++-
+ src/libinput.h                                 | 222 ++++++++++++++++
+ src/libinput.sym                               |  13 +
+ test/touch.c                                   | 239 +++++++++++++++++
+ 12 files changed, 1313 insertions(+), 32 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 a8d4182..da21283 100644
+--- a/doc/Makefile.am
++++ b/doc/Makefile.am
+@@ -26,6 +26,7 @@ header_files = \
+ 	$(srcdir)/tapping.dox \
+ 	$(srcdir)/test-suite.dox \
+ 	$(srcdir)/tools.dox \
++	$(srcdir)/touch-event-properties.dox \
+ 	$(srcdir)/touchpads.dox
+ 
+ diagram_files = \
+@@ -49,6 +50,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 3fdb1f7..72765e2 100644
+--- a/doc/page-hierarchy.dox
++++ b/doc/page-hierarchy.dox
+@@ -11,6 +11,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..75fc072
+--- /dev/null
++++ b/doc/touch-event-properties.dox
+@@ -0,0 +1,42 @@
++/**
++ at 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,
++ at ref LIBINPUT_EVENT_TOUCH_MOTION and @ref LIBINPUT_EVENT_TOUCH_CANCEL. The
++touchscreen events @ref LIBINPUT_EVENT_TOUCH_DOWN and
++ at 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.
++
++ at 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:
++- @ref libinput_event_touch_get_major_transformed
++- @ref libinput_event_touch_get_minor_transformed
++- @ref libinput_event_touch_get_orientation
++- @ref libinput_event_touch_get_pressure
++
++For testing which of the touch properties are available see:
++- @ref libinput_event_touch_has_major
++- @ref libinput_event_touch_has_minor
++- @ref libinput_event_touch_has_orientation
++- @ref libinput_event_touch_has_pressure
++
++*/
+diff --git a/src/evdev.c b/src/evdev.c
+index 303e447..29303f8 100644
+--- a/src/evdev.c
++++ b/src/evdev.c
+@@ -45,6 +45,10 @@
+ 
+ #define DEFAULT_WHEEL_CLICK_ANGLE 15
+ #define DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT ms2us(200)
++#define DEFAULT_TOUCH_PRESSURE 1
++#define DEFAULT_TOUCH_ORIENTATION 0
++#define DEFAULT_TOUCH_MAJOR 0
++#define DEFAULT_TOUCH_MINOR 0
+ 
+ enum evdev_key_type {
+ 	EVDEV_KEY_TYPE_NONE,
+@@ -245,6 +249,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 / (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,
+@@ -282,8 +380,15 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
+ 	struct normalized_coords accel, unaccel;
+ 	struct device_coords point;
+ 	struct device_float_coords raw;
++	struct mt_slot *slot_data;
++	struct ellipse default_touch = {
++		.major = DEFAULT_TOUCH_MAJOR,
++		.minor = DEFAULT_TOUCH_MINOR,
++		.orientation = DEFAULT_TOUCH_ORIENTATION
++	};
+ 
+ 	slot = device->mt.slot;
++	slot_data = &device->mt.slots[slot];
+ 
+ 	switch (device->pending_event) {
+ 	case EVDEV_NONE:
+@@ -314,7 +419,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
+ 		if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
+ 			break;
+ 
+-		if (device->mt.slots[slot].seat_slot != -1) {
++		if (slot_data->seat_slot != -1) {
+ 			log_bug_kernel(libinput,
+ 				       "%s: Driver sent multiple touch down for the "
+ 				       "same slot",
+@@ -323,38 +428,52 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
+ 		}
+ 
+ 		seat_slot = ffs(~seat->slot_map) - 1;
+-		device->mt.slots[slot].seat_slot = seat_slot;
++		slot_data->seat_slot = seat_slot;
+ 
+ 		if (seat_slot == -1)
+ 			break;
+ 
+ 		seat->slot_map |= 1 << seat_slot;
+-		point = device->mt.slots[slot].point;
++		point = slot_data->point;
+ 		transform_absolute(device, &point);
+ 
+-		touch_notify_touch_down(base, time, slot, seat_slot,
+-					&point);
++		touch_notify_touch_down(base,
++					time,
++					slot,
++					seat_slot,
++					&point,
++					slot_data->available_data,
++					&slot_data->area,
++					slot_data->pressure);
+ 		break;
+ 	case EVDEV_ABSOLUTE_MT_MOTION:
+ 		if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
+ 			break;
+ 
+-		seat_slot = device->mt.slots[slot].seat_slot;
+-		point = device->mt.slots[slot].point;
++		seat_slot = slot_data->seat_slot;
++
++		point = slot_data->point;
+ 
+ 		if (seat_slot == -1)
+ 			break;
+ 
+ 		transform_absolute(device, &point);
+-		touch_notify_touch_motion(base, time, slot, seat_slot,
+-					  &point);
++
++		touch_notify_touch_motion(base,
++					  time,
++					  slot,
++					  seat_slot,
++					  &point,
++					  slot_data->available_data,
++					  &slot_data->area,
++					  slot_data->pressure);
+ 		break;
+ 	case EVDEV_ABSOLUTE_MT_UP:
+ 		if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
+ 			break;
+ 
+-		seat_slot = device->mt.slots[slot].seat_slot;
+-		device->mt.slots[slot].seat_slot = -1;
++		seat_slot = slot_data->seat_slot;
++		slot_data->seat_slot = -1;
+ 
+ 		if (seat_slot == -1)
+ 			break;
+@@ -386,7 +505,14 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
+ 		point = device->abs.point;
+ 		transform_absolute(device, &point);
+ 
+-		touch_notify_touch_down(base, time, -1, seat_slot, &point);
++		touch_notify_touch_down(base,
++					time,
++					-1,
++					seat_slot,
++					&point,
++					TOUCH_SLOT_DATA_NONE,
++					&default_touch,
++					DEFAULT_TOUCH_PRESSURE);
+ 		break;
+ 	case EVDEV_ABSOLUTE_MOTION:
+ 		point = device->abs.point;
+@@ -398,8 +524,14 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
+ 			if (seat_slot == -1)
+ 				break;
+ 
+-			touch_notify_touch_motion(base, time, -1, seat_slot,
+-						  &point);
++			touch_notify_touch_motion(base,
++						  time,
++						  -1,
++						  seat_slot,
++						  &point,
++						  TOUCH_SLOT_DATA_NONE,
++						  &default_touch,
++						  DEFAULT_TOUCH_PRESSURE);
+ 		} else if (device->seat_caps & EVDEV_DEVICE_POINTER) {
+ 			pointer_notify_motion_absolute(base, time, &point);
+ 		}
+@@ -559,8 +691,9 @@ evdev_process_touch(struct evdev_device *device,
+ 		    struct input_event *e,
+ 		    uint64_t time)
+ {
+-	switch (e->code) {
+-	case ABS_MT_SLOT:
++	struct mt_slot *current_slot = &device->mt.slots[device->mt.slot];
++
++	if (e->code == ABS_MT_SLOT) {
+ 		if ((size_t)e->value >= device->mt.slots_len) {
+ 			log_bug_libinput(device->base.seat->libinput,
+ 					 "%s exceeds slots (%d of %zd)\n",
+@@ -571,8 +704,7 @@ evdev_process_touch(struct evdev_device *device,
+ 		}
+ 		evdev_flush_pending_event(device, time);
+ 		device->mt.slot = e->value;
+-		break;
+-	case ABS_MT_TRACKING_ID:
++	} else if(e->code == ABS_MT_TRACKING_ID) {
+ 		if (device->pending_event != EVDEV_NONE &&
+ 		    device->pending_event != EVDEV_ABSOLUTE_MT_MOTION)
+ 			evdev_flush_pending_event(device, time);
+@@ -580,17 +712,40 @@ evdev_process_touch(struct evdev_device *device,
+ 			device->pending_event = EVDEV_ABSOLUTE_MT_DOWN;
+ 		else
+ 			device->pending_event = EVDEV_ABSOLUTE_MT_UP;
+-		break;
+-	case ABS_MT_POSITION_X:
+-		device->mt.slots[device->mt.slot].point.x = e->value;
+-		if (device->pending_event == EVDEV_NONE)
+-			device->pending_event = EVDEV_ABSOLUTE_MT_MOTION;
+-		break;
+-	case ABS_MT_POSITION_Y:
+-		device->mt.slots[device->mt.slot].point.y = e->value;
+-		if (device->pending_event == EVDEV_NONE)
++	} else {
++		bool needs_wake = true;
++
++		switch(e->code) {
++		case ABS_MT_POSITION_X:
++			current_slot->point.x = e->value;
++			break;
++		case ABS_MT_POSITION_Y:
++			current_slot->point.y = e->value;
++			break;
++		case ABS_MT_TOUCH_MAJOR:
++			current_slot->available_data |= TOUCH_SLOT_DATA_MAJOR;
++			current_slot->area.major = e->value;
++			break;
++		case ABS_MT_TOUCH_MINOR:
++			current_slot->available_data |= TOUCH_SLOT_DATA_MINOR;
++			current_slot->area.minor = e->value;
++			break;
++		case ABS_MT_ORIENTATION:
++			current_slot->available_data |=
++						TOUCH_SLOT_DATA_ORIENTATION;
++			current_slot->area.orientation = e->value;
++			break;
++		case ABS_MT_PRESSURE:
++			current_slot->available_data |=
++						TOUCH_SLOT_DATA_PRESSURE;
++			current_slot->pressure = e->value;
++			break;
++		default:
++			needs_wake = false;
++			break;
++		}
++		if (needs_wake && device->pending_event == EVDEV_NONE)
+ 			device->pending_event = EVDEV_ABSOLUTE_MT_MOTION;
+-		break;
+ 	}
+ }
+ 
+@@ -1941,6 +2096,13 @@ evdev_configure_device(struct evdev_device *device)
+ 		return -1;
+ 	}
+ 
++	device->abs.absinfo_orientation =
++		libevdev_get_abs_info(evdev,
++				      ABS_MT_ORIENTATION);
++	device->abs.absinfo_pressure =
++		libevdev_get_abs_info(evdev,
++				      ABS_MT_PRESSURE);
++
+ 	if (!evdev_is_fake_mt_device(device))
+ 		evdev_fix_android_mt(device);
+ 
+diff --git a/src/evdev.h b/src/evdev.h
+index e44a65d..383e682 100644
+--- a/src/evdev.h
++++ b/src/evdev.h
+@@ -112,6 +112,9 @@ enum evdev_device_model {
+ struct mt_slot {
+ 	int32_t seat_slot;
+ 	struct device_coords point;
++	enum touch_slot_data available_data;
++	struct ellipse area;
++	int32_t pressure;
+ };
+ 
+ struct evdev_device {
+@@ -128,6 +131,8 @@ struct evdev_device {
+ 	int fd;
+ 	struct {
+ 		const struct input_absinfo *absinfo_x, *absinfo_y;
++		const struct input_absinfo *absinfo_pressure,
++					   *absinfo_orientation;
+ 		int fake_resolution;
+ 
+ 		struct device_coords point;
+@@ -349,6 +354,26 @@ 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);
++
+ int
+ evdev_device_suspend(struct evdev_device *device);
+ 
+diff --git a/src/libinput-private.h b/src/libinput-private.h
+index 8b161cc..0060030 100644
+--- a/src/libinput-private.h
++++ b/src/libinput-private.h
+@@ -40,6 +40,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.
+@@ -58,6 +63,16 @@ struct discrete_coords {
+ 	int x, y;
+ };
+ 
++enum touch_slot_data {
++	TOUCH_SLOT_DATA_NONE = 0,
++	TOUCH_SLOT_DATA_MAJOR = (1 << 1),
++	TOUCH_SLOT_DATA_MINOR = (1 << 2),
++	TOUCH_SLOT_DATA_ORIENTATION = (1 << 3),
++	TOUCH_SLOT_DATA_PRESSURE = (1 << 4),


Reply to: