[PATCH libinput 10/19] touchpad: add support for multi-finger tapping

Peter Hutterer peter.hutterer at who-t.net
Sun Feb 16 22:48:29 PST 2014


Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 doc/touchpad-tap-state-machine.svg | 771 +++++++++++++++++++++++++++++++++++++
 src/Makefile.am                    |   1 +
 src/evdev-mt-touchpad-tap.c        | 586 ++++++++++++++++++++++++++++
 src/evdev-mt-touchpad.c            |   4 +
 src/evdev-mt-touchpad.h            |  33 ++
 5 files changed, 1395 insertions(+)
 create mode 100644 doc/touchpad-tap-state-machine.svg
 create mode 100644 src/evdev-mt-touchpad-tap.c

diff --git a/doc/touchpad-tap-state-machine.svg b/doc/touchpad-tap-state-machine.svg
new file mode 100644
index 0000000..50ebc71
--- /dev/null
+++ b/doc/touchpad-tap-state-machine.svg
@@ -0,0 +1,771 @@
+<svg xmlns="http://www.w3.org/2000/svg" style="background-color: rgb(255, 255, 255);"
+width="2301px" height="2384px" xmlns:xlink="http://www.w3.org/1999/xlink"
+version="1.1"><defs/><g transform="translate(0.5,0.5)"><path d="M 1464 1307 L 2197 850"
+fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3"
+pointer-events="none"/><path d="M 2201 848 L 2197 854 L 2197 850 L 2194 848 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M
+1351 292 L 2197 785" fill="none" stroke="#000000" stroke-miterlimit="10"
+stroke-dasharray="3 3" pointer-events="none"/><path d="M 2201 788 L 2193 788 L 2197 785 L
+2197 782 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 802 1532 L 936 1687" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 940 1691 L 932 1688 L 936 1687 L
+938 1684 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><ellipse cx="1317" cy="32" rx="49.5" ry="30" fill="#ccccff"
+stroke="#000000" stroke-width="2" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1317" y="36" fill="#000000"
+font-family="Helvetica">IDLE</text></g><rect x="1252" y="252" width="130" height="40"
+rx="2" ry="2" fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1317" y="276" fill="#000000"
+font-family="Helvetica">TOUCH</text></g><path d="M 1289 137 C 1292 134 1296 132 1300 132 L
+1334 132 C 1338 132 1342 134 1345 137 L 1365 160 C 1366 161 1366 163 1365 164 L 1345 187 C
+1342 190 1338 192 1334 192 L 1300 192 C 1296 192 1292 190 1289 187 L 1269 164 C 1269 163
+1269 161 1269 160 L 1289 137 Z" fill="#ffd966" stroke="#000000" stroke-width="2"
+stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1317" y="159" fill="#000000"
+font-family="Helvetica">first</text><text x="1317" y="173" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 1317 62 L 1317 126" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1317 131 L 1314
+124 L 1317 126 L 1321 124 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1317 192 L 1317 246" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1317 251 L 1314 244 L 1317 246 L
+1321 244 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1016 367 C 1019 364 1023 362 1027 362 L 1061 362 C 1065
+362 1069 364 1072 367 L 1092 390 C 1093 391 1093 393 1092 394 L 1072 417 C 1069 420 1065
+422 1061 422 L 1027 422 C 1023 422 1019 420 1016 417 L 996 394 C 996 393 996 391 996 390 L
+1016 367 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="1044" y="396"
+fill="#000000" font-family="Helvetica">finger up</text></g><path d="M 1272 292 L 1098 368"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1094
+370 L 1099 364 L 1098 368 L 1101 371 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1014 682 C 1015 681 1015 679 1016
+678 C 1017 678 1018 677 1019 677 L 1088 677 C 1089 677 1091 678 1092 679 C 1093 680 1093
+681 1093 682 L 1074 732 C 1073 733 1072 735 1072 736 C 1071 736 1070 737 1069 737 L 999
+737 C 998 737 997 736 996 735 C 995 734 995 733 995 732 Z" fill="#ff6666" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1044" y="704" fill="#000000" font-family="Helvetica">button
+1</text><text x="1044" y="718" fill="#000000"
+font-family="Helvetica">press</text></g><path d="M 1564 367 C 1566 364 1570 362 1575 362 L
+1608 362 C 1613 362 1617 364 1619 367 L 1639 390 C 1640 391 1640 393 1639 394 L 1619 417 C
+1617 420 1613 422 1608 422 L 1575 422 C 1570 422 1566 420 1564 417 L 1544 394 C 1543 393
+1543 391 1544 390 L 1564 367 Z" fill="#99ffff" stroke="#000000" stroke-width="2"
+stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1592" y="396" fill="#000000"
+font-family="Helvetica">timeout</text></g><path d="M 1363 292 L 1537 368" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1542 370 L 1534
+371 L 1537 368 L 1537 364 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1383 367 C 1385 364 1389 362 1394 362 L 1427 362 C 1432
+362 1436 364 1438 367 L 1458 390 C 1459 391 1459 393 1458 394 L 1438 417 C 1436 420 1432
+422 1427 422 L 1394 422 C 1389 422 1385 420 1383 417 L 1363 394 C 1362 393 1362 391 1363
+390 L 1383 367 Z" fill="#67ab9f" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="1411" y="389"
+fill="#000000" font-family="Helvetica">move > </text><text x="1411" y="403"
+fill="#000000" font-family="Helvetica">threshold</text></g><path d="M 1333 292 L 1383 357"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1386
+361 L 1379 358 L 1383 357 L 1385 353 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1194 367 C 1196 364 1200 362 1205
+362 L 1238 362 C 1243 362 1247 364 1249 367 L 1269 390 C 1270 391 1270 393 1269 394 L 1249
+417 C 1247 420 1243 422 1238 422 L 1205 422 C 1200 422 1196 420 1194 417 L 1174 394 C 1173
+393 1173 391 1174 390 L 1194 367 Z" fill="#7ea6e0" stroke="#000000" stroke-width="2"
+stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1222" y="389" fill="#000000"
+font-family="Helvetica">second</text><text x="1222" y="403" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 1301 292 L 1249 357" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1246 361 L 1248
+353 L 1249 357 L 1253 358 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><rect x="1332" y="687" width="130" height="40" rx="2" ry="2"
+fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1397" y="711" fill="#000000"
+font-family="Helvetica">TOUCH_2</text></g><path d="M 1238 422 L 1383 681" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1385 686 L 1379
+682 L 1383 681 L 1385 678 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1274 792 C 1277 789 1281 787 1285 787 L 1319 787 C 1323
+787 1327 789 1330 792 L 1350 815 C 1351 816 1351 818 1350 819 L 1330 842 C 1327 845 1323
+847 1319 847 L 1285 847 C 1281 847 1277 845 1274 842 L 1254 819 C 1254 818 1254 816 1254
+815 L 1274 792 Z" fill="#7ea6e0" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="1302" y="814"
+fill="#000000" font-family="Helvetica">second</text><text x="1302" y="828" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1380 727 L 1332 782" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1329 786 L 1331
+779 L 1332 782 L 1336 783 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1191 672 C 1192 671 1192 669 1193 668 C 1194 668 1195
+667 1196 667 L 1265 667 C 1266 667 1268 668 1269 669 C 1270 670 1270 671 1270 672 L 1251
+722 C 1250 723 1249 725 1249 726 C 1248 726 1247 727 1246 727 L 1176 727 C 1175 727 1174
+726 1173 725 C 1172 724 1172 723 1172 722 Z" fill="#ff6666" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1221" y="694" fill="#000000" font-family="Helvetica">button
+2</text><text x="1221" y="708" fill="#000000"
+font-family="Helvetica">press</text></g><path d="M 1543 792 C 1545 789 1549 787 1554 787 L
+1587 787 C 1592 787 1596 789 1598 792 L 1618 815 C 1619 816 1619 818 1618 819 L 1598 842 C
+1596 845 1592 847 1587 847 L 1554 847 C 1549 847 1545 845 1543 842 L 1523 819 C 1522 818
+1522 816 1523 815 L 1543 792 Z" fill="#67ab9f" stroke="#000000" stroke-width="2"
+stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1571" y="814" fill="#000000" font-family="Helvetica">move >
+</text><text x="1571" y="828" fill="#000000"
+font-family="Helvetica">threshold</text></g><path d="M 1693 792 C 1695 789 1699 787 1704
+787 L 1737 787 C 1742 787 1746 789 1748 792 L 1768 815 C 1769 816 1769 818 1768 819 L 1748
+842 C 1746 845 1742 847 1737 847 L 1704 847 C 1699 847 1695 845 1693 842 L 1673 819 C 1672
+818 1672 816 1673 815 L 1693 792 Z" fill="#99ffff" stroke="#000000" stroke-width="2"
+stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1721" y="821" fill="#000000"
+font-family="Helvetica">timeout</text></g><path d="M 1456 727 L 1666 798" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1671 800 L 1663
+801 L 1666 798 L 1665 795 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1429 727 L 1518 784" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1522 786 L 1514 786 L 1518 784 L
+1518 780 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1106 1102 C 1106 1101 1107 1099 1108 1098 C 1109 1098
+1110 1097 1111 1097 L 1179 1097 C 1181 1097 1182 1098 1183 1099 C 1184 1100 1184 1101 1184
+1102 L 1165 1152 C 1165 1153 1164 1155 1163 1156 C 1162 1156 1161 1157 1160 1157 L 1091
+1157 C 1089 1157 1088 1156 1087 1155 C 1087 1154 1086 1153 1087 1152 Z" fill="#ff6666"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1136" y="1124" fill="#000000"
+font-family="Helvetica">button 1</text><text x="1136" y="1138" fill="#000000"
+font-family="Helvetica">release</text></g><path d="M 1189 567 C 1189 566 1190 564 1191 563
+C 1192 563 1193 562 1194 562 L 1262 562 C 1264 562 1265 563 1266 564 C 1267 565 1267 566
+1267 567 L 1248 617 C 1248 618 1247 620 1246 621 C 1245 621 1244 622 1243 622 L 1174 622 C
+1172 622 1171 621 1170 620 C 1170 619 1169 618 1170 617 Z" fill="#ff6666" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1218" y="589" fill="#000000" font-family="Helvetica">button
+2</text><text x="1218" y="603" fill="#000000"
+font-family="Helvetica">release</text></g><path d="M 1282 787 L 1245 732" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1242 728 L 1249
+732 L 1245 732 L 1243 736 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1220 667 L 1219 628" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1219 623 L 1223 630 L 1219 628 L
+1216 630 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1044 422 L 1044 671" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1044 676 L 1041 669 L 1044 671 L
+1048 669 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><rect x="979" y="877" width="130" height="40" rx="2" ry="2"
+fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1044" y="901" fill="#000000"
+font-family="Helvetica">TAPPED</text></g><path d="M 1108 1002 C 1111 999 1115 997 1119 997
+L 1153 997 C 1157 997 1161 999 1164 1002 L 1184 1025 C 1185 1026 1185 1028 1184 1029 L
+1164 1052 C 1161 1055 1157 1057 1153 1057 L 1119 1057 C 1115 1057 1111 1055 1108 1052 L
+1088 1029 C 1088 1028 1088 1026 1088 1025 L 1108 1002 Z" fill="#99ffff" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1136" y="1031" fill="#000000"
+font-family="Helvetica">timeout</text></g><path d="M 1058 917 L 1111 992" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1114 996 L 1107
+992 L 1111 992 L 1113 988 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 919 1002 C 921 999 925 997 930 997 L 963 997 C 968 997
+972 999 974 1002 L 994 1025 C 995 1026 995 1028 994 1029 L 974 1052 C 972 1055 968 1057
+963 1057 L 930 1057 C 925 1057 921 1055 919 1052 L 899 1029 C 898 1028 898 1026 899 1025 L
+919 1002 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="947" y="1024"
+fill="#000000" font-family="Helvetica">first</text><text x="947" y="1038" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 1029 917 L 973 992" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 970 996 L 971
+988 L 973 992 L 977 993 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><rect x="410" y="1347" width="130" height="40" rx="2" ry="2"
+fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="475" y="1371" fill="#000000"
+font-family="Helvetica">DRAGGING</text></g><path d="M 304 1477 C 307 1474 311 1472 315
+1472 L 349 1472 C 353 1472 357 1474 360 1477 L 380 1500 C 381 1501 381 1503 380 1504 L 360
+1527 C 357 1530 353 1532 349 1532 L 315 1532 C 311 1532 307 1530 304 1527 L 284 1504 C 284
+1503 284 1501 284 1500 L 304 1477 Z" fill="#ffd966" stroke="#000000" stroke-width="2"
+stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="332" y="1499" fill="#000000"
+font-family="Helvetica">first</text><text x="332" y="1513" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 510 1742 C 511 1741 511 1739 512
+1738 C 513 1738 514 1737 515 1737 L 584 1737 C 585 1737 587 1738 588 1739 C 589 1740 589
+1741 589 1742 L 570 1792 C 569 1793 568 1795 568 1796 C 567 1796 566 1797 565 1797 L 495
+1797 C 494 1797 493 1796 492 1795 C 491 1794 491 1793 491 1792 Z" fill="#ff6666"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="540" y="1764" fill="#000000"
+font-family="Helvetica">btn1</text><text x="540" y="1778" fill="#000000"
+font-family="Helvetica">release</text></g><path d="M 454 1387 L 368 1468" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 365 1471 L 367
+1464 L 368 1468 L 372 1469 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1044 737 L 1044 871" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1044 876 L 1041 869 L 1044 871 L
+1048 869 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1136 1057 L 1136 1091" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1136 1096 L 1132 1089 L 1136 1091
+L 1139 1089 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><ellipse cx="1689" cy="717" rx="49.5" ry="30" fill="#ccccff"
+stroke="#000000" stroke-width="2" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1689" y="721" fill="#000000"
+font-family="Helvetica">IDLE</text></g><path d="M 1403 792 C 1405 789 1409 787 1414 787 L
+1447 787 C 1452 787 1456 789 1458 792 L 1478 815 C 1479 816 1479 818 1478 819 L 1458 842 C
+1456 845 1452 847 1447 847 L 1414 847 C 1409 847 1405 845 1403 842 L 1383 819 C 1382 818
+1382 816 1383 815 L 1403 792 Z" fill="#ffb570" stroke="#000000" stroke-width="2"
+stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1431" y="814" fill="#000000"
+font-family="Helvetica">third</text><text x="1431" y="828" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 1403 727 L 1420 781" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1421 786 L 1416
+780 L 1420 781 L 1422 778 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><rect x="1366" y="1307" width="130" height="40" rx="2" ry="2"
+fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1431" y="1331" fill="#000000"
+font-family="Helvetica">TOUCH_3</text></g><path d="M 1244 1487 C 1247 1484 1251 1482 1255
+1482 L 1289 1482 C 1293 1482 1297 1484 1300 1487 L 1320 1510 C 1321 1511 1321 1513 1320
+1514 L 1300 1537 C 1297 1540 1293 1542 1289 1542 L 1255 1542 C 1251 1542 1247 1540 1244
+1537 L 1224 1514 C 1224 1513 1224 1511 1224 1510 L 1244 1487 Z" fill="#7ea6e0"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1272" y="1509" fill="#000000"
+font-family="Helvetica">second</text><text x="1272" y="1523" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1431 847 L 1431 1301" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1431 1306 L 1428
+1299 L 1431 1301 L 1435 1299 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1177 1592 C 1178 1591 1178 1589 1179 1588 C 1180 1588
+1181 1587 1182 1587 L 1251 1587 C 1252 1587 1254 1588 1255 1589 C 1256 1590 1256 1591 1256
+1592 L 1237 1642 C 1236 1643 1235 1645 1235 1646 C 1234 1646 1233 1647 1232 1647 L 1162
+1647 C 1161 1647 1160 1646 1159 1645 C 1158 1644 1158 1643 1158 1642 Z" fill="#ff6666"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1207" y="1614" fill="#000000"
+font-family="Helvetica">button 3</text><text x="1207" y="1628" fill="#000000"
+font-family="Helvetica">press</text></g><path d="M 1177 1712 C 1178 1711 1178 1709 1179
+1708 C 1180 1708 1181 1707 1182 1707 L 1251 1707 C 1252 1707 1254 1708 1255 1709 C 1256
+1710 1256 1711 1256 1712 L 1237 1762 C 1236 1763 1235 1765 1235 1766 C 1234 1766 1233 1767
+1232 1767 L 1162 1767 C 1161 1767 1160 1766 1159 1765 C 1158 1764 1158 1763 1158 1762 Z"
+fill="#ff6666" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="1207" y="1734"
+fill="#000000" font-family="Helvetica">button 3</text><text x="1207" y="1748"
+fill="#000000" font-family="Helvetica">release</text></g><path d="M 1207 1647 L 1207 1701"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1207
+1706 L 1204 1699 L 1207 1701 L 1211 1699 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1414 1347 L 1302 1477"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1299
+1481 L 1301 1474 L 1302 1477 L 1306 1478 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1253 1542 L 1229 1582"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1226
+1586 L 1227 1578 L 1229 1582 L 1233 1582 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1490 1487 C 1493 1484 1497 1482
+1501 1482 L 1535 1482 C 1539 1482 1543 1484 1546 1487 L 1566 1510 C 1567 1511 1567 1513
+1566 1514 L 1546 1537 C 1543 1540 1539 1542 1535 1542 L 1501 1542 C 1497 1542 1493 1540
+1490 1537 L 1470 1514 C 1470 1513 1470 1511 1470 1510 L 1490 1487 Z" fill="#67ab9f"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1518" y="1509" fill="#000000"
+font-family="Helvetica">move > </text><text x="1518" y="1523" fill="#000000"
+font-family="Helvetica">threshold</text></g><path d="M 1441 1347 L 1501 1476" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1503 1481 L 1497
+1476 L 1501 1476 L 1504 1473 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><ellipse cx="692" cy="1782" rx="49.5" ry="30" fill="#ccccff"
+stroke="#000000" stroke-width="2" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="692" y="1786" fill="#000000"
+font-family="Helvetica">IDLE</text></g><path d="M 1619 1487 C 1621 1484 1625 1482 1630
+1482 L 1663 1482 C 1668 1482 1672 1484 1674 1487 L 1694 1510 C 1695 1511 1695 1513 1694
+1514 L 1674 1537 C 1672 1540 1668 1542 1663 1542 L 1630 1542 C 1625 1542 1621 1540 1619
+1537 L 1599 1514 C 1598 1513 1598 1511 1599 1510 L 1619 1487 Z" fill="#99ffff"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1647" y="1516" fill="#000000"
+font-family="Helvetica">timeout</text></g><path d="M 1455 1347 L 1607 1478" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1611 1481 L 1603
+1479 L 1607 1478 L 1608 1474 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1363 1487 C 1365 1484 1369 1482 1374 1482 L 1407 1482 C
+1412 1482 1416 1484 1418 1487 L 1438 1510 C 1439 1511 1439 1513 1438 1514 L 1418 1537 C
+1416 1540 1412 1542 1407 1542 L 1374 1542 C 1369 1542 1365 1540 1363 1537 L 1343 1514 C
+1342 1513 1342 1511 1343 1510 L 1363 1487 Z" fill="#ffb570" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1391" y="1509" fill="#000000"
+font-family="Helvetica">third</text><text x="1391" y="1523" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1427 1347 L 1399 1476" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1397 1481 L 1395
+1473 L 1399 1476 L 1402 1475 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1342 1540 L 1262 1586" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1257 1588 L 1261 1582 L 1262 1586
+L 1265 1588 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1164 792 C 1166 789 1170 787 1175 787 L 1208 787 C 1213
+787 1217 789 1219 792 L 1239 815 C 1240 816 1240 818 1239 819 L 1219 842 C 1217 845 1213
+847 1208 847 L 1175 847 C 1170 847 1166 845 1164 842 L 1144 819 C 1143 818 1143 816 1144
+815 L 1164 792 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="1192" y="814"
+fill="#000000" font-family="Helvetica">first</text><text x="1192" y="828" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1360 727 L 1246 788" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1241 791 L 1246
+784 L 1246 788 L 1249 790 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1199 787 L 1212 733" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1213 728 L 1215 736 L 1212 733 L
+1208 734 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><ellipse cx="1136" cy="1267" rx="49.5" ry="30" fill="#ccccff"
+stroke="#000000" stroke-width="2" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1136" y="1271" fill="#000000"
+font-family="Helvetica">IDLE</text></g><path d="M 1016 1487 C 1019 1484 1023 1482 1027
+1482 L 1061 1482 C 1065 1482 1069 1484 1072 1487 L 1092 1510 C 1093 1511 1093 1513 1092
+1514 L 1072 1537 C 1069 1540 1065 1542 1061 1542 L 1027 1542 C 1023 1542 1019 1540 1016
+1537 L 996 1514 C 996 1513 996 1511 996 1510 L 1016 1487 Z" fill="#ffffff"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1044" y="1509" fill="#000000"
+font-family="Helvetica">fourth</text><text x="1044" y="1523" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 1390 1347 L 1098 1486"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1094
+1488 L 1098 1482 L 1098 1486 L 1101 1489 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1136 1157 L 1136 1231"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1136
+1236 L 1132 1229 L 1136 1231 L 1139 1229 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><rect x="651" y="1127" width="209"
+height="40" rx="2" ry="2" fill="#ccffcc" stroke="#000000" stroke-width="2"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="755" y="1151"
+fill="#000000" font-family="Helvetica">DRAGGING_OR_DOUBLETAP</text></g><path d="M 899 1057
+L 792 1124" fill="none" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 788 1126 L 792 1120 L 792 1124 L 796 1126 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M
+528 1212 C 530 1209 534 1207 539 1207 L 572 1207 C 577 1207 581 1209 583 1212 L 603 1235 C
+604 1236 604 1238 603 1239 L 583 1262 C 581 1265 577 1267 572 1267 L 539 1267 C 534 1267
+530 1265 528 1262 L 508 1239 C 507 1238 507 1236 508 1235 L 528 1212 Z" fill="#99ffff"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="556" y="1241" fill="#000000"
+font-family="Helvetica">timeout</text></g><path d="M 711 1167 L 610 1213" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 605 1215 L 610
+1209 L 610 1213 L 613 1215 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 537 1267 L 491 1342" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 488 1346 L 489 1338 L 491 1342 L
+495 1342 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 841 1212 C 844 1209 848 1207 852 1207 L 886 1207 C 890
+1207 894 1209 897 1212 L 917 1235 C 918 1236 918 1238 917 1239 L 897 1262 C 894 1265 890
+1267 886 1267 L 852 1267 C 848 1267 844 1265 841 1262 L 821 1239 C 821 1238 821 1236 821
+1235 L 841 1212 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="869" y="1234"
+fill="#000000" font-family="Helvetica">first</text><text x="869" y="1248" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 780 1167 L 826 1203" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 830 1206 L 822
+1205 L 826 1203 L 827 1199 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 872 1337 C 873 1336 873 1334 874 1333 C 875 1333 876
+1332 877 1332 L 946 1332 C 947 1332 949 1333 950 1334 C 951 1335 951 1336 951 1337 L 932
+1387 C 931 1388 930 1390 930 1391 C 929 1391 928 1392 927 1392 L 857 1392 C 856 1392 855
+1391 854 1390 C 853 1389 853 1388 853 1387 Z" fill="#ff6666" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="902" y="1359" fill="#000000" font-family="Helvetica">button
+1</text><text x="902" y="1373" fill="#000000"
+font-family="Helvetica">release</text></g><path d="M 872 1417 C 873 1416 873 1414 874 1413
+C 875 1413 876 1412 877 1412 L 946 1412 C 947 1412 949 1413 950 1414 C 951 1415 951 1416
+951 1417 L 932 1467 C 931 1468 930 1470 930 1471 C 929 1471 928 1472 927 1472 L 857 1472 C
+856 1472 855 1471 854 1470 C 853 1469 853 1468 853 1467 Z" fill="#ff6666" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="902" y="1439" fill="#000000" font-family="Helvetica">button
+1</text><text x="902" y="1453" fill="#000000"
+font-family="Helvetica">press</text></g><path d="M 879 1507 C 879 1506 880 1504 881 1503 C
+882 1503 883 1502 884 1502 L 952 1502 C 954 1502 955 1503 956 1504 C 957 1505 957 1506 957
+1507 L 938 1557 C 938 1558 937 1560 936 1561 C 935 1561 934 1562 933 1562 L 864 1562 C 862
+1562 861 1561 860 1560 C 860 1559 859 1558 860 1557 Z" fill="#ff6666" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="909" y="1529" fill="#000000"
+font-family="Helvetica">btn1</text><text x="909" y="1543" fill="#000000"
+font-family="Helvetica">release</text></g><path d="M 879 1267 L 900 1326" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 902 1331 L 896
+1325 L 900 1326 L 903 1323 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 902 1392 L 902 1406" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 902 1411 L 899 1404 L 902 1406 L
+906 1404 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 904 1472 L 906 1496" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 906 1501 L 902 1494 L 906 1496 L
+909 1494 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 882 1562 L 722 1747" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 718 1751 L 720 1744 L 722 1747 L
+726 1748 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 683 1212 C 685 1209 689 1207 694 1207 L 727 1207 C 732
+1207 736 1209 738 1212 L 758 1235 C 759 1236 759 1238 758 1239 L 738 1262 C 736 1265 732
+1267 727 1267 L 694 1267 C 689 1267 685 1265 683 1262 L 663 1239 C 662 1238 662 1236 663
+1235 L 683 1212 Z" fill="#7ea6e0" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="711" y="1234"
+fill="#000000" font-family="Helvetica">second</text><text x="711" y="1248" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 745 1167 L 728 1201" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 726 1206 L 726
+1198 L 728 1201 L 732 1201 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 353 1212 C 355 1209 359 1207 364 1207 L 397 1207 C 402
+1207 406 1209 408 1212 L 428 1235 C 429 1236 429 1238 428 1239 L 408 1262 C 406 1265 402
+1267 397 1267 L 364 1267 C 359 1267 355 1265 353 1262 L 333 1239 C 332 1238 332 1236 333
+1235 L 353 1212 Z" fill="#67ab9f" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="381" y="1234"
+fill="#000000" font-family="Helvetica">move > </text><text x="381" y="1248"
+fill="#000000" font-family="Helvetica">threshold</text></g><path d="M 672 1167 L 435 1224"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 430
+1225 L 436 1220 L 435 1224 L 438 1227 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 402 1267 L 457 1342" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 460 1346 L 453
+1342 L 457 1342 L 459 1338 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><rect x="1429" y="502" width="130" height="40" rx="2" ry="2"
+fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1494" y="526" fill="#000000"
+font-family="Helvetica">HOLD</text></g><path d="M 1569 422 L 1513 497" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1510 501 L 1511
+493 L 1513 497 L 1517 498 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1430 422 L 1478 497" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1481 501 L 1474 497 L 1478 497 L
+1480 493 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1547 582 C 1550 579 1554 577 1558 577 L 1592 577 C 1596
+577 1600 579 1603 582 L 1623 605 C 1624 606 1624 608 1623 609 L 1603 632 C 1600 635 1596
+637 1592 637 L 1558 637 C 1554 637 1550 635 1547 632 L 1527 609 C 1527 608 1527 606 1527
+605 L 1547 582 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="1575" y="604"
+fill="#000000" font-family="Helvetica">first</text><text x="1575" y="618" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1513 542 L 1542 572" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1546 576 L 1538
+574 L 1542 572 L 1543 569 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1606 637 L 1654 683" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1657 686 L 1650 684 L 1654 683 L
+1655 679 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1400 582 C 1402 579 1406 577 1411 577 L 1444 577 C 1449
+577 1453 579 1455 582 L 1475 605 C 1476 606 1476 608 1475 609 L 1455 632 C 1453 635 1449
+637 1444 637 L 1411 637 C 1406 637 1402 635 1400 632 L 1380 609 C 1379 608 1379 606 1380
+605 L 1400 582 Z" fill="#7ea6e0" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="1428" y="604"
+fill="#000000" font-family="Helvetica">second</text><text x="1428" y="618" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 1478 542 L 1455 572" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1452 576 L 1453
+568 L 1455 572 L 1459 573 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1418 637 L 1405 681" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1403 686 L 1402 678 L 1405 681 L
+1409 680 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1267 580 L 1423 540" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1428 539 L 1422 544 L 1423 540 L
+1420 537 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><rect x="1776" y="937" width="130" height="40" rx="2" ry="2"
+fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1841" y="961" fill="#000000"
+font-family="Helvetica">TOUCH_2_HOLD</text></g><path d="M 1619 842 L 1797 934" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1802 936 L 1794
+936 L 1797 934 L 1797 930 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1746 847 L 1820 932" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1823 936 L 1816 933 L 1820 932 L
+1821 929 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1957 1032 C 1960 1029 1964 1027 1968 1027 L 2002 1027 C
+2006 1027 2010 1029 2013 1032 L 2033 1055 C 2033 1056 2033 1058 2033 1059 L 2013 1082 C
+2010 1085 2006 1087 2002 1087 L 1968 1087 C 1964 1087 1960 1085 1957 1082 L 1937 1059 C
+1936 1058 1936 1056 1937 1055 L 1957 1032 Z" fill="#7ea6e0" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1985" y="1054" fill="#000000"
+font-family="Helvetica">second</text><text x="1985" y="1068" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1870 977 L 1936 1023" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1941 1026 L 1933
+1025 L 1936 1023 L 1937 1019 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1668 1032 C 1671 1029 1675 1027 1679 1027 L 1713 1027 C
+1717 1027 1721 1029 1724 1032 L 1744 1055 C 1745 1056 1745 1058 1744 1059 L 1724 1082 C
+1721 1085 1717 1087 1713 1087 L 1679 1087 C 1675 1087 1671 1085 1668 1082 L 1648 1059 C
+1648 1058 1648 1056 1648 1055 L 1668 1032 Z" fill="#ffd966" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1696" y="1054" fill="#000000"
+font-family="Helvetica">first</text><text x="1696" y="1068" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1812 977 L 1745 1023" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1741 1026 L 1744
+1020 L 1745 1023 L 1748 1025 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1982 1027 L 1982 532 Q 1982 522 1972 522 L 1565 522"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1560
+522 L 1567 519 L 1565 522 L 1567 526 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1648 1057 L 1640 1057 Q 1632 1057
+1632 1047 L 1632 532 Q 1632 522 1622 522 L 1565 522" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1560 522 L 1567 519 L 1565 522 L
+1567 526 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1814 1032 C 1817 1029 1821 1027 1825 1027 L 1859 1027 C
+1863 1027 1867 1029 1870 1032 L 1890 1055 C 1890 1056 1890 1058 1890 1059 L 1870 1082 C
+1867 1085 1863 1087 1859 1087 L 1825 1087 C 1821 1087 1817 1085 1814 1082 L 1794 1059 C
+1793 1058 1793 1056 1794 1055 L 1814 1032 Z" fill="#ffb570" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1842" y="1054" fill="#000000"
+font-family="Helvetica">third</text><text x="1842" y="1068" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 1841 977 L 1842 1021" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1842 1026 L 1838
+1019 L 1842 1021 L 1845 1019 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1796 1087 L 1467 1303" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1463 1306 L 1467 1300 L 1467 1303
+L 1471 1305 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1256 1737 L 2062 1737 Q 2072 1737 2072 1727 L 2072 967 Q
+2072 957 2062 957 L 1913 957" fill="none" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1907 957 L 1914 954 L 1913 957 L 1914 961 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect
+x="1522" y="1637" width="130" height="40" rx="2" ry="2" fill="#ccffcc" stroke="#000000"
+stroke-width="2" pointer-events="none"/><g text-anchor="middle" font-size="12px"><text
+x="1587" y="1661" fill="#000000" font-family="Helvetica">TOUCH_3_HOLD</text></g><path d="M
+1532 1542 L 1575 1631" fill="none" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1577 1636 L 1571 1631 L 1575 1631 L 1577 1628 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M
+1634 1542 L 1598 1631" fill="none" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1596 1636 L 1595 1628 L 1598 1631 L 1602 1631 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M
+1559 1827 C 1562 1824 1566 1822 1570 1822 L 1604 1822 C 1608 1822 1612 1824 1615 1827 L
+1635 1850 C 1636 1851 1636 1853 1635 1854 L 1615 1877 C 1612 1880 1608 1882 1604 1882 L
+1570 1882 C 1566 1882 1562 1880 1559 1877 L 1539 1854 C 1539 1853 1539 1851 1539 1850 L
+1559 1827 Z" fill="#7ea6e0" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="1587" y="1849"
+fill="#000000" font-family="Helvetica">second</text><text x="1587" y="1863" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1680 1862 C 1683 1859 1687 1857
+1691 1857 L 1725 1857 C 1729 1857 1733 1859 1736 1862 L 1756 1885 C 1757 1886 1757 1888
+1756 1889 L 1736 1912 C 1733 1915 1729 1917 1725 1917 L 1691 1917 C 1687 1917 1683 1915
+1680 1912 L 1660 1889 C 1660 1888 1660 1886 1660 1885 L 1680 1862 Z" fill="#ffb570"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1708" y="1884" fill="#000000"
+font-family="Helvetica">third</text><text x="1708" y="1898" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1314 1787 C 1317 1784 1321 1782
+1325 1782 L 1359 1782 C 1363 1782 1367 1784 1370 1787 L 1390 1810 C 1391 1811 1391 1813
+1390 1814 L 1370 1837 C 1367 1840 1363 1842 1359 1842 L 1325 1842 C 1321 1842 1317 1840
+1314 1837 L 1294 1814 C 1294 1813 1294 1811 1294 1810 L 1314 1787 Z" fill="#ffffff"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1342" y="1809" fill="#000000"
+font-family="Helvetica">fourth</text><text x="1342" y="1823" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 1587 1677 L 1587 1816"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1587
+1821 L 1584 1814 L 1587 1816 L 1591 1814 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1598 1677 L 1689 1851"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1692
+1856 L 1685 1851 L 1689 1851 L 1692 1848 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1636 1852 L 2062 1852 Q 2072 1852
+2072 1842 L 2072 967 Q 2072 957 2062 957 L 1913 957" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1907 957 L 1914 954 L 1913 957 L
+1914 961 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1757 1887 L 2062 1887 Q 2072 1887 2072 1877 L 2072 967 Q
+2072 957 2062 957 L 1913 957" fill="none" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1907 957 L 1914 954 L 1913 957 L 1914 961 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect
+x="1071" y="1962" width="130" height="40" rx="2" ry="2" fill="#ccffcc" stroke="#000000"
+stroke-width="2" pointer-events="none"/><g text-anchor="middle" font-size="12px"><text
+x="1136" y="1986" fill="#000000" font-family="Helvetica">DEAD</text></g><path d="M 1555
+1677 L 1395 1779" fill="none" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1390 1781 L 1394 1775 L 1395 1779 L 1398 1781 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M
+1306 1842 L 1165 1958" fill="none" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1161 1961 L 1164 1954 L 1165 1958 L 1169 1960 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M
+1050 1542 L 1131 1956" fill="none" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1132 1961 L 1127 1955 L 1131 1956 L 1134 1953 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M
+1053 2067 C 1055 2064 1059 2062 1064 2062 L 1097 2062 C 1102 2062 1106 2064 1108 2067 L
+1128 2090 C 1129 2091 1129 2093 1128 2094 L 1108 2117 C 1106 2120 1102 2122 1097 2122 L
+1064 2122 C 1059 2122 1055 2120 1053 2117 L 1033 2094 C 1032 2093 1032 2091 1033 2090 L
+1053 2067 Z" fill="#7ea6e0" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="1081" y="2089"
+fill="#000000" font-family="Helvetica">second</text><text x="1081" y="2103" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1171 2067 C 1174 2064 1178 2062
+1182 2062 L 1216 2062 C 1220 2062 1224 2064 1227 2067 L 1247 2090 C 1248 2091 1248 2093
+1247 2094 L 1227 2117 C 1224 2120 1220 2122 1216 2122 L 1182 2122 C 1178 2122 1174 2120
+1171 2117 L 1151 2094 C 1151 2093 1151 2091 1151 2090 L 1171 2067 Z" fill="#ffb570"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1199" y="2089" fill="#000000"
+font-family="Helvetica">third</text><text x="1199" y="2103" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1293 2067 C 1295 2064 1299 2062
+1304 2062 L 1337 2062 C 1342 2062 1346 2064 1348 2067 L 1368 2090 C 1369 2091 1369 2093
+1368 2094 L 1348 2117 C 1346 2120 1342 2122 1337 2122 L 1304 2122 C 1299 2122 1295 2120
+1293 2117 L 1273 2094 C 1272 2093 1272 2091 1273 2090 L 1293 2067 Z" fill="#ffffff"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1321" y="2089" fill="#000000"
+font-family="Helvetica">fourth</text><text x="1321" y="2103" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 1131 1487 C 1133 1484 1137 1482
+1142 1482 L 1175 1482 C 1180 1482 1184 1484 1186 1487 L 1206 1510 C 1207 1511 1207 1513
+1206 1514 L 1186 1537 C 1184 1540 1180 1542 1175 1542 L 1142 1542 C 1137 1542 1133 1540
+1131 1537 L 1111 1514 C 1110 1513 1110 1511 1111 1510 L 1131 1487 Z" fill="#ffd966"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1159" y="1509" fill="#000000"
+font-family="Helvetica">first</text><text x="1159" y="1523" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1402 1347 L 1208 1478" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1204 1481 L 1208
+1475 L 1208 1478 L 1211 1480 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1172 1542 L 1190 1581" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1193 1586 L 1187 1581 L 1190 1581
+L 1193 1578 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1434 1787 C 1437 1784 1441 1782 1445 1782 L 1479 1782 C
+1483 1782 1487 1784 1490 1787 L 1510 1810 C 1511 1811 1511 1813 1510 1814 L 1490 1837 C
+1487 1840 1483 1842 1479 1842 L 1445 1842 C 1441 1842 1437 1840 1434 1837 L 1414 1814 C
+1414 1813 1414 1811 1414 1810 L 1434 1787 Z" fill="#ffd966" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1462" y="1809" fill="#000000"
+font-family="Helvetica">first</text><text x="1462" y="1823" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1571 1677 L 1490 1777" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1487 1781 L 1489
+1773 L 1490 1777 L 1494 1778 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1511 1812 L 2062 1812 Q 2072 1812 2072 1802 L 2072 967 Q
+2072 957 2062 957 L 1913 957" fill="none" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1907 957 L 1914 954 L 1913 957 L 1914 961 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M
+923 2067 C 925 2064 929 2062 934 2062 L 967 2062 C 972 2062 976 2064 978 2067 L 998 2090 C
+999 2091 999 2093 998 2094 L 978 2117 C 976 2120 972 2122 967 2122 L 934 2122 C 929 2122
+925 2120 923 2117 L 903 2094 C 902 2093 902 2091 903 2090 L 923 2067 Z" fill="#ffd966"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="951" y="2089" fill="#000000"
+font-family="Helvetica">first</text><text x="951" y="2103" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 1102 2002 L 1004 2060" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1000 2063 L 1004
+2056 L 1004 2060 L 1008 2062 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1126 2002 L 1099 2056" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1096 2061 L 1096 2053 L 1099 2056
+L 1102 2056 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1147 2002 L 1179 2056" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1181 2061 L 1175 2057 L 1179 2056
+L 1181 2053 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1170 2002 L 1267 2060" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1271 2063 L 1263 2062 L 1267 2060
+L 1267 2056 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><ellipse cx="1136" cy="2352" rx="49.5" ry="30" fill="#ccccff"
+stroke="#000000" stroke-width="2" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="1136" y="2356" fill="#000000"
+font-family="Helvetica">IDLE</text></g><path d="M 1140 2192 L 1192 2237 L 1140 2282 L 1089
+2237 Z" fill="#ffffff" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="1140" y="2234"
+fill="#000000" font-family="Helvetica">if finger</text><text x="1140" y="2248"
+fill="#000000" font-family="Helvetica">count == 0</text></g><path d="M 990 2122 L 1084
+2194" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path
+d="M 1088 2197 L 1080 2195 L 1084 2194 L 1084 2190 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1093 2122 L 1119 2186"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1121
+2191 L 1115 2186 L 1119 2186 L 1122 2183 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1187 2122 L 1161 2186"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1159
+2191 L 1158 2183 L 1161 2186 L 1165 2186 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1283 2122 L 1197 2191"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1193
+2195 L 1196 2188 L 1197 2191 L 1201 2193 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1139 2282 L 1137 2316"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1137
+2321 L 1134 2314 L 1137 2316 L 1141 2314 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 643 1477 C 645 1474 649 1472 654
+1472 L 687 1472 C 692 1472 696 1474 698 1477 L 718 1500 C 719 1501 719 1503 718 1504 L 698
+1527 C 696 1530 692 1532 687 1532 L 654 1532 C 649 1532 645 1530 643 1527 L 623 1504 C 622
+1503 622 1501 623 1500 L 643 1477 Z" fill="#7ea6e0" stroke="#000000" stroke-width="2"
+stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="671" y="1499" fill="#000000"
+font-family="Helvetica">second</text><text x="671" y="1513" fill="#000000"
+font-family="Helvetica">finger up</text></g><rect x="597" y="1347" width="130" height="40"
+rx="2" ry="2" fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="662" y="1371" fill="#000000"
+font-family="Helvetica">DRAGGING_2</text></g><path d="M 699 1267 L 672 1341" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 670 1346 L 669
+1338 L 672 1341 L 676 1341 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 663 1387 L 668 1466" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 669 1471 L 665 1464 L 668 1466 L
+672 1464 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 528 1477 C 530 1474 534 1472 539 1472 L 572 1472 C 577
+1472 581 1474 583 1477 L 603 1500 C 604 1501 604 1503 603 1504 L 583 1527 C 581 1530 577
+1532 572 1532 L 539 1532 C 534 1532 530 1530 528 1527 L 508 1504 C 507 1503 507 1501 508
+1500 L 528 1477 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="556" y="1499"
+fill="#000000" font-family="Helvetica">first</text><text x="556" y="1513" fill="#000000"
+font-family="Helvetica">finger up</text></g><path d="M 646 1387 L 583 1467" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 580 1471 L 581
+1463 L 583 1467 L 587 1468 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 538 1472 L 490 1392" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 487 1388 L 494 1392 L 490 1392 L
+488 1396 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 627 1472 L 509 1391" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 505 1388 L 513 1389 L 509 1391 L
+509 1394 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 415 1477 C 417 1474 421 1472 426 1472 L 459 1472 C 464
+1472 468 1474 470 1477 L 490 1500 C 491 1501 491 1503 490 1504 L 470 1527 C 468 1530 464
+1532 459 1532 L 426 1532 C 421 1532 417 1530 415 1527 L 395 1504 C 394 1503 394 1501 395
+1500 L 415 1477 Z" fill="#7ea6e0" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="443" y="1499"
+fill="#000000" font-family="Helvetica">second</text><text x="443" y="1513" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 470 1387 L 451 1466" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 450 1471 L 448
+1463 L 451 1466 L 455 1465 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 491 1472 L 624 1390" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 629 1388 L 624 1394 L 624 1390 L
+621 1388 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 589 1772 L 636 1776" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 641 1777 L 634 1780 L 636 1776 L
+634 1773 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 748 1477 C 750 1474 754 1472 759 1472 L 792 1472 C 797
+1472 801 1474 803 1477 L 823 1500 C 824 1501 824 1503 823 1504 L 803 1527 C 801 1530 797
+1532 792 1532 L 759 1532 C 754 1532 750 1530 748 1527 L 728 1504 C 727 1503 727 1501 728
+1500 L 748 1477 Z" fill="#ffb570" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="776" y="1499"
+fill="#000000" font-family="Helvetica">third</text><text x="776" y="1513" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 679 1387 L 746 1467" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 750 1471 L 742
+1468 L 746 1467 L 748 1464 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 937 1697 C 937 1696 938 1694 939 1693 C 940 1693 941
+1692 942 1692 L 1010 1692 C 1012 1692 1013 1693 1014 1694 C 1015 1695 1015 1696 1015 1697
+L 996 1747 C 996 1748 995 1750 994 1751 C 993 1751 992 1752 991 1752 L 922 1752 C 920 1752
+919 1751 918 1750 C 918 1749 917 1748 918 1747 Z" fill="#ff6666" stroke="#000000"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="967" y="1719" fill="#000000"
+font-family="Helvetica">btn1</text><text x="967" y="1733" fill="#000000"
+font-family="Helvetica">release</text></g><path d="M 986 1752 L 1119 1957" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1122 1961 L 1116
+1957 L 1119 1957 L 1121 1953 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 2223 792 C 2225 789 2229 787 2234 787 L 2267 787 C 2272
+787 2276 789 2278 792 L 2298 815 C 2299 816 2299 818 2298 819 L 2278 842 C 2276 845 2272
+847 2267 847 L 2234 847 C 2229 847 2225 845 2223 842 L 2203 819 C 2202 818 2202 816 2203
+815 L 2223 792 Z" fill="#000000" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="2251" y="807"
+fill="#FFFFFF" font-family="Helvetica">phys</text><text x="2251" y="821" fill="#FFFFFF"
+font-family="Helvetica">button</text><text x="2251" y="835" fill="#FFFFFF"
+font-family="Helvetica">press</text></g><path d="M 1545 542 L 2196 796" fill="none"
+stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3"
+pointer-events="none"/><path d="M 2201 798 L 2193 798 L 2196 796 L 2196 792 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M
+1462 715 L 2196 810" fill="none" stroke="#000000" stroke-miterlimit="10"
+stroke-dasharray="3 3" pointer-events="none"/><path d="M 2201 811 L 2194 813 L 2196 810 L
+2194 806 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1900 937 L 2196 836" fill="none" stroke="#000000"
+stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="none"/><path d="M 2201 834 L
+2195 840 L 2196 836 L 2193 833 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 1603 1637 L 2223 852" fill="none" stroke="#000000"
+stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="none"/><path d="M 2226 848 L
+2225 856 L 2223 852 L 2219 851 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 2252 847 L 2252 1972 Q 2252 1982 2242 1982 L 1207 1982"
+fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 1202
+1982 L 1209 1979 L 1207 1982 L 1209 1986 Z" fill="#000000" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1404 2067 C 1406 2064 1410 2062
+1415 2062 L 1448 2062 C 1453 2062 1457 2064 1459 2067 L 1479 2090 C 1480 2091 1480 2093
+1479 2094 L 1459 2117 C 1457 2120 1453 2122 1448 2122 L 1415 2122 C 1410 2122 1406 2120
+1404 2117 L 1384 2094 C 1383 2093 1383 2091 1384 2090 L 1404 2067 Z" fill="#ffffff"
+stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="1431" y="2089" fill="#000000"
+font-family="Helvetica">fourth</text><text x="1431" y="2103" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 1353 62 L 2210 783" fill="none"
+stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3"
+pointer-events="none"/><path d="M 2214 786 L 2206 784 L 2210 783 L 2211 779 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M
+23 1162 C 25 1159 29 1157 34 1157 L 67 1157 C 72 1157 76 1159 78 1162 L 98 1185 C 99 1186
+99 1188 98 1189 L 78 1212 C 76 1215 72 1217 67 1217 L 34 1217 C 29 1217 25 1215 23 1212 L
+3 1189 C 2 1188 2 1186 3 1185 L 23 1162 Z" fill="#000000" stroke="#ffffff"
+stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="51" y="1177" fill="#FFFFFF"
+font-family="Helvetica">phys</text><text x="51" y="1191" fill="#FFFFFF"
+font-family="Helvetica">button</text><text x="51" y="1205" fill="#FFFFFF"
+font-family="Helvetica">press</text></g><path d="M 979 916 L 105 1171" fill="none"
+stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3"
+pointer-events="none"/><path d="M 100 1173 L 106 1167 L 105 1171 L 108 1174 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M
+31 1797 C 32 1796 32 1794 33 1793 C 34 1793 35 1792 36 1792 L 105 1792 C 106 1792 108 1793
+109 1794 C 110 1795 110 1796 110 1797 L 91 1847 C 90 1848 89 1850 89 1851 C 88 1851 87
+1852 86 1852 L 16 1852 C 15 1852 14 1851 13 1850 C 12 1849 12 1848 12 1847 Z"
+fill="#ff6666" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="61" y="1819"
+fill="#000000" font-family="Helvetica">button 1</text><text x="61" y="1833" fill="#000000"
+font-family="Helvetica">release</text></g><path d="M 51 1217 L 60 1786" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 60 1791 L 57
+1784 L 60 1786 L 64 1784 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 110 1829 L 1065 1971" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 1070 1972 L 1062 1975 L 1065 1971
+L 1063 1968 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 651 1153 L 105 1184" fill="none" stroke="#000000"
+stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="none"/><path d="M 100 1184 L
+107 1180 L 105 1184 L 107 1187 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 428 1347 L 105 1210" fill="none" stroke="#000000"
+stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="none"/><path d="M 100 1208 L
+108 1208 L 105 1210 L 105 1214 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 597 1348 L 105 1203" fill="none" stroke="#000000"
+stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="none"/><path d="M 100 1202 L
+108 1200 L 105 1203 L 106 1207 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><rect x="251" y="1622" width="130" height="40" rx="2" ry="2"
+fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/><g
+text-anchor="middle" font-size="12px"><text x="316" y="1646" fill="#000000"
+font-family="Helvetica">DRAGGING_WAIT</text></g><path d="M 382 1727 C 385 1724 389 1722
+393 1722 L 427 1722 C 431 1722 435 1724 438 1727 L 458 1750 C 459 1751 459 1753 458 1754 L
+438 1777 C 435 1780 431 1782 427 1782 L 393 1782 C 389 1782 385 1780 382 1777 L 362 1754 C
+362 1753 362 1751 362 1750 L 382 1727 Z" fill="#99ffff" stroke="#000000" stroke-width="2"
+stroke-miterlimit="10" pointer-events="none"/><g text-anchor="middle"
+font-size="12px"><text x="410" y="1756" fill="#000000"
+font-family="Helvetica">timeout</text></g><path d="M 328 1532 L 316 1616" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 316 1621 L 313
+1613 L 316 1616 L 320 1614 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 333 1662 L 380 1717" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 383 1721 L 376 1718 L 380 1717 L
+382 1714 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 459 1758 L 485 1761" fill="none" stroke="#000000"
+stroke-miterlimit="10" pointer-events="none"/><path d="M 490 1761 L 483 1764 L 485 1761 L
+483 1757 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 203 1727 C 205 1724 209 1722 214 1722 L 247 1722 C 252
+1722 256 1724 258 1727 L 278 1750 C 279 1751 279 1753 278 1754 L 258 1777 C 256 1780 252
+1782 247 1782 L 214 1782 C 209 1782 205 1780 203 1777 L 183 1754 C 182 1753 182 1751 183
+1750 L 203 1727 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10"
+pointer-events="none"/><g text-anchor="middle" font-size="12px"><text x="231" y="1749"
+fill="#000000" font-family="Helvetica">first</text><text x="231" y="1763" fill="#000000"
+font-family="Helvetica">finger down</text></g><path d="M 300 1662 L 258 1717" fill="none"
+stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 254 1721 L 256
+1713 L 258 1717 L 261 1718 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 182 1752 L 162 1752 Q 152 1752 152 1742 L 152 1377 Q 152
+1367 162 1367 L 404 1367" fill="none" stroke="#000000" stroke-miterlimit="10"
+pointer-events="none"/><path d="M 409 1367 L 402 1371 L 404 1367 L 402 1364 Z"
+fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/></g></svg>
diff --git a/src/Makefile.am b/src/Makefile.am
index f6d0335..0e74a97 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,6 +12,7 @@ libinput_la_SOURCES =			\
 	evdev.h				\
 	evdev-mt-touchpad.c		\
 	evdev-mt-touchpad.h		\
+	evdev-mt-touchpad-tap.c		\
 	evdev-touchpad.c		\
 	filter.c			\
 	filter.h			\
diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c
new file mode 100644
index 0000000..7ac592b
--- /dev/null
+++ b/src/evdev-mt-touchpad-tap.c
@@ -0,0 +1,586 @@
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.  Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/timerfd.h>
+
+#include "evdev-mt-touchpad.h"
+
+#define CASE_RETURN_STRING(a) case a: return #a;
+
+#define DEFAULT_TAP_TIMEOUT_PERIOD 180
+#define DEFAULT_TAP_MOVE_THRESHOLD 30
+
+enum tap_event {
+	TAP_EVENT_TOUCH = 12,
+	TAP_EVENT_MOTION,
+	TAP_EVENT_RELEASE,
+	TAP_EVENT_BUTTON,
+	TAP_EVENT_TIMEOUT,
+};
+
+/*****************************************
+ * DO NOT EDIT THIS FILE!
+ *
+ * Look at the state diagram in doc/touchpad-tap-state-machine.svg, or
+ * online at
+ * https://drive.google.com/file/d/0B1NwWmji69noYTdMcU1kTUZuUVE/edit?usp=sharing
+ * (it's a http://draw.io diagram)
+ *
+ * Any changes in this file must be represented in the diagram.
+ */
+
+static inline const char*
+tap_state_to_str(enum tp_tap_state state) {
+
+	switch(state) {
+	CASE_RETURN_STRING(TAP_STATE_IDLE);
+	CASE_RETURN_STRING(TAP_STATE_HOLD);
+	CASE_RETURN_STRING(TAP_STATE_TOUCH);
+	CASE_RETURN_STRING(TAP_STATE_TAPPED);
+	CASE_RETURN_STRING(TAP_STATE_TOUCH_2);
+	CASE_RETURN_STRING(TAP_STATE_TOUCH_2_HOLD);
+	CASE_RETURN_STRING(TAP_STATE_TOUCH_3);
+	CASE_RETURN_STRING(TAP_STATE_TOUCH_3_HOLD);
+	CASE_RETURN_STRING(TAP_STATE_DRAGGING);
+	CASE_RETURN_STRING(TAP_STATE_DRAGGING_WAIT);
+	CASE_RETURN_STRING(TAP_STATE_DRAGGING_OR_DOUBLETAP);
+	CASE_RETURN_STRING(TAP_STATE_DRAGGING_2);
+	CASE_RETURN_STRING(TAP_STATE_DEAD);
+	}
+	return NULL;
+}
+
+static inline const char*
+tap_event_to_str(enum tap_event event) {
+
+	switch(event) {
+	CASE_RETURN_STRING(TAP_EVENT_TOUCH);
+	CASE_RETURN_STRING(TAP_EVENT_MOTION);
+	CASE_RETURN_STRING(TAP_EVENT_RELEASE);
+	CASE_RETURN_STRING(TAP_EVENT_TIMEOUT);
+	CASE_RETURN_STRING(TAP_EVENT_BUTTON);
+	}
+	return NULL;
+}
+#undef CASE_RETURN_STRING
+
+static void
+tp_tap_notify(struct tp_dispatch *tp,
+	      uint32_t time,
+	      int nfingers,
+	      enum libinput_pointer_button_state state)
+{
+	int32_t button;
+
+	switch (nfingers) {
+	case 1: button = BTN_LEFT; break;
+	case 2: button = BTN_RIGHT; break;
+	case 3: button = BTN_MIDDLE; break;
+	default:
+		return;
+	}
+
+	pointer_notify_button(&tp->device->base,
+			      time,
+			      button,
+			      state);
+}
+
+static void
+tp_tap_set_timer(struct tp_dispatch *tp, uint32_t time)
+{
+	uint32_t timeout = time + DEFAULT_TAP_TIMEOUT_PERIOD;
+	struct itimerspec its;
+
+	its.it_interval.tv_sec = 0;
+	its.it_interval.tv_nsec = 0;
+	its.it_value.tv_sec = timeout / 1000;
+	its.it_value.tv_nsec = (timeout % 1000) * 1000 * 1000;
+	timerfd_settime(tp->tap.timer_fd, TFD_TIMER_ABSTIME, &its, NULL);
+
+	tp->tap.timeout = timeout;
+}
+
+static void
+tp_tap_clear_timer(struct tp_dispatch *tp)
+{
+	tp->tap.timeout = 0;
+}
+
+static void
+tp_tap_idle_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+
+	switch (event) {
+	case TAP_EVENT_TOUCH:
+		tp->tap.state = TAP_STATE_TOUCH;
+		tp_tap_set_timer(tp, time);
+		break;
+	case TAP_EVENT_RELEASE:
+	case TAP_EVENT_MOTION:
+		log_info("invalid event, no fingers are down\n");
+		break;
+	case TAP_EVENT_TIMEOUT:
+		break;
+	case TAP_EVENT_BUTTON:
+		tp->tap.state = TAP_STATE_DEAD;
+		break;
+	}
+}
+
+static void
+tp_tap_touch_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+
+	switch (event) {
+	case TAP_EVENT_TOUCH:
+		tp->tap.state = TAP_STATE_TOUCH_2;
+		tp_tap_set_timer(tp, time);
+		break;
+	case TAP_EVENT_RELEASE:
+		tp->tap.state = TAP_STATE_TAPPED;
+		tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
+		tp_tap_set_timer(tp, time);
+		break;
+	case TAP_EVENT_TIMEOUT:
+	case TAP_EVENT_MOTION:
+		tp->tap.state = TAP_STATE_HOLD;
+		tp_tap_clear_timer(tp);
+		break;
+	case TAP_EVENT_BUTTON:
+		tp->tap.state = TAP_STATE_DEAD;
+		break;
+	}
+}
+
+static void
+tp_tap_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+
+	switch (event) {
+	case TAP_EVENT_TOUCH:
+		tp->tap.state = TAP_STATE_TOUCH_2;
+		tp_tap_set_timer(tp, time);
+		break;
+	case TAP_EVENT_RELEASE:
+		tp->tap.state = TAP_STATE_IDLE;
+		break;
+	case TAP_EVENT_MOTION:
+	case TAP_EVENT_TIMEOUT:
+		break;
+	case TAP_EVENT_BUTTON:
+		tp->tap.state = TAP_STATE_DEAD;
+		break;
+	}
+}
+
+static void
+tp_tap_tapped_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+
+	switch (event) {
+	case TAP_EVENT_MOTION:
+	case TAP_EVENT_RELEASE:
+		log_info("invalid event when fingers are up\n");
+		break;
+	case TAP_EVENT_TOUCH:
+		tp->tap.state = TAP_STATE_DRAGGING_OR_DOUBLETAP;
+		tp_tap_clear_timer(tp);
+		break;
+	case TAP_EVENT_TIMEOUT:
+		tp->tap.state = TAP_STATE_IDLE;
+		tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+		break;
+	case TAP_EVENT_BUTTON:
+		tp->tap.state = TAP_STATE_DEAD;
+		tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+		break;
+	}
+}
+
+static void
+tp_tap_touch2_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+
+	switch (event) {
+	case TAP_EVENT_TOUCH:
+		tp->tap.state = TAP_STATE_TOUCH_3;
+		tp_tap_set_timer(tp, time);
+		break;
+	case TAP_EVENT_RELEASE:
+		tp->tap.state = TAP_STATE_HOLD;
+		tp_tap_notify(tp, time, 2, LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
+		tp_tap_notify(tp, time, 2, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+		tp_tap_clear_timer(tp);
+		break;
+	case TAP_EVENT_MOTION:
+		tp_tap_clear_timer(tp);
+	case TAP_EVENT_TIMEOUT:
+		tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
+		break;
+	case TAP_EVENT_BUTTON:
+		tp->tap.state = TAP_STATE_DEAD;
+		break;
+	}
+}
+
+static void
+tp_tap_touch2_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+
+	switch (event) {
+	case TAP_EVENT_TOUCH:
+		tp->tap.state = TAP_STATE_TOUCH_3;
+		tp_tap_set_timer(tp, time);
+		break;
+	case TAP_EVENT_RELEASE:
+		tp->tap.state = TAP_STATE_HOLD;
+		break;
+	case TAP_EVENT_MOTION:
+	case TAP_EVENT_TIMEOUT:
+		tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
+		break;
+	case TAP_EVENT_BUTTON:
+		tp->tap.state = TAP_STATE_DEAD;
+		break;
+	}
+}
+
+static void
+tp_tap_touch3_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+
+	switch (event) {
+	case TAP_EVENT_TOUCH:
+		tp->tap.state = TAP_STATE_DEAD;
+		tp_tap_clear_timer(tp);
+		break;
+	case TAP_EVENT_MOTION:
+	case TAP_EVENT_TIMEOUT:
+		tp->tap.state = TAP_STATE_TOUCH_3_HOLD;
+		tp_tap_clear_timer(tp);
+		break;
+	case TAP_EVENT_RELEASE:
+		tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
+		tp_tap_notify(tp, time, 3, LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
+		tp_tap_notify(tp, time, 3, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+		break;
+	case TAP_EVENT_BUTTON:
+		tp->tap.state = TAP_STATE_DEAD;
+		break;
+	}
+}
+
+static void
+tp_tap_touch3_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+
+	switch (event) {
+	case TAP_EVENT_TOUCH:
+		tp->tap.state = TAP_STATE_DEAD;
+		tp_tap_set_timer(tp, time);
+		break;
+	case TAP_EVENT_RELEASE:
+		tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
+		break;
+	case TAP_EVENT_MOTION:
+	case TAP_EVENT_TIMEOUT:
+		break;
+	case TAP_EVENT_BUTTON:
+		tp->tap.state = TAP_STATE_DEAD;
+		break;
+	}
+}
+
+static void
+tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+	switch (event) {
+	case TAP_EVENT_TOUCH:
+		tp->tap.state = TAP_STATE_DRAGGING_2;
+		break;
+	case TAP_EVENT_RELEASE:
+		tp->tap.state = TAP_STATE_IDLE;
+		tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+		tp_tap_clear_timer(tp);
+		break;
+	case TAP_EVENT_MOTION:
+	case TAP_EVENT_TIMEOUT:
+		tp->tap.state = TAP_STATE_DRAGGING;
+		break;
+	case TAP_EVENT_BUTTON:
+		tp->tap.state = TAP_STATE_DEAD;
+		tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+		break;
+	}
+}
+
+static void
+tp_tap_dragging_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+
+	switch (event) {
+	case TAP_EVENT_TOUCH:
+		tp->tap.state = TAP_STATE_DRAGGING_2;
+		break;
+	case TAP_EVENT_RELEASE:
+		tp->tap.state = TAP_STATE_DRAGGING_WAIT;
+		tp_tap_set_timer(tp, time);
+		break;
+	case TAP_EVENT_MOTION:
+	case TAP_EVENT_TIMEOUT:
+		/* noop */
+		break;
+	case TAP_EVENT_BUTTON:
+		tp->tap.state = TAP_STATE_DEAD;
+		tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+		break;
+	}
+}
+
+static void
+tp_tap_dragging_wait_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+
+	switch (event) {
+	case TAP_EVENT_TOUCH:
+		tp->tap.state = TAP_STATE_DRAGGING;
+		tp_tap_clear_timer(tp);
+		break;
+	case TAP_EVENT_RELEASE:
+	case TAP_EVENT_MOTION:
+		break;
+	case TAP_EVENT_TIMEOUT:
+		tp->tap.state = TAP_STATE_IDLE;
+		tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+		break;
+	case TAP_EVENT_BUTTON:
+		tp->tap.state = TAP_STATE_DEAD;
+		tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+		break;
+	}
+}
+
+static void
+tp_tap_dragging2_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+
+	switch (event) {
+	case TAP_EVENT_RELEASE:
+		tp->tap.state = TAP_STATE_DRAGGING;
+		break;
+	case TAP_EVENT_TOUCH:
+		tp->tap.state = TAP_STATE_DEAD;
+		tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+		break;
+	case TAP_EVENT_MOTION:
+	case TAP_EVENT_TIMEOUT:
+		/* noop */
+		break;
+	case TAP_EVENT_BUTTON:
+		tp->tap.state = TAP_STATE_DEAD;
+		tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+		break;
+	}
+}
+
+static void
+tp_tap_dead_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+
+	switch (event) {
+	case TAP_EVENT_RELEASE:
+		if (tp->nfingers_down == 0)
+			tp->tap.state = TAP_STATE_IDLE;
+		break;
+	case TAP_EVENT_TOUCH:
+	case TAP_EVENT_MOTION:
+	case TAP_EVENT_TIMEOUT:
+	case TAP_EVENT_BUTTON:
+		break;
+	}
+}
+
+static void
+tp_tap_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
+{
+	enum tp_tap_state current;
+	if (!tp->tap.enabled)
+		return;
+
+	current = tp->tap.state;
+
+	switch(tp->tap.state) {
+	case TAP_STATE_IDLE:
+		tp_tap_idle_handle_event(tp, event, time);
+		break;
+	case TAP_STATE_TOUCH:
+		tp_tap_touch_handle_event(tp, event, time);
+		break;
+	case TAP_STATE_HOLD:
+		tp_tap_hold_handle_event(tp, event, time);
+		break;
+	case TAP_STATE_TAPPED:
+		tp_tap_tapped_handle_event(tp, event, time);
+		break;
+	case TAP_STATE_TOUCH_2:
+		tp_tap_touch2_handle_event(tp, event, time);
+		break;
+	case TAP_STATE_TOUCH_2_HOLD:
+		tp_tap_touch2_hold_handle_event(tp, event, time);
+		break;
+	case TAP_STATE_TOUCH_3:
+		tp_tap_touch3_handle_event(tp, event, time);
+		break;
+	case TAP_STATE_TOUCH_3_HOLD:
+		tp_tap_touch3_hold_handle_event(tp, event, time);
+		break;
+	case TAP_STATE_DRAGGING_OR_DOUBLETAP:
+		tp_tap_dragging_or_doubletap_handle_event(tp, event, time);
+		break;
+	case TAP_STATE_DRAGGING:
+		tp_tap_dragging_handle_event(tp, event, time);
+		break;
+	case TAP_STATE_DRAGGING_WAIT:
+		tp_tap_dragging_wait_handle_event(tp, event, time);
+		break;
+	case TAP_STATE_DRAGGING_2:
+		tp_tap_dragging2_handle_event(tp, event, time);
+		break;
+	case TAP_STATE_DEAD:
+		tp_tap_dead_handle_event(tp, event, time);
+		break;
+	}
+
+	if (tp->tap.state == TAP_STATE_IDLE || tp->tap.state == TAP_STATE_DEAD)
+		tp_tap_clear_timer(tp);
+
+	log_debug("%s → %s → %s\n", tap_state_to_str(current), tap_event_to_str(event), tap_state_to_str(tp->tap.state));
+}
+
+static bool
+tp_tap_exceeds_motion_threshold(struct tp_dispatch *tp, struct tp_touch *t)
+{
+	int threshold = DEFAULT_TAP_MOVE_THRESHOLD;
+	double dx, dy;
+
+	tp_get_delta(t, &dx, &dy);
+
+	return dx * dx + dy * dy > threshold * threshold;
+}
+
+int
+tp_tap_handle_state(struct tp_dispatch *tp, uint32_t time)
+{
+	struct tp_touch *t;
+
+	if (tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS)
+		tp_tap_handle_event(tp, TAP_EVENT_BUTTON, time);
+
+	tp_for_each_touch(tp, t) {
+		if (!t->dirty || t->state == TOUCH_NONE)
+			continue;
+
+		if (t->state == TOUCH_BEGIN)
+			tp_tap_handle_event(tp, TAP_EVENT_TOUCH, time);
+		else if (t->state == TOUCH_END)
+			tp_tap_handle_event(tp, TAP_EVENT_RELEASE, time);
+		else if (tp->tap.state != TAP_STATE_IDLE &&
+			 tp_tap_exceeds_motion_threshold(tp, t))
+			tp_tap_handle_event(tp, TAP_EVENT_MOTION, time);
+	}
+
+	return 0;
+}
+
+static void
+tp_tap_timeout_handler(void *data)
+{
+	struct tp_dispatch *touchpad = data;
+	uint64_t expires;
+	int len;
+	struct timespec ts;
+	uint32_t now;
+
+	len = read(touchpad->tap.timer_fd, &expires, sizeof expires);
+	if (len != sizeof expires)
+		/* This will only happen if the application made the fd
+		 * non-blocking, but this function should only be called
+		 * upon the timeout, so lets continue anyway. */
+		fprintf(stderr, "timerfd read error: %m\n");
+
+	clock_gettime(CLOCK_MONOTONIC, &ts);
+	now = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
+
+	tp_tap_handle_timeout(touchpad, now);
+}
+
+unsigned int
+tp_tap_handle_timeout(struct tp_dispatch *tp, uint32_t time)
+{
+	if (!tp->tap.enabled)
+		return 0;
+
+	if (tp->tap.timeout && tp->tap.timeout <= time) {
+		tp_tap_clear_timer(tp);
+		tp_tap_handle_event(tp, TAP_EVENT_TIMEOUT, time);
+	}
+
+	return tp->tap.timeout;
+}
+
+int
+tp_init_tap(struct tp_dispatch *tp)
+{
+	tp->tap.state = TAP_STATE_IDLE;
+	tp->tap.timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
+
+	if (tp->tap.timer_fd == -1)
+		return -1;
+
+	tp->tap.source =
+		libinput_add_fd(tp->device->base.seat->libinput,
+				tp->tap.timer_fd,
+				tp_tap_timeout_handler,
+				tp);
+
+	if (tp->tap.source == NULL) {
+		close(tp->tap.timer_fd);
+		return -1;
+	}
+
+	tp->tap.enabled = 1; /* FIXME */
+
+	return 0;
+}
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 73ea8a8..d1268f6 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -369,6 +369,7 @@ tp_post_events(struct tp_dispatch *tp, uint32_t time)
 		return;
 	}
 
+	tp_tap_handle_state(tp, time);
 
 	if (t->history.count < 4)
 		return;
@@ -487,6 +488,9 @@ tp_init(struct tp_dispatch *tp,
 	if (tp_init_accel(tp, diagonal) != 0)
 		return -1;
 
+	if (tp_init_tap(tp) != 0)
+		return -1;
+
 	return 0;
 }
 
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 907aec8..973b478 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -45,6 +45,22 @@ enum touch_state {
 	TOUCH_END
 };
 
+enum tp_tap_state {
+	TAP_STATE_IDLE = 4,
+	TAP_STATE_TOUCH,
+	TAP_STATE_HOLD,
+	TAP_STATE_TAPPED,
+	TAP_STATE_TOUCH_2,
+	TAP_STATE_TOUCH_2_HOLD,
+	TAP_STATE_TOUCH_3,
+	TAP_STATE_TOUCH_3_HOLD,
+	TAP_STATE_DRAGGING_OR_DOUBLETAP,
+	TAP_STATE_DRAGGING,
+	TAP_STATE_DRAGGING_WAIT,
+	TAP_STATE_DRAGGING_2,
+	TAP_STATE_DEAD, /**< finger count exceeded */
+};
+
 struct tp_motion {
 	int32_t x;
 	int32_t y;
@@ -97,6 +113,14 @@ struct tp_dispatch {
 	} buttons;				/* physical buttons */
 
 	enum touchpad_event queued;
+
+	struct {
+		bool enabled;
+		int timer_fd;
+		struct libinput_source *source;
+		unsigned int timeout;
+		enum tp_tap_state state;
+	} tap;
 };
 
 #define tp_for_each_touch(_tp, _t) \
@@ -105,4 +129,13 @@ struct tp_dispatch {
 void
 tp_get_delta(struct tp_touch *t, double *dx, double *dy);
 
+int
+tp_tap_handle_state(struct tp_dispatch *tp, uint32_t time);
+
+unsigned int
+tp_tap_handle_timeout(struct tp_dispatch *tp, uint32_t time);
+
+int
+tp_init_tap(struct tp_dispatch *tp);
+
 #endif
-- 
1.8.4.2



More information about the wayland-devel mailing list