[PATCH v2 libinput] touchpad: Route top softbuttons through the trackstick if we've one

Peter Hutterer peter.hutterer at who-t.net
Wed Sep 17 20:17:55 PDT 2014


From: Hans de Goede <hdegoede at redhat.com>

The touchpad top softbuttons such as found on the Lenove T440 are intended for
use with the trackstick. Route their events through the trackstick, so that
they can be used for e.g. middle button scrolling with the trackstick.

Note that sending top button events to a disabled trackpoint makes no sense
(and will mess up internal state). Likely a user with a disabled trackpoint
will still expect the top buttons to work, so rather than not sending events
in that case, simply treat a suspendeded trackpoint as not being there, and
send the events directly from the touchpad device.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
Changes to v1:
- rename is_top and active_is_top to *is_topbutton for better clarity
- add timestamp to struct input_event generation 
- replace two commas with semicolons (typos)
- change active_is_topbutton to a bool (from unsigned int)

 doc/touchpad-softbutton-state-machine.svg | 198 +++++++++++++++++-------------
 src/evdev-mt-touchpad-buttons.c           |  47 +++++--
 src/evdev-mt-touchpad.c                   |  17 ++-
 src/evdev-mt-touchpad.h                   |   1 +
 4 files changed, 164 insertions(+), 99 deletions(-)

diff --git a/doc/touchpad-softbutton-state-machine.svg b/doc/touchpad-softbutton-state-machine.svg
index 1d569bf..ffa17a2 100644
--- a/doc/touchpad-softbutton-state-machine.svg
+++ b/doc/touchpad-softbutton-state-machine.svg
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="2190px" height="1624px" version="1.1">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="2180px" height="1624px" version="1.1">
   <defs/>
   <g transform="translate(0.5,0.5)">
     <path d="M 862 441 L 894 441" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
@@ -68,13 +68,13 @@
     <path d="M 712 441 L 668 441 Q 658 441 658 451 L 658 762" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 786 62 L 786 81 Q 786 91 786 101 L 786 114" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 786 120 L 783 113 L 786 114 L 790 113 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-    <rect x="1753" y="472" width="120" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+    <rect x="1753" y="412" width="120" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-      <text x="1813" y="489">Check state of</text>
-      <text x="1813" y="503">all touches</text>
+      <text x="1813" y="429">Check state of</text>
+      <text x="1813" y="443">all touches</text>
     </g>
-    <path d="M 1813 512 L 1813 518 Q 1813 524 1813 529 L 1813 534" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1809 526 L 1813 535 L 1818 526" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1813 452 L 1813 458 Q 1813 465 1813 470 L 1813 475" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1809 467 L 1813 476 L 1818 467" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <ellipse cx="1813" cy="72" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
     <path d="M 1813 87 L 1813 115 Q 1813 125 1813 135 L 1813 160" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 1809 152 L 1813 161 L 1818 152" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
@@ -82,88 +82,89 @@
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
       <text x="1813" y="41">tp_post_softbutton_buttons()</text>
     </g>
-    <path d="M 1813 212 L 1908 267 L 1813 322 L 1718 267 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1813 192 L 1908 247 L 1813 302 L 1718 247 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-      <text x="1813" y="264">!buttons.click_pend</text>
-      <text x="1813" y="278">&& current == old</text>
+      <text x="1813" y="244">!buttons.click_pend</text>
+      <text x="1813" y="258">&& current == old</text>
     </g>
-    <path d="M 1908 267 L 1968 267 Q 1978 267 1988 267 L 2056 267" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 2048 272 L 2057 267 L 2048 263" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1908 247 L 1968 247 Q 1978 247 1988 247 L 2056 247" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 2048 252 L 2057 247 L 2048 243" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" font-size="11px">
-      <rect fill="#ffffff" stroke="none" x="1998" y="252" width="18" height="14" stroke-width="0"/>
-      <text x="1999" y="261">yes</text>
+      <rect fill="#ffffff" stroke="none" x="1998" y="228" width="24" height="18" stroke-width="0"/>
+      <text x="1999" y="241">yes</text>
     </g>
-    <path d="M 1813 322 L 1813 332 Q 1813 342 1813 351 L 1813 360" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1809 352 L 1813 361 L 1818 352" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1813 302 L 1813 307 Q 1813 313 1813 317 L 1813 321" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1809 313 L 1813 322 L 1818 313" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" font-size="11px">
-      <rect fill="#ffffff" stroke="none" x="1815" y="330" width="15" height="14" stroke-width="0"/>
-      <text x="1815" y="339">no</text>
+      <rect fill="#ffffff" stroke="none" x="1830" y="310" width="18" height="18" stroke-width="0"/>
+      <text x="1830" y="319">no</text>
     </g>
-    <ellipse cx="2073" cy="267" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
-    <ellipse cx="2073" cy="267" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
-    <rect x="1708" y="112" width="200" height="60" rx="24" ry="24" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+    <ellipse cx="2073" cy="247" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
+    <ellipse cx="2073" cy="247" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
+    <rect x="1713" y="102" width="200" height="70" rx="28" ry="28" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-      <text x="1808" y="132">current = buttons.state & 0x01</text>
-      <text x="1808" y="146">old = buttons.old_state & 0x01</text>
-      <text x="1808" y="160">button = 0</text>
+      <text x="1813" y="120">current = buttons.state & 0x01</text>
+      <text x="1813" y="134">old = buttons.old_state & 0x01</text>
+      <text x="1813" y="148">button = 0</text>
+      <text x="1813" y="162">is_top = 0</text>
     </g>
-    <path d="M 1813 172 L 1813 182 Q 1813 192 1813 201 L 1813 210" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1809 202 L 1813 211 L 1818 202" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1813 536 L 1928 607 L 1813 678 L 1698 607 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1813 172 L 1813 177 Q 1813 182 1813 186 L 1813 190" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1809 182 L 1813 191 L 1818 182" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1813 568 L 1918 626 L 1813 684 L 1708 626 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-      <text x="1813" y="611">All touches are in state none</text>
+      <text x="1813" y="630">All touches are in state none</text>
     </g>
-    <path d="M 1813 678 L 1813 684 Q 1813 690 1813 695 L 1813 700" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1809 692 L 1813 701 L 1818 692" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1813 684 L 1813 691 Q 1813 697 1813 702 L 1813 708" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1809 700 L 1813 709 L 1818 700" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" font-size="11px">
-      <rect fill="#ffffff" stroke="none" x="1820" y="687" width="15" height="14" stroke-width="0"/>
-      <text x="1820" y="696">no</text>
+      <rect fill="#ffffff" stroke="none" x="1820" y="691" width="18" height="18" stroke-width="0"/>
+      <text x="1820" y="704">no</text>
     </g>
-    <path d="M 1928 607 L 1938 607 Q 1948 607 1957 607 L 1966 607" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1958 612 L 1967 607 L 1958 603" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1918 626 L 1936 626 Q 1946 626 1955 626 L 1971 626" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1963 631 L 1972 626 L 1963 622" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" font-size="11px">
-      <rect fill="#ffffff" stroke="none" x="1930" y="615" width="18" height="14" stroke-width="0"/>
-      <text x="1930" y="624">yes</text>
+      <rect fill="#ffffff" stroke="none" x="1920" y="634" width="24" height="18" stroke-width="0"/>
+      <text x="1920" y="643">yes</text>
     </g>
-    <rect x="1968" y="587" width="150" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+    <rect x="1973" y="606" width="150" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-      <text x="2043" y="611">buttons.click_pend = 1</text>
+      <text x="2048" y="630">buttons.click_pend = 1</text>
     </g>
-    <path d="M 2118 607 L 2128 607 Q 2138 607 2147 607 L 2156 607" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 2148 612 L 2157 607 L 2148 603" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1813 702 L 1938 787 L 1813 872 L 1688 787 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 2123 626 L 2128 626 Q 2133 626 2137 626 L 2141 626" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 2133 631 L 2142 626 L 2133 622" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1813 710 L 1938 795 L 1813 880 L 1688 795 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-      <text x="1813" y="777">(Some touches are in middle) ||</text>
-      <text x="1813" y="791">((Some touches are in right) &&</text>
-      <text x="1813" y="805">(Some touches are in left))</text>
+      <text x="1813" y="785">(Some touches are in middle) ||</text>
+      <text x="1813" y="799">((Some touches are in right) &&</text>
+      <text x="1813" y="813">(Some touches are in left))</text>
     </g>
-    <path d="M 1938 787 L 1943 787 Q 1948 787 1957 787 L 1966 787" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1958 792 L 1967 787 L 1958 783" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1938 795 L 1943 795 Q 1948 795 1957 795 L 1966 795" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1958 800 L 1967 795 L 1958 791" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" font-size="11px">
-      <rect fill="#ffffff" stroke="none" x="1941" y="795" width="18" height="14" stroke-width="0"/>
-      <text x="1942" y="804">yes</text>
+      <rect fill="#ffffff" stroke="none" x="1941" y="803" width="24" height="18" stroke-width="0"/>
+      <text x="1942" y="812">yes</text>
     </g>
-    <rect x="1968" y="767" width="160" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+    <rect x="1968" y="775" width="160" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-      <text x="2048" y="791">button = BTN_MIDDLE</text>
+      <text x="2048" y="799">button = BTN_MIDDLE</text>
     </g>
-    <path d="M 2128 787 L 2158 787 Q 2168 787 2168 797 L 2168 1207 Q 2168 1217 2158 1217 L 1913 1217" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1921 1213 L 1912 1217 L 1921 1222" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1813 362 L 1876 396 L 1813 431 L 1751 396 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 2128 795 L 2158 795 Q 2168 795 2168 805 L 2168 1197 Q 2168 1207 2158 1207 L 1913 1207" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1921 1203 L 1912 1207 L 1921 1212" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1813 323 L 1876 357 L 1813 392 L 1751 357 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-      <text x="1813" y="400">current</text>
+      <text x="1813" y="361">current</text>
     </g>
-    <path d="M 1751 396 L 1601 396 Q 1591 396 1591 406 L 1591 1172 Q 1591 1182 1591 1182 L 1592 1182" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1596 1180 L 1591 1182 L 1596 1184" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1751 357 L 1606 357 Q 1596 357 1596 367 L 1596 1160" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1592 1152 L 1596 1161 L 1601 1152" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" font-size="11px">
-      <rect fill="#ffffff" stroke="none" x="1688" y="381" width="15" height="14" stroke-width="0"/>
-      <text x="1688" y="390">no</text>
+      <rect fill="#ffffff" stroke="none" x="1687" y="338" width="18" height="18" stroke-width="0"/>
+      <text x="1687" y="351">no</text>
     </g>
-    <path d="M 1813 431 L 1813 441 Q 1813 451 1813 461 L 1813 470" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1809 462 L 1813 471 L 1818 462" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1813 392 L 1813 397 Q 1813 402 1813 406 L 1813 410" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1809 402 L 1813 411 L 1818 402" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" font-size="11px">
-      <rect fill="#ffffff" stroke="none" x="1815" y="438" width="18" height="14" stroke-width="0"/>
-      <text x="1815" y="448">yes</text>
+      <rect fill="#ffffff" stroke="none" x="1830" y="390" width="24" height="18" stroke-width="0"/>
+      <text x="1830" y="399">yes</text>
     </g>
     <path d="M 1813 902 L 1909 967 L 1813 1032 L 1717 967 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
@@ -172,13 +173,13 @@
     <path d="M 1909 967 L 1928 967 Q 1938 967 1948 967 L 1966 967" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 1958 972 L 1967 967 L 1958 963" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" font-size="11px">
-      <rect fill="#ffffff" stroke="none" x="1930" y="975" width="18" height="14" stroke-width="0"/>
+      <rect fill="#ffffff" stroke="none" x="1930" y="975" width="24" height="18" stroke-width="0"/>
       <text x="1930" y="984">yes</text>
     </g>
-    <path d="M 1813 872 L 1813 880 Q 1813 887 1813 893 L 1813 900" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1813 880 L 1813 886 Q 1813 891 1813 895 L 1813 900" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 1809 892 L 1813 901 L 1818 892" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" font-size="11px">
-      <rect fill="#ffffff" stroke="none" x="1820" y="887" width="15" height="14" stroke-width="0"/>
+      <rect fill="#ffffff" stroke="none" x="1820" y="883" width="18" height="18" stroke-width="0"/>
       <text x="1820" y="896">no</text>
     </g>
     <rect x="1968" y="947" width="160" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
@@ -192,25 +193,28 @@
     <path d="M 1813 1032 L 1813 1047 Q 1813 1057 1813 1067 L 1813 1080" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 1809 1072 L 1813 1081 L 1818 1072" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" font-size="11px">
-      <rect fill="#ffffff" stroke="none" x="1815" y="1044" width="15" height="14" stroke-width="0"/>
+      <rect fill="#ffffff" stroke="none" x="1815" y="1040" width="18" height="18" stroke-width="0"/>
       <text x="1815" y="1053">no</text>
     </g>
-    <rect x="1716" y="1182" width="195" height="70" rx="28" ry="28" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+    <rect x="1716" y="1162" width="195" height="90" rx="36" ry="36" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-      <text x="1813" y="1214">buttons.active = button</text>
-      <text x="1813" y="1228">state = BUTTON_PRESSED</text>
+      <text x="1814" y="1197">buttons.active = button</text>
+      <text x="1814" y="1211">buttons.active_is_top = is_top</text>
+      <text x="1814" y="1225">state = BUTTON_PRESSED</text>
     </g>
-    <path d="M 1813 1252 L 1813 1282 Q 1813 1292 1803 1292 L 1713 1292 Q 1703 1292 1703 1302 L 1703 1330" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1814 1252 L 1814 1282 Q 1814 1292 1804 1292 L 1713 1292 Q 1703 1292 1703 1302 L 1703 1330" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 1699 1322 L 1703 1331 L 1708 1322" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1813 1122 L 1813 1142 Q 1813 1152 1813 1162 L 1813 1180" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1809 1172 L 1813 1181 L 1818 1172" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 2128 967 L 2158 967 Q 2168 967 2168 977 L 2168 1207 Q 2168 1217 2158 1217 L 1913 1217" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1921 1213 L 1912 1217 L 1921 1222" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <rect x="1493" y="1182" width="195" height="70" rx="28" ry="28" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+    <path d="M 1813 1122 L 1813 1122 Q 1813 1122 1813 1132 L 1813 1152 Q 1813 1162 1813 1161 L 1813 1160" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1809 1152 L 1813 1161 L 1818 1152" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 2128 967 L 2158 967 Q 2168 967 2168 977 L 2168 1197 Q 2168 1207 2158 1207 L 1913 1207" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1921 1203 L 1912 1207 L 1921 1212" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <rect x="1493" y="1162" width="205" height="90" rx="36" ry="36" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-      <text x="1591" y="1207">button = buttons.active</text>
-      <text x="1591" y="1221">buttons.active = 0</text>
-      <text x="1591" y="1235">state = BUTTON_RELEASED</text>
+      <text x="1596" y="1183">button = buttons.active</text>
+      <text x="1596" y="1197">is_top = buttons.active_is_top</text>
+      <text x="1596" y="1211">buttons.active = 0</text>
+      <text x="1596" y="1225">buttons.active_is_top = 0</text>
+      <text x="1596" y="1239">state = BUTTON_RELEASED</text>
     </g>
     <rect x="1628" y="1332" width="150" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
@@ -218,7 +222,7 @@
     </g>
     <path d="M 1703 1372 L 1703 1380 Q 1703 1387 1703 1393 L 1703 1400" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 1699 1392 L 1703 1401 L 1708 1392" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 1591 1252 L 1591 1282 Q 1591 1292 1601 1292 L 1693 1292 Q 1703 1292 1703 1302 L 1703 1330" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1596 1252 L 1596 1282 Q 1596 1292 1606 1292 L 1693 1292 Q 1703 1292 1703 1302 L 1703 1330" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 1699 1322 L 1703 1331 L 1708 1322" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 1703 1402 L 1743 1422 L 1703 1442 L 1663 1422 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
@@ -227,26 +231,26 @@
     <path d="M 1743 1422 L 1808 1422 Q 1818 1422 1818 1432 L 1818 1597 Q 1818 1607 1808 1607 L 1720 1607" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 1728 1603 L 1719 1607 L 1728 1612" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" font-size="11px">
-      <rect fill="#ffffff" stroke="none" x="1745" y="1407" width="15" height="14" stroke-width="0"/>
+      <rect fill="#ffffff" stroke="none" x="1745" y="1403" width="18" height="18" stroke-width="0"/>
       <text x="1745" y="1416">no</text>
     </g>
     <path d="M 1703 1442 L 1703 1452 Q 1703 1462 1703 1471 L 1703 1480" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 1699 1472 L 1703 1481 L 1708 1472" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" font-size="11px">
-      <rect fill="#ffffff" stroke="none" x="1705" y="1450" width="18" height="14" stroke-width="0"/>
+      <rect fill="#ffffff" stroke="none" x="1705" y="1450" width="24" height="18" stroke-width="0"/>
       <text x="1705" y="1459">yes</text>
     </g>
     <rect x="1618" y="1482" width="170" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-      <text x="1703" y="1499">pointer_notify_button(</text>
-      <text x="1703" y="1513">button, state)</text>
+      <text x="1703" y="1499">tp_notify_softbutton(</text>
+      <text x="1703" y="1513">button, is_top, state)</text>
     </g>
     <path d="M 1703 1522 L 1703 1542 Q 1703 1552 1703 1562 L 1703 1590" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 1699 1582 L 1703 1591 L 1708 1582" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
     <ellipse cx="1703" cy="1607" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
     <ellipse cx="1703" cy="1607" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
-    <ellipse cx="2173" cy="607" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
-    <ellipse cx="2173" cy="607" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
+    <ellipse cx="2158" cy="626" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
+    <ellipse cx="2158" cy="626" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
     <path d="M 456 232 C 458 229 461 227 464 227 L 490 227 C 493 227 496 229 498 232 L 514 256 C 514 257 514 259 514 260 L 498 284 C 496 287 493 289 490 289 L 464 289 C 461 289 458 287 456 284 L 440 260 C 440 259 440 257 440 256 L 456 232 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
       <text x="477" y="255">finger in</text>
@@ -261,8 +265,8 @@
       <text x="477" y="453">curr = button</text>
       <text x="477" y="467">start enter timeout</text>
     </g>
-    <path d="M 477 289 L 477 385" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-    <path d="M 477 391 L 474 384 L 477 385 L 481 384 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 477 289 L 477 330 Q 477 340 477 350 L 477 385" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 477 391 L 473 384 L 477 385 L 480 384 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 552 442 L 648 442 Q 658 442 658 452 L 658 762" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
     <rect x="412" y="712" width="130" height="100" rx="6" ry="6" fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/>
     <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
@@ -356,5 +360,27 @@
     <path d="M 737 32 L 730 36 L 732 32 L 730 29 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 66 762 L 18 762 Q 8 762 8 752 L 8 42 Q 8 32 18 32 L 732 32" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
     <path d="M 737 32 L 730 36 L 732 32 L 730 29 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1813 477 L 1876 511 L 1813 546 L 1751 511 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
+      <text x="1813" y="515">touches in top?</text>
+    </g>
+    <path d="M 1876 511 L 1928 511 Q 1938 511 1938 518 L 1938 524" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1934 516 L 1938 525 L 1943 516" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <g fill="#000000" font-family="Helvetica" font-size="11px">
+      <rect fill="#ffffff" stroke="none" x="1890" y="500" width="24" height="18" stroke-width="0"/>
+      <text x="1890" y="509">yes</text>
+    </g>
+    <rect x="1898" y="526" width="80" height="30" rx="12" ry="12" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+    <g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
+      <text x="1938" y="545">is_top = 1</text>
+    </g>
+    <path d="M 1938 556 L 1938 562 Q 1938 568 1928 568 L 1815 568" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1823 564 L 1814 568 L 1823 573" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1813 546 L 1813 554 Q 1813 562 1813 564 L 1813 566" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <path d="M 1809 558 L 1813 567 L 1818 558" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+    <g fill="#000000" font-family="Helvetica" font-size="11px">
+      <rect fill="#ffffff" stroke="none" x="1820" y="550" width="18" height="18" stroke-width="0"/>
+      <text x="1820" y="559">no</text>
+    </g>
   </g>
 </svg>
diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index 02d3205..b6aee24 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -675,16 +675,42 @@ tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
 	return 0;
 }
 
+static void
+tp_notify_softbutton(struct tp_dispatch *tp,
+		     uint64_t time,
+		     uint32_t button,
+		     uint32_t is_topbutton,
+		     enum libinput_button_state state)
+{
+	/* If we've a trackpoint, send top buttons through the trackpoint */
+	if (is_topbutton && tp->buttons.trackpoint) {
+		struct evdev_dispatch *dispatch = tp->buttons.trackpoint->dispatch;
+		struct input_event event;
+
+		event.time.tv_sec = time/1000;
+		event.time.tv_usec = (time % 1000) * 1000;
+		event.type = EV_KEY;
+		event.code = button;
+		event.value = (state == LIBINPUT_BUTTON_STATE_PRESSED) ? 1 : 0;
+		dispatch->interface->process(dispatch, tp->buttons.trackpoint,
+					     &event, time);
+		return;
+	}
+
+	evdev_pointer_notify_button(tp->device, time, button, state);
+}
+
 static int
 tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
 {
-	uint32_t current, old, button;
+	uint32_t current, old, button, is_top;
 	enum libinput_button_state state;
 	enum { AREA = 0x01, LEFT = 0x02, MIDDLE = 0x04, RIGHT = 0x08 };
 
 	current = tp->buttons.state;
 	old = tp->buttons.old_state;
 	button = 0;
+	is_top = 0;
 
 	if (!tp->buttons.click_pending && current == old)
 		return 0;
@@ -697,15 +723,18 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
 			case BUTTON_EVENT_IN_AREA:
 				button |= AREA;
 				break;
-			case BUTTON_EVENT_IN_BOTTOM_L:
 			case BUTTON_EVENT_IN_TOP_L:
+				is_top = 1;
+			case BUTTON_EVENT_IN_BOTTOM_L:
 				button |= LEFT;
 				break;
 			case BUTTON_EVENT_IN_TOP_M:
+				is_top = 1;
 				button |= MIDDLE;
 				break;
-			case BUTTON_EVENT_IN_BOTTOM_R:
 			case BUTTON_EVENT_IN_TOP_R:
+				is_top = 1;
+			case BUTTON_EVENT_IN_BOTTOM_R:
 				button |= RIGHT;
 				break;
 			default:
@@ -727,21 +756,21 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
 			button = BTN_LEFT;
 
 		tp->buttons.active = button;
+		tp->buttons.active_is_topbutton = is_top;
 		state = LIBINPUT_BUTTON_STATE_PRESSED;
 	} else {
 		button = tp->buttons.active;
+		is_top = tp->buttons.active_is_topbutton;
 		tp->buttons.active = 0;
+		tp->buttons.active_is_topbutton = 0;
 		state = LIBINPUT_BUTTON_STATE_RELEASED;
 	}
 
 	tp->buttons.click_pending = false;
 
-	if (button) {
-		evdev_pointer_notify_button(tp->device,
-					    time,
-					    button,
-					    state);
-	}
+	if (button)
+		tp_notify_softbutton(tp, time, button, is_top, state);
+
 	return 1;
 }
 
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index a0ad8db..e4b860a 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -643,8 +643,11 @@ tp_device_added(struct evdev_device *device,
 	struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
 
 	if (tp->buttons.trackpoint == NULL &&
-	    (added_device->tags & EVDEV_TAG_TRACKPOINT))
+	    (added_device->tags & EVDEV_TAG_TRACKPOINT)) {
+		/* Don't send any pending releases to the new trackpoint */
+		tp->buttons.active_is_topbutton = false;
 		tp->buttons.trackpoint = added_device;
+	}
 
 	if (tp->sendevents.current_mode !=
 	    LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
@@ -661,8 +664,14 @@ tp_device_removed(struct evdev_device *device,
 	struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
 	struct libinput_device *dev;
 
-	if (removed_device == tp->buttons.trackpoint)
+	if (removed_device == tp->buttons.trackpoint) {
+		/* Clear any pending releases for the trackpoint */
+		if (tp->buttons.active && tp->buttons.active_is_topbutton) {
+			tp->buttons.active = 0;
+			tp->buttons.active_is_topbutton = true;
+		}
 		tp->buttons.trackpoint = NULL;
+	}
 
 	if (tp->sendevents.current_mode !=
 	    LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
@@ -703,8 +712,8 @@ static struct evdev_dispatch_interface tp_interface = {
 	tp_destroy,
 	tp_device_added,
 	tp_device_removed,
-	NULL, /* device_suspended */
-	NULL, /* device_resumed */
+	tp_device_removed, /* device_suspended, treat as remove */
+	tp_device_added,   /* device_resumed, treat as add */
 	tp_tag_device,
 };
 
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 4a16db9..3d3932b 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -183,6 +183,7 @@ struct tp_dispatch {
 		uint32_t old_state;
 		uint32_t motion_dist;		/* for pinned touches */
 		unsigned int active;		/* currently active button, for release event */
+		bool active_is_topbutton;	/* is active a top button? */
 
 		/* Only used for clickpads. The software button areas are
 		 * always 2 horizontal stripes across the touchpad.
-- 
1.9.3



More information about the wayland-devel mailing list