[PATCH libinput 2/2] evdev-mt-touchpad-buttons: Add support for top softbutton area
Hans de Goede
hdegoede at redhat.com
Wed May 28 06:19:56 PDT 2014
Add support for the top softbutton area found on some laptops.
For details of how this works, see the updated
doc/touchpad-softbutton-state-machine.svg diagram.
Basically this mirrors the state-machine for the bottom softbutton area, with
one exception, if a finger stays at least inner timeout milliseconds in the
top button area and then moves out of it, it will be ignored rather then
become the pointer. This is done so that people using the top buttons together
with a trackstick and accidentally move their finger out of the upper area
don't get spurious pointer movements from the finger on the trackpad.
This behavior is indentical to xf86-input-synaptics, which also ignores
movements from touches which start in the top button area.
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
doc/touchpad-softbutton-state-machine.svg | 602 ++++++++++++++++++------------
src/evdev-mt-touchpad-buttons.c | 241 +++++++++++-
src/evdev-mt-touchpad.h | 21 +-
3 files changed, 615 insertions(+), 249 deletions(-)
diff --git a/doc/touchpad-softbutton-state-machine.svg b/doc/touchpad-softbutton-state-machine.svg
index 1142343..b7028ef 100644
--- a/doc/touchpad-softbutton-state-machine.svg
+++ b/doc/touchpad-softbutton-state-machine.svg
@@ -1,390 +1,532 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1560px" height="1624px" version="1.1">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="2190px" height="1624px" version="1.1">
<defs/>
<g transform="translate(0.5,0.5)">
-<path d="M 232 441 L 257 441" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 263 441 L 256 445 L 257 441 L 256 438 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<ellipse cx="154" cy="151" rx="49.5" ry="30" fill="#ccccff" stroke="#000000" stroke-width="2" pointer-events="none"/>
+<path d="M 862 425 L 894 418" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 899 417 L 893 422 L 894 418 L 891 415 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<ellipse cx="785" cy="151" rx="49.5" ry="30" fill="#ccccff" stroke="#000000" stroke-width="2" pointer-events="none"/>
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-<text x="154" y="141">
+<text x="785" y="141">
NONE</text>
-<text x="154" y="155">
+<text x="785" y="155">
on-entry:</text>
-<text x="154" y="169">
+<text x="785" y="169">
curr = none</text>
</g>
-<rect x="82" y="391" width="150" height="101" rx="6" ry="6" fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/>
+<rect x="712" y="391" width="150" height="101" 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">
-<text x="157" y="424">
+<text x="787" y="424">
BOTTOM_NEW</text>
-<text x="157" y="438">
+<text x="787" y="438">
on-entry:</text>
-<text x="157" y="452">
+<text x="787" y="452">
curr = button</text>
-<text x="157" y="466">
+<text x="787" y="466">
start inner timeout</text>
</g>
-<rect x="392" y="392" width="130" height="100" rx="6" ry="6" fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/>
+<rect x="1023" y="392" 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">
-<text x="457" y="432">
+<text x="1088" y="425">
AREA</text>
-<text x="457" y="446">
+<text x="1088" y="439">
on-entry:</text>
-<text x="457" y="460">
+<text x="1088" y="453">
curr =area</text>
+<text x="1088" y="467">
+set_pointer()</text>
</g>
-<path d="M 284 416 C 287 413 291 411 295 411 L 329 411 C 333 411 337 413 340 416 L 360 439 C 361 441 361 442 360 443 L 340 466 C 337 469 333 471 329 471 L 295 471 C 291 471 287 469 284 466 L 264 443 C 264 442 264 441 264 439 L 284 416 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 921 376 C 923 373 927 370 932 370 L 965 370 C 970 370 974 373 976 376 L 996 404 C 997 405 997 407 996 409 L 976 436 C 974 440 970 442 965 442 L 932 442 C 927 442 923 440 921 436 L 901 409 C 900 407 900 405 901 404 L 921 376 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="312" y="438">
+<text x="949" y="403">
finger in</text>
-<text x="312" y="452">
-area</text>
+<text x="949" y="417">
+area or top</text>
</g>
-<rect x="92" y="712" width="130" height="100" rx="6" ry="6" fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/>
+<rect x="722" 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">
-<text x="157" y="766">
+<text x="787" y="766">
BOTTOM</text>
</g>
-<path d="M 129 7 C 132 4 136 2 140 2 L 174 2 C 178 2 182 4 185 7 L 205 30 C 205 31 205 33 205 34 L 185 57 C 182 60 178 62 174 62 L 140 62 C 136 62 132 60 129 57 L 109 34 C 108 33 108 31 109 30 L 129 7 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 759 7 C 762 4 766 2 770 2 L 804 2 C 808 2 812 4 815 7 L 835 30 C 836 31 836 33 835 34 L 815 57 C 812 60 808 62 804 62 L 770 62 C 766 62 762 60 759 57 L 739 34 C 739 33 739 31 739 30 L 759 7 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="157" y="29">
+<text x="787" y="29">
finger</text>
-<text x="157" y="43">
+<text x="787" y="43">
up</text>
</g>
-<path d="M 64 571 C 67 568 71 566 75 566 L 109 566 C 113 566 117 568 120 571 L 140 594 C 140 596 140 597 140 598 L 120 621 C 117 624 113 626 109 626 L 75 626 C 71 626 67 624 64 621 L 44 598 C 43 597 43 596 44 594 L 64 571 Z" fill="#000000" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 694 571 C 697 568 701 566 705 566 L 739 566 C 743 566 747 568 750 571 L 770 594 C 771 596 771 597 770 598 L 750 621 C 747 625 743 626 739 626 L 705 626 C 701 626 697 625 694 621 L 674 598 C 674 597 674 596 674 594 L 694 571 Z" fill="#000000" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<g fill="#FFFFFF" font-family="Helvetica" text-anchor="middle" font-size="12px">
-<text x="92" y="586">
+<text x="722" y="586">
phys</text>
-<text x="92" y="600">
+<text x="722" y="600">
button</text>
-<text x="92" y="614">
+<text x="722" y="614">
press</text>
</g>
-<path d="M 361 441 L 386 442" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 391 442 L 384 445 L 386 442 L 384 438 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 177 571 C 180 568 184 566 188 566 L 222 566 C 226 566 230 568 233 571 L 253 594 C 254 596 254 597 253 598 L 233 621 C 230 624 226 626 222 626 L 188 626 C 184 626 180 624 177 621 L 157 598 C 157 597 157 596 157 594 L 177 571 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 997 419 L 1017 424" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1022 425 L 1014 427 L 1017 424 L 1016 420 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 798 571 C 800 568 804 566 809 566 L 842 566 C 847 566 851 568 853 571 L 873 594 C 874 596 874 597 873 598 L 853 621 C 851 625 847 626 842 626 L 809 626 C 804 626 800 625 798 621 L 778 598 C 777 597 777 596 778 594 L 798 571 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="205" y="593">
+<text x="826" y="593">
inner</text>
-<text x="205" y="607">
+<text x="826" y="607">
timeout</text>
</g>
-<path d="M 157 492 L 189 560" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 191 565 L 185 560 L 189 560 L 191 557 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 196 626 L 173 706" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 172 711 L 170 703 L 173 706 L 177 705 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 265 693 C 267 690 271 688 275 688 L 309 688 C 314 688 318 690 320 693 L 340 716 C 341 717 341 719 340 720 L 320 743 C 318 746 314 748 309 748 L 275 748 C 271 748 267 746 265 743 L 245 720 C 244 719 244 717 245 716 L 265 693 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 787 492 L 812 560" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 814 565 L 808 560 L 812 560 L 815 558 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 819 626 L 800 706" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 799 711 L 797 703 L 800 706 L 804 705 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 895 694 C 898 690 902 688 906 688 L 940 688 C 944 688 948 690 951 694 L 971 718 C 971 719 971 721 971 722 L 951 747 C 948 750 944 752 940 752 L 906 752 C 902 752 898 750 895 747 L 875 722 C 874 721 874 719 875 718 L 895 694 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="292" y="715">
+<text x="923" y="717">
finger in</text>
-<text x="292" y="729">
-AREA</text>
+<text x="923" y="731">
+area or top</text>
</g>
-<path d="M 222 762 L 241 724" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 243 719 L 243 727 L 241 724 L 237 724 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<rect x="361" y="718" width="194" height="94" rx="6" ry="6" fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/>
+<path d="M 852 762 L 871 726" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 874 721 L 874 729 L 871 726 L 867 726 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<rect x="991" y="718" width="194" height="94" 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">
-<text x="457" y="755">
+<text x="1088" y="755">
BOTTOM_TO_AREA</text>
-<text x="457" y="769">
+<text x="1088" y="769">
on-entry:</text>
-<text x="457" y="783">
+<text x="1088" y="783">
start outer timeout</text>
</g>
-<path d="M 341 718 L 358 759" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 360 764 L 354 759 L 358 759 L 361 756 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 430 541 C 432 538 436 536 440 536 L 474 536 C 479 536 483 538 485 541 L 505 564 C 506 566 506 567 505 568 L 485 591 C 483 594 479 596 474 596 L 440 596 C 436 596 432 594 430 591 L 410 568 C 409 567 409 566 410 564 L 430 541 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 971 720 L 988 759" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 991 764 L 985 759 L 988 759 L 991 756 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1060 541 C 1063 538 1067 536 1071 536 L 1105 536 C 1109 536 1113 538 1116 541 L 1136 564 C 1136 566 1136 567 1136 568 L 1116 591 C 1113 595 1109 596 1105 596 L 1071 596 C 1067 596 1063 595 1060 591 L 1040 568 C 1039 567 1039 566 1040 564 L 1060 541 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="457" y="563">
+<text x="1088" y="563">
outer</text>
-<text x="457" y="577">
+<text x="1088" y="577">
timeout</text>
</g>
-<path d="M 457 718 L 457 603" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 457 597 L 461 604 L 457 603 L 454 604 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 457 536 L 457 498" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 457 493 L 461 500 L 457 498 L 454 500 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 135 235 C 137 232 140 230 144 230 L 170 230 C 173 230 176 232 178 235 L 194 259 C 194 260 194 262 194 263 L 178 287 C 176 290 173 292 170 292 L 144 292 C 140 292 137 290 135 287 L 120 263 C 119 262 119 260 120 259 L 135 235 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1088 718 L 1088 603" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1088 597 L 1091 604 L 1088 603 L 1084 604 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1088 536 L 1088 498" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1088 493 L 1091 500 L 1088 498 L 1084 500 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 766 235 C 768 232 771 230 774 230 L 800 230 C 803 230 806 232 808 235 L 824 259 C 824 260 824 262 824 263 L 808 287 C 806 290 803 292 800 292 L 774 292 C 771 292 768 290 766 287 L 750 263 C 750 262 750 260 750 259 L 766 235 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="157" y="258">
+<text x="787" y="258">
finger in</text>
-<text x="157" y="272">
+<text x="787" y="272">
bottom</text>
</g>
-<path d="M 155 181 L 156 224" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 156 229 L 152 222 L 156 224 L 159 222 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 157 292 L 157 384" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 157 389 L 153 382 L 157 384 L 160 382 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 438 236 C 440 233 443 231 446 231 L 469 231 C 472 231 475 233 477 236 L 491 259 C 492 260 492 262 491 263 L 477 287 C 475 290 472 292 469 292 L 446 292 C 443 292 440 290 438 287 L 424 263 C 423 262 423 260 424 259 L 438 236 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 785 181 L 786 224" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 786 229 L 783 222 L 786 224 L 790 222 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 787 292 L 787 384" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 787 390 L 784 383 L 787 384 L 791 383 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1068 236 C 1070 233 1073 231 1076 231 L 1100 231 C 1103 231 1105 233 1107 236 L 1121 259 C 1122 261 1122 262 1121 263 L 1107 287 C 1105 290 1103 292 1100 292 L 1076 292 C 1073 292 1070 290 1068 287 L 1054 263 C 1054 262 1054 261 1054 259 L 1068 236 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="457" y="258">
+<text x="1088" y="258">
finger in</text>
-<text x="457" y="272">
+<text x="1088" y="272">
area</text>
</g>
-<path d="M 457 292 L 457 385" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 457 391 L 454 384 L 457 385 L 461 384 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 204 151 L 418 246" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 422 248 L 414 249 L 418 246 L 417 242 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 290 563 C 293 559 297 556 302 556 L 338 556 C 343 556 347 559 350 563 L 372 594 C 372 595 372 597 372 599 L 350 630 C 347 634 343 636 338 636 L 302 636 C 297 636 293 634 290 630 L 268 599 C 268 597 268 595 268 594 L 290 563 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1088 292 L 1088 386" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1088 391 L 1084 384 L 1088 386 L 1091 384 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 834 151 L 1048 246" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1053 248 L 1045 249 L 1048 246 L 1048 242 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 922 563 C 925 559 930 556 934 556 L 971 556 C 975 556 980 559 983 563 L 1004 594 C 1005 595 1005 597 1004 599 L 983 630 C 980 634 975 636 971 636 L 934 636 C 930 636 925 634 922 630 L 901 599 C 900 597 900 595 901 594 L 922 563 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="320" y="586">
+<text x="952" y="586">
finger in</text>
-<text x="320" y="600">
+<text x="952" y="600">
bottom</text>
-<text x="320" y="614">
+<text x="952" y="614">
button != curr</text>
</g>
-<path d="M 295 558 L 242 487" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 238 483 L 245 486 L 242 487 L 240 490 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 419 718 L 357 641" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 353 637 L 360 640 L 357 641 L 355 645 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 92 626 L 153 707" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 156 711 L 149 708 L 153 707 L 155 703 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 157 492 L 96 561" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 92 565 L 94 558 L 96 561 L 100 562 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 266 772 C 269 767 273 765 278 765 L 314 765 C 318 765 323 767 326 772 L 347 802 C 347 804 347 806 347 808 L 326 838 C 323 842 318 845 314 845 L 278 845 C 273 845 269 842 266 838 L 245 808 C 244 806 244 804 245 802 L 266 772 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="296" y="788">
+<path d="M 927 558 L 872 487" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 869 483 L 876 486 L 872 487 L 870 491 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1050 718 L 988 641" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 985 637 L 992 641 L 988 641 L 987 645 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 722 626 L 783 707" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 786 711 L 779 708 L 783 707 L 785 703 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 787 492 L 726 562" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 723 566 L 725 558 L 726 562 L 730 563 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 896 772 C 899 768 903 765 908 765 L 944 765 C 949 765 953 768 956 772 L 977 802 C 978 804 978 806 977 808 L 956 838 C 953 843 949 845 944 845 L 908 845 C 903 845 899 843 896 838 L 875 808 C 874 806 874 804 875 802 L 896 772 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="926" y="788">
finger in</text>
-<text x="296" y="802">
+<text x="926" y="802">
bottom</text>
-<text x="296" y="816">
+<text x="926" y="816">
button == curr</text>
</g>
-<path d="M 361 765 L 349 799" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 348 804 L 347 796 L 349 799 L 353 798 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 244 805 L 225 768" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 222 763 L 229 767 L 225 768 L 222 771 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 206 712 L 276 641" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 280 637 L 277 644 L 276 641 L 272 640 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 178 492 L 263 554" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 267 557 L 259 556 L 263 554 L 263 550 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 554 765 L 728 765 Q 738 765 738 755 L 738 42 Q 738 32 728 32 L 212 32" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 206 32 L 213 28 L 212 32 L 213 35 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 92 762 L 18 762 Q 8 762 8 752 L 8 42 Q 8 32 18 32 L 102 32" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 107 32 L 100 35 L 102 32 L 100 28 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 522 442 L 728 442 Q 738 442 738 432 L 738 42 Q 738 32 728 32 L 212 32" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 206 32 L 213 28 L 212 32 L 213 35 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 82 441 L 18 441 Q 8 441 8 431 L 8 42 Q 8 32 18 32 L 102 32" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 107 32 L 100 35 L 102 32 L 100 28 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 156 62 L 156 81 Q 156 91 156 101 L 156 114" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 156 119 L 152 112 L 156 114 L 159 112 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
-<rect x="1123" y="472" 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="1183" y="489">
+<path d="M 991 765 L 980 799" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 978 804 L 977 796 L 980 799 L 984 799 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 874 805 L 855 768" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 853 763 L 859 768 L 855 768 L 853 771 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 837 712 L 908 641" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 912 637 L 909 645 L 908 641 L 904 640 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 808 492 L 895 555" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 899 558 L 891 557 L 895 555 L 895 551 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1185 765 L 1358 765 Q 1368 765 1368 755 L 1368 42 Q 1368 32 1358 32 L 842 32" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 837 32 L 844 29 L 842 32 L 844 36 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1153 442 L 1358 442 Q 1368 442 1368 432 L 1368 42 Q 1368 32 1358 32 L 842 32" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 837 32 L 844 29 L 842 32 L 844 36 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 712 441 L 668 441 Q 658 441 658 451 L 658 862" 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"/>
+<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
+<text x="1813" y="489">
Check state of</text>
-<text x="1183" y="503">
+<text x="1813" y="503">
all touches</text>
</g>
-<path d="M 1183 512 L 1183 520 Q 1183 529 1183 536 L 1183 544" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1178 536 L 1183 545 L 1187 536" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<ellipse cx="1183" cy="72" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
-<path d="M 1183 87 L 1183 114 Q 1183 124 1183 134 L 1183 160" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1178 152 L 1183 161 L 1187 152" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<rect x="1133" y="17" width="100" height="40" fill="none" stroke="none" pointer-events="none"/>
+<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"/>
+<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"/>
+<rect x="1763" y="17" width="100" height="40" fill="none" stroke="none" pointer-events="none"/>
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-<text x="1183" y="41">
+<text x="1813" y="41">
tp_post_softbutton_buttons()</text>
</g>
-<path d="M 1183 212 L 1278 267 L 1183 322 L 1088 267 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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"/>
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-<text x="1183" y="264">
+<text x="1813" y="264">
!buttons.click_pend</text>
-<text x="1183" y="278">
+<text x="1813" y="278">
&& current == old</text>
</g>
-<path d="M 1278 267 L 1338 267 Q 1348 267 1358 267 L 1425 267" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1418 271 L 1427 267 L 1418 262" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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"/>
<g fill="#000000" font-family="Helvetica" font-size="11px">
-<rect fill="#ffffff" stroke="none" x="1368" y="247" width="24" height="18" stroke-width="0"/>
-<text x="1368" y="261">
+<rect fill="#ffffff" stroke="none" x="1998" y="248" width="24" height="18" stroke-width="0"/>
+<text x="1999" y="261">
yes</text>
</g>
-<path d="M 1183 322 L 1183 332 Q 1183 342 1183 351 L 1183 360" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1178 352 L 1183 361 L 1187 352" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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"/>
<g fill="#000000" font-family="Helvetica" font-size="11px">
-<rect fill="#ffffff" stroke="none" x="1184" y="329" width="18" height="18" stroke-width="0"/>
-<text x="1185" y="339">
+<rect fill="#ffffff" stroke="none" x="1815" y="330" width="18" height="18" stroke-width="0"/>
+<text x="1815" y="339">
no</text>
</g>
-<ellipse cx="1443" cy="267" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
-<ellipse cx="1443" cy="267" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
-<rect x="1078" y="112" width="200" height="60" rx="24" ry="24" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+<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"/>
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-<text x="1178" y="132">
+<text x="1808" y="132">
current = buttons.state & 0x01</text>
-<text x="1178" y="146">
+<text x="1808" y="146">
old = buttons.old_state & 0x01</text>
-<text x="1178" y="160">
+<text x="1808" y="160">
button = 0</text>
</g>
-<path d="M 1183 172 L 1183 182 Q 1183 192 1183 201 L 1183 210" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1178 202 L 1183 211 L 1187 202" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1183 546 L 1298 617 L 1183 688 L 1068 617 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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"/>
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-<text x="1183" y="621">
+<text x="1813" y="611">
All touches are in state none</text>
</g>
-<path d="M 1183 688 L 1183 696 Q 1183 703 1183 709 L 1183 716" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1178 708 L 1183 717 L 1187 708" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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"/>
<g fill="#000000" font-family="Helvetica" font-size="11px">
-<rect fill="#ffffff" stroke="none" x="1184" y="685" width="18" height="18" stroke-width="0"/>
-<text x="1185" y="698">
+<rect fill="#ffffff" stroke="none" x="1820" y="683" width="18" height="18" stroke-width="0"/>
+<text x="1820" y="696">
no</text>
</g>
-<path d="M 1298 617 L 1308 617 Q 1318 617 1327 617 L 1335 617" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1328 622 L 1337 617 L 1328 613" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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"/>
<g fill="#000000" font-family="Helvetica" font-size="11px">
-<rect fill="#ffffff" stroke="none" x="1299" y="625" width="24" height="18" stroke-width="0"/>
-<text x="1300" y="634">
+<rect fill="#ffffff" stroke="none" x="1930" y="615" width="24" height="18" stroke-width="0"/>
+<text x="1930" y="624">
yes</text>
</g>
-<rect x="1338" y="597" width="150" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+<rect x="1968" y="587" 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="1413" y="621">
+<text x="2043" y="611">
buttons.click_pend = 1</text>
</g>
-<path d="M 1488 617 L 1498 617 Q 1508 617 1517 617 L 1525 617" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1518 622 L 1527 617 L 1518 613" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1183 718 L 1298 789 L 1183 860 L 1068 789 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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"/>
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-<text x="1183" y="793">
-(Some touches are in right) &&</text>
-<text x="1183" y="807">
-(Some touches are in left)</text>
-</g>
-<path d="M 1298 789 L 1308 789 Q 1318 789 1327 789 L 1335 789" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1328 794 L 1337 789 L 1328 785" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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>
+</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"/>
<g fill="#000000" font-family="Helvetica" font-size="11px">
-<rect fill="#ffffff" stroke="none" x="1301" y="797" width="24" height="18" stroke-width="0"/>
-<text x="1302" y="806">
+<rect fill="#ffffff" stroke="none" x="1941" y="795" width="24" height="18" stroke-width="0"/>
+<text x="1942" y="804">
yes</text>
</g>
-<rect x="1338" y="769" width="160" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+<rect x="1968" y="767" 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="1418" y="793">
+<text x="2048" y="791">
button = BTN_MIDDLE</text>
</g>
-<path d="M 1498 789 L 1528 789 Q 1538 789 1538 799 L 1538 1207 Q 1538 1217 1528 1217 L 1282 1217" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1290 1212 L 1281 1217 L 1290 1221" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1183 362 L 1245 396 L 1183 431 L 1120 396 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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"/>
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-<text x="1183" y="400">
+<text x="1813" y="400">
current</text>
</g>
-<path d="M 1120 396 L 971 396 Q 961 396 961 406 L 961 1172 Q 961 1182 961 1182 L 961 1182" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 965 1180 L 961 1182 L 965 1184" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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"/>
<g fill="#000000" font-family="Helvetica" font-size="11px">
-<rect fill="#ffffff" stroke="none" x="1057" y="377" width="18" height="18" stroke-width="0"/>
-<text x="1058" y="390">
+<rect fill="#ffffff" stroke="none" x="1688" y="377" width="18" height="18" stroke-width="0"/>
+<text x="1688" y="390">
no</text>
</g>
-<path d="M 1183 431 L 1183 441 Q 1183 451 1183 460 L 1183 470" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1178 462 L 1183 471 L 1187 462" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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"/>
<g fill="#000000" font-family="Helvetica" font-size="11px">
-<rect fill="#ffffff" stroke="none" x="1184" y="438" width="24" height="18" stroke-width="0"/>
-<text x="1185" y="448">
+<rect fill="#ffffff" stroke="none" x="1815" y="438" width="24" height="18" stroke-width="0"/>
+<text x="1815" y="448">
yes</text>
</g>
-<path d="M 1183 902 L 1279 967 L 1183 1032 L 1086 967 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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">
-<text x="1183" y="971">
+<text x="1813" y="971">
Some touches are in right</text>
</g>
-<path d="M 1279 967 L 1298 967 Q 1308 967 1318 967 L 1335 967" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1328 971 L 1337 967 L 1328 962" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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="1309" y="984" width="24" height="18" stroke-width="0"/>
-<text x="1310" y="994">
+<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 1183 860 L 1183 871 Q 1183 881 1183 890 L 1183 900" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1178 892 L 1183 901 L 1187 892" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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 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="1184" y="863" width="18" height="18" stroke-width="0"/>
-<text x="1185" y="877">
+<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="1338" y="947" width="160" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+<rect x="1968" y="947" 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="1418" y="971">
+<text x="2048" y="971">
button = BTN_RIGHT</text>
</g>
-<rect x="1103" y="1082" width="160" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+<rect x="1733" y="1082" 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="1183" y="1106">
+<text x="1813" y="1106">
button = BTN_LEFT</text>
</g>
-<path d="M 1183 1032 L 1183 1047 Q 1183 1057 1183 1067 L 1183 1080" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1178 1072 L 1183 1081 L 1187 1072" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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="1184" y="1039" width="18" height="18" stroke-width="0"/>
-<text x="1185" y="1053">
+<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="1085" y="1182" width="195" height="70" rx="28" ry="28" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+<rect x="1716" y="1182" width="195" 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="1183" y="1214">
+<text x="1813" y="1214">
buttons.active = button</text>
-<text x="1183" y="1228">
+<text x="1813" y="1228">
state = BUTTON_PRESSED</text>
</g>
-<path d="M 1183 1252 L 1183 1282 Q 1183 1292 1173 1292 L 1083 1292 Q 1073 1292 1073 1302 L 1073 1330" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1068 1322 L 1073 1331 L 1077 1322" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1183 1122 L 1183 1142 Q 1183 1152 1183 1162 L 1183 1180" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1178 1172 L 1183 1181 L 1187 1172" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1498 967 L 1528 967 Q 1538 967 1538 977 L 1538 1207 Q 1538 1217 1528 1217 L 1282 1217" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1290 1212 L 1281 1217 L 1290 1221" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<rect x="863" y="1182" width="195" height="70" rx="28" ry="28" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+<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 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"/>
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
-<text x="960" y="1207">
+<text x="1591" y="1207">
button = buttons.active</text>
-<text x="960" y="1221">
+<text x="1591" y="1221">
buttons.active = 0</text>
-<text x="960" y="1235">
+<text x="1591" y="1235">
state = BUTTON_RELEASED</text>
</g>
-<rect x="998" y="1332" width="150" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+<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">
-<text x="1073" y="1356">
+<text x="1703" y="1356">
buttons.click_pend = 0</text>
</g>
-<path d="M 1073 1372 L 1073 1379 Q 1073 1387 1073 1393 L 1073 1400" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1068 1392 L 1073 1401 L 1077 1392" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 960 1252 L 960 1282 Q 960 1292 970 1292 L 1063 1292 Q 1073 1292 1073 1302 L 1073 1330" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1068 1322 L 1073 1331 L 1077 1322" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1073 1402 L 1113 1422 L 1073 1442 L 1033 1422 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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 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">
-<text x="1073" y="1426">
+<text x="1703" y="1426">
button</text>
</g>
-<path d="M 1113 1422 L 1178 1422 Q 1188 1422 1188 1432 L 1188 1597 Q 1188 1607 1178 1607 L 1090 1607" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1098 1602 L 1089 1607 L 1098 1611" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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="1114" y="1402" width="18" height="18" stroke-width="0"/>
-<text x="1115" y="1416">
+<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 1073 1442 L 1073 1452 Q 1073 1462 1073 1471 L 1073 1480" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1068 1472 L 1073 1481 L 1077 1472" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
+<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="1074" y="1449" width="24" height="18" stroke-width="0"/>
-<text x="1075" y="1459">
+<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="988" y="1482" width="170" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
+<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="1073" y="1499">
+<text x="1703" y="1499">
pointer_notify_button(</text>
-<text x="1073" y="1513">
+<text x="1703" y="1513">
button, state)</text>
</g>
-<path d="M 1073 1522 L 1073 1542 Q 1073 1552 1073 1562 L 1073 1590" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<path d="M 1068 1582 L 1073 1591 L 1077 1582" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
-<ellipse cx="1073" cy="1607" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
-<ellipse cx="1073" cy="1607" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
-<ellipse cx="1543" cy="617" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
-<ellipse cx="1543" cy="617" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
+<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"/>
+<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>
+<text x="477" y="269">
+top</text>
+</g>
+<path d="M 722 762 L 668 762 Q 658 762 658 772 L 658 892 Q 658 902 668 902 L 1358 902 Q 1368 902 1368 892 L 1368 52" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 735 151 L 520 243" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 515 245 L 520 239 L 520 243 L 523 245 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<rect x="402" y="392" width="150" height="101" 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">
+<text x="477" y="425">
+TOP_NEW</text>
+<text x="477" y="439">
+on-entry:</text>
+<text x="477" y="453">
+curr = button</text>
+<text x="477" y="467">
+start inner 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 552 442 L 648 442 Q 658 442 658 452 L 658 872" 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">
+<text x="477" y="766">
+TOP</text>
+</g>
+<path d="M 542 762 L 648 762 Q 658 762 658 772 L 658 872" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 524 571 C 527 568 531 566 535 566 L 569 566 C 573 566 577 568 580 571 L 600 594 C 601 596 601 597 600 598 L 580 621 C 577 625 573 626 569 626 L 535 626 C 531 626 527 625 524 621 L 504 598 C 504 597 504 596 504 594 L 524 571 Z" fill="#000000" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
+<g fill="#FFFFFF" font-family="Helvetica" text-anchor="middle" font-size="12px">
+<text x="552" y="586">
+phys</text>
+<text x="552" y="600">
+button</text>
+<text x="552" y="614">
+press</text>
+</g>
+<path d="M 412 571 C 414 568 418 566 423 566 L 456 566 C 461 566 465 568 467 571 L 487 594 C 488 596 488 597 487 598 L 467 621 C 465 625 461 626 456 626 L 423 626 C 418 626 414 625 412 621 L 392 598 C 391 597 391 596 392 594 L 412 571 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="440" y="593">
+inner</text>
+<text x="440" y="607">
+timeout</text>
+</g>
+<path d="M 280 563 C 283 559 288 556 292 556 L 329 556 C 333 556 338 559 341 563 L 362 594 C 363 595 363 597 362 599 L 341 630 C 338 634 333 636 329 636 L 292 636 C 288 636 283 634 280 630 L 259 599 C 258 597 258 595 259 594 L 280 563 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="310" y="586">
+finger in</text>
+<text x="310" y="600">
+top</text>
+<text x="310" y="614">
+button != curr</text>
+</g>
+<path d="M 477 493 L 547 562" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 551 566 L 544 563 L 547 562 L 549 558 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 477 493 L 442 561" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 440 565 L 440 558 L 442 561 L 446 561 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 465 492 L 368 557" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 364 560 L 368 554 L 368 557 L 371 559 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 344 556 L 396 494" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 399 490 L 397 497 L 396 494 L 392 493 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 440 626 L 470 703" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 472 708 L 466 703 L 470 703 L 472 700 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 552 626 L 503 704" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 501 708 L 501 700 L 503 704 L 507 704 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 427 712 L 355 641" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 351 637 L 359 640 L 355 641 L 354 645 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 636 325 C 638 321 642 319 645 319 L 675 319 C 679 319 682 321 684 325 L 702 353 C 702 354 702 356 702 357 L 684 385 C 682 389 679 391 675 391 L 645 391 C 642 391 638 389 636 385 L 618 357 C 618 356 618 354 618 353 L 636 325 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="660" y="345">
+finger in</text>
+<text x="660" y="359">
+area or</text>
+<text x="660" y="373">
+bottom</text>
+</g>
+<path d="M 702 355 L 1048 355 Q 1058 355 1058 365 L 1058 386" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 1058 391 L 1055 384 L 1058 386 L 1062 384 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 612 355 L 518 355 Q 508 355 508 365 L 508 392" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 617 355 L 610 359 L 612 355 L 610 352 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<rect x="66" y="715" width="194" height="94" 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">
+<text x="163" y="752">
+TOP_TO_IGNORE</text>
+<text x="163" y="766">
+on-entry:</text>
+<text x="163" y="780">
+start outer timeout</text>
+</g>
+<path d="M 301 678 C 304 674 309 672 314 672 L 352 672 C 357 672 362 674 365 678 L 387 708 C 388 709 388 711 387 713 L 365 742 C 362 746 357 748 352 748 L 314 748 C 309 748 304 746 301 742 L 279 713 C 278 711 278 709 279 708 L 301 678 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="333" y="700">
+finger in</text>
+<text x="333" y="714">
+area or bottom</text>
+</g>
+<path d="M 304 769 C 307 765 311 762 316 762 L 352 762 C 357 762 361 765 364 769 L 385 799 C 386 801 386 803 385 805 L 364 835 C 361 840 357 842 352 842 L 316 842 C 311 842 307 840 304 835 L 283 805 C 282 803 282 801 283 799 L 304 769 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="334" y="785">
+finger in</text>
+<text x="334" y="799">
+top</text>
+<text x="334" y="813">
+button == curr</text>
+</g>
+<path d="M 278 710 L 262 756" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 260 761 L 259 753 L 262 756 L 266 756 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 279 797 L 260 762" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 282 801 L 275 797 L 279 797 L 281 793 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 412 762 L 391 716" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 388 711 L 395 716 L 391 716 L 388 719 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 409 767 L 386 802" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 411 763 L 410 771 L 409 767 L 405 767 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 238 712 L 282 642" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 285 637 L 284 645 L 282 642 L 278 641 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<rect x="98" y="391" 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">
+<text x="163" y="431">
+IGNORE</text>
+<text x="163" y="445">
+on-entry:</text>
+<text x="163" y="459">
+curr =none</text>
+</g>
+<path d="M 135 541 C 138 538 142 536 146 536 L 180 536 C 184 536 188 538 191 541 L 211 564 C 211 566 211 567 211 568 L 191 591 C 188 595 184 596 180 596 L 146 596 C 142 596 138 595 135 591 L 115 568 C 114 567 114 566 115 564 L 135 541 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="163" y="563">
+outer</text>
+<text x="163" y="577">
+timeout</text>
+</g>
+<path d="M 163 536 L 163 497" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 163 492 L 166 499 L 163 497 L 159 499 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 163 715 L 163 603" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 163 597 L 166 604 L 163 603 L 159 604 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
+<path d="M 98 441 L 18 441 Q 8 441 8 431 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 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"/>
</g>
</svg>
diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index b4d3920..566880f 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -31,6 +31,10 @@
#include "evdev-mt-touchpad.h"
+#ifndef INPUT_PROP_TOPBUTTONPAD
+#define INPUT_PROP_TOPBUTTONPAD 0x04
+#endif
+
#define DEFAULT_BUTTON_MOTION_THRESHOLD 0.02 /* 2% of size */
#define DEFAULT_BUTTON_ENTER_TIMEOUT 100 /* ms */
#define DEFAULT_BUTTON_LEAVE_TIMEOUT 300 /* ms */
@@ -56,6 +60,10 @@ button_state_to_str(enum button_state state) {
CASE_RETURN_STRING(BUTTON_STATE_BOTTOM);
CASE_RETURN_STRING(BUTTON_STATE_BOTTOM_NEW);
CASE_RETURN_STRING(BUTTON_STATE_BOTTOM_TO_AREA);
+ CASE_RETURN_STRING(BUTTON_STATE_TOP);
+ CASE_RETURN_STRING(BUTTON_STATE_TOP_NEW);
+ CASE_RETURN_STRING(BUTTON_STATE_TOP_TO_IGNORE);
+ CASE_RETURN_STRING(BUTTON_STATE_IGNORE);
}
return NULL;
}
@@ -65,6 +73,9 @@ button_event_to_str(enum button_event event) {
switch(event) {
CASE_RETURN_STRING(BUTTON_EVENT_IN_BOTTOM_R);
CASE_RETURN_STRING(BUTTON_EVENT_IN_BOTTOM_L);
+ CASE_RETURN_STRING(BUTTON_EVENT_IN_TOP_R);
+ CASE_RETURN_STRING(BUTTON_EVENT_IN_TOP_M);
+ CASE_RETURN_STRING(BUTTON_EVENT_IN_TOP_L);
CASE_RETURN_STRING(BUTTON_EVENT_IN_AREA);
CASE_RETURN_STRING(BUTTON_EVENT_UP);
CASE_RETURN_STRING(BUTTON_EVENT_PRESS);
@@ -94,6 +105,34 @@ is_inside_bottom_left_area(struct tp_dispatch *tp, struct tp_touch *t)
!is_inside_bottom_right_area(tp, t);
}
+static inline bool
+is_inside_top_button_area(struct tp_dispatch *tp, struct tp_touch *t)
+{
+ return t->y <= tp->buttons.top_area.bottom_edge;
+}
+
+static inline bool
+is_inside_top_right_area(struct tp_dispatch *tp, struct tp_touch *t)
+{
+ return is_inside_top_button_area(tp, t) &&
+ t->x > tp->buttons.top_area.rightbutton_left_edge;
+}
+
+static inline bool
+is_inside_top_left_area(struct tp_dispatch *tp, struct tp_touch *t)
+{
+ return is_inside_top_button_area(tp, t) &&
+ t->x < tp->buttons.top_area.leftbutton_right_edge;
+}
+
+static inline bool
+is_inside_top_middle_area(struct tp_dispatch *tp, struct tp_touch *t)
+{
+ return is_inside_top_button_area(tp, t) &&
+ t->x >= tp->buttons.top_area.leftbutton_right_edge &&
+ t->x <= tp->buttons.top_area.rightbutton_left_edge;
+}
+
static void
tp_button_set_timer(struct tp_dispatch *tp, uint64_t timeout)
{
@@ -153,6 +192,18 @@ tp_button_set_state(struct tp_dispatch *tp, struct tp_touch *t,
case BUTTON_STATE_BOTTOM_TO_AREA:
tp_button_set_leave_timer(tp, t);
break;
+ case BUTTON_STATE_TOP:
+ break;
+ case BUTTON_STATE_TOP_NEW:
+ t->button.curr = event;
+ tp_button_set_enter_timer(tp, t);
+ break;
+ case BUTTON_STATE_TOP_TO_IGNORE:
+ tp_button_set_leave_timer(tp, t);
+ break;
+ case BUTTON_STATE_IGNORE:
+ t->button.curr = 0;
+ break;
}
}
@@ -166,6 +217,11 @@ tp_button_none_handle_event(struct tp_dispatch *tp,
case BUTTON_EVENT_IN_BOTTOM_L:
tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_NEW, event);
break;
+ case BUTTON_EVENT_IN_TOP_R:
+ case BUTTON_EVENT_IN_TOP_M:
+ case BUTTON_EVENT_IN_TOP_L:
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP_NEW, event);
+ break;
case BUTTON_EVENT_IN_AREA:
tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
break;
@@ -187,6 +243,9 @@ tp_button_area_handle_event(struct tp_dispatch *tp,
switch (event) {
case BUTTON_EVENT_IN_BOTTOM_R:
case BUTTON_EVENT_IN_BOTTOM_L:
+ case BUTTON_EVENT_IN_TOP_R:
+ case BUTTON_EVENT_IN_TOP_M:
+ case BUTTON_EVENT_IN_TOP_L:
case BUTTON_EVENT_IN_AREA:
break;
case BUTTON_EVENT_UP:
@@ -212,6 +271,9 @@ tp_button_bottom_handle_event(struct tp_dispatch *tp,
event);
break;
case BUTTON_EVENT_IN_AREA:
+ case BUTTON_EVENT_IN_TOP_R:
+ case BUTTON_EVENT_IN_TOP_M:
+ case BUTTON_EVENT_IN_TOP_L:
tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_TO_AREA, event);
break;
case BUTTON_EVENT_UP:
@@ -237,6 +299,9 @@ tp_button_bottom_new_handle_event(struct tp_dispatch *tp,
event);
break;
case BUTTON_EVENT_IN_AREA:
+ case BUTTON_EVENT_IN_TOP_R:
+ case BUTTON_EVENT_IN_TOP_M:
+ case BUTTON_EVENT_IN_TOP_L:
tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
break;
case BUTTON_EVENT_UP:
@@ -268,6 +333,9 @@ tp_button_bottom_to_area_handle_event(struct tp_dispatch *tp,
tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_NEW,
event);
break;
+ case BUTTON_EVENT_IN_TOP_R:
+ case BUTTON_EVENT_IN_TOP_M:
+ case BUTTON_EVENT_IN_TOP_L:
case BUTTON_EVENT_IN_AREA:
break;
case BUTTON_EVENT_UP:
@@ -283,6 +351,121 @@ tp_button_bottom_to_area_handle_event(struct tp_dispatch *tp,
}
static void
+tp_button_top_handle_event(struct tp_dispatch *tp,
+ struct tp_touch *t,
+ enum button_event event)
+{
+ switch (event) {
+ case BUTTON_EVENT_IN_TOP_R:
+ case BUTTON_EVENT_IN_TOP_M:
+ case BUTTON_EVENT_IN_TOP_L:
+ if (event != t->button.curr)
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP_NEW,
+ event);
+ break;
+ case BUTTON_EVENT_IN_AREA:
+ case BUTTON_EVENT_IN_BOTTOM_R:
+ case BUTTON_EVENT_IN_BOTTOM_L:
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP_TO_IGNORE, event);
+ break;
+ case BUTTON_EVENT_UP:
+ tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
+ break;
+ case BUTTON_EVENT_PRESS:
+ case BUTTON_EVENT_RELEASE:
+ case BUTTON_EVENT_TIMEOUT:
+ break;
+ }
+}
+
+static void
+tp_button_top_new_handle_event(struct tp_dispatch *tp,
+ struct tp_touch *t,
+ enum button_event event)
+{
+ switch(event) {
+ case BUTTON_EVENT_IN_TOP_R:
+ case BUTTON_EVENT_IN_TOP_M:
+ case BUTTON_EVENT_IN_TOP_L:
+ if (event != t->button.curr)
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP_NEW,
+ event);
+ break;
+ case BUTTON_EVENT_IN_AREA:
+ case BUTTON_EVENT_IN_BOTTOM_R:
+ case BUTTON_EVENT_IN_BOTTOM_L:
+ tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
+ break;
+ case BUTTON_EVENT_UP:
+ tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
+ break;
+ case BUTTON_EVENT_PRESS:
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP, event);
+ break;
+ case BUTTON_EVENT_RELEASE:
+ break;
+ case BUTTON_EVENT_TIMEOUT:
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP, event);
+ break;
+ }
+}
+
+static void
+tp_button_top_to_ignore_handle_event(struct tp_dispatch *tp,
+ struct tp_touch *t,
+ enum button_event event)
+{
+ switch(event) {
+ case BUTTON_EVENT_IN_TOP_R:
+ case BUTTON_EVENT_IN_TOP_M:
+ case BUTTON_EVENT_IN_TOP_L:
+ if (event == t->button.curr)
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP,
+ event);
+ else
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP_NEW,
+ event);
+ break;
+ case BUTTON_EVENT_IN_BOTTOM_R:
+ case BUTTON_EVENT_IN_BOTTOM_L:
+ case BUTTON_EVENT_IN_AREA:
+ break;
+ case BUTTON_EVENT_UP:
+ tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
+ break;
+ case BUTTON_EVENT_PRESS:
+ case BUTTON_EVENT_RELEASE:
+ break;
+ case BUTTON_EVENT_TIMEOUT:
+ tp_button_set_state(tp, t, BUTTON_STATE_IGNORE, event);
+ break;
+ }
+}
+
+static void
+tp_button_ignore_handle_event(struct tp_dispatch *tp,
+ struct tp_touch *t,
+ enum button_event event)
+{
+ switch (event) {
+ case BUTTON_EVENT_IN_BOTTOM_R:
+ case BUTTON_EVENT_IN_BOTTOM_L:
+ case BUTTON_EVENT_IN_TOP_R:
+ case BUTTON_EVENT_IN_TOP_M:
+ case BUTTON_EVENT_IN_TOP_L:
+ case BUTTON_EVENT_IN_AREA:
+ break;
+ case BUTTON_EVENT_UP:
+ tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
+ break;
+ case BUTTON_EVENT_PRESS:
+ case BUTTON_EVENT_RELEASE:
+ case BUTTON_EVENT_TIMEOUT:
+ break;
+ }
+}
+
+static void
tp_button_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
enum button_event event,
@@ -306,6 +489,18 @@ tp_button_handle_event(struct tp_dispatch *tp,
case BUTTON_STATE_BOTTOM_TO_AREA:
tp_button_bottom_to_area_handle_event(tp, t, event);
break;
+ case BUTTON_STATE_TOP:
+ tp_button_top_handle_event(tp, t, event);
+ break;
+ case BUTTON_STATE_TOP_NEW:
+ tp_button_top_new_handle_event(tp, t, event);
+ break;
+ case BUTTON_STATE_TOP_TO_IGNORE:
+ tp_button_top_to_ignore_handle_event(tp, t, event);
+ break;
+ case BUTTON_STATE_IGNORE:
+ tp_button_ignore_handle_event(tp, t, event);
+ break;
}
if (current != t->button.state)
@@ -331,6 +526,12 @@ tp_button_handle_state(struct tp_dispatch *tp, uint64_t time)
tp_button_handle_event(tp, t, BUTTON_EVENT_IN_BOTTOM_R, time);
else if (is_inside_bottom_left_area(tp, t))
tp_button_handle_event(tp, t, BUTTON_EVENT_IN_BOTTOM_L, time);
+ else if (is_inside_top_right_area(tp, t))
+ tp_button_handle_event(tp, t, BUTTON_EVENT_IN_TOP_R, time);
+ else if (is_inside_top_middle_area(tp, t))
+ tp_button_handle_event(tp, t, BUTTON_EVENT_IN_TOP_M, time);
+ else if (is_inside_top_left_area(tp, t))
+ tp_button_handle_event(tp, t, BUTTON_EVENT_IN_TOP_L, time);
else
tp_button_handle_event(tp, t, BUTTON_EVENT_IN_AREA, time);
}
@@ -412,6 +613,8 @@ tp_init_buttons(struct tp_dispatch *tp,
tp->buttons.is_clickpad = libevdev_has_property(device->evdev,
INPUT_PROP_BUTTONPAD);
+ tp->buttons.has_topbuttons = libevdev_has_property(device->evdev,
+ INPUT_PROP_TOPBUTTONPAD);
if (libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE) ||
libevdev_has_event_code(device->evdev, EV_KEY, BTN_RIGHT)) {
@@ -434,8 +637,16 @@ tp_init_buttons(struct tp_dispatch *tp,
if (tp->buttons.is_clickpad && !tp->buttons.use_clickfinger) {
tp->buttons.bottom_area.top_edge = height * .8 + device->abs.min_y;
tp->buttons.bottom_area.rightbutton_left_edge = width/2 + device->abs.min_x;
- tp->buttons.timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
+ if (tp->buttons.has_topbuttons) {
+ tp->buttons.top_area.bottom_edge = height * .08 + device->abs.min_y;
+ tp->buttons.top_area.rightbutton_left_edge = width * .58 + device->abs.min_x;
+ tp->buttons.top_area.leftbutton_right_edge = width * .42 + device->abs.min_x;
+ } else {
+ tp->buttons.top_area.bottom_edge = 0;
+ }
+
+ tp->buttons.timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
if (tp->buttons.timer_fd == -1)
return -1;
@@ -448,6 +659,7 @@ tp_init_buttons(struct tp_dispatch *tp,
return -1;
} else {
tp->buttons.bottom_area.top_edge = INT_MAX;
+ tp->buttons.top_area.bottom_edge = 0;
}
return 0;
@@ -540,7 +752,7 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
{
uint32_t current, old, button;
enum libinput_pointer_button_state state;
- enum { AREA = 0x01, LEFT = 0x02, RIGHT = 0x04 };
+ enum { AREA = 0x01, LEFT = 0x02, MIDDLE = 0x04, RIGHT = 0x08 };
current = tp->buttons.state;
old = tp->buttons.old_state;
@@ -558,9 +770,14 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
button |= AREA;
break;
case BUTTON_EVENT_IN_BOTTOM_L:
+ case BUTTON_EVENT_IN_TOP_L:
button |= LEFT;
break;
+ case BUTTON_EVENT_IN_TOP_M:
+ button |= MIDDLE;
+ break;
case BUTTON_EVENT_IN_BOTTOM_R:
+ case BUTTON_EVENT_IN_TOP_R:
button |= RIGHT;
break;
default:
@@ -568,24 +785,18 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
}
}
- switch (button) {
- case 0:
+ if (button == 0) {
/* No touches, wait for a touch before processing */
tp->buttons.click_pending = true;
return 0;
- case RIGHT:
- case RIGHT | AREA:
- /* Some touches in right, no touches in left */
- button = BTN_RIGHT;
- break;
- case LEFT | RIGHT:
- case LEFT | RIGHT | AREA:
- /* Some touches in left and some in right */
+ }
+
+ if ((button & MIDDLE) || ((button & LEFT) && (button & RIGHT)))
button = BTN_MIDDLE;
- break;
- default:
+ else if (button & RIGHT)
+ button = BTN_RIGHT;
+ else
button = BTN_LEFT;
- }
tp->buttons.active = button;
state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 62abe59..7bd0d12 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -49,6 +49,9 @@ enum touch_state {
enum button_event {
BUTTON_EVENT_IN_BOTTOM_R = 30,
BUTTON_EVENT_IN_BOTTOM_L,
+ BUTTON_EVENT_IN_TOP_R,
+ BUTTON_EVENT_IN_TOP_M,
+ BUTTON_EVENT_IN_TOP_L,
BUTTON_EVENT_IN_AREA,
BUTTON_EVENT_UP,
BUTTON_EVENT_PRESS,
@@ -62,6 +65,10 @@ enum button_state {
BUTTON_STATE_BOTTOM,
BUTTON_STATE_BOTTOM_NEW,
BUTTON_STATE_BOTTOM_TO_AREA,
+ BUTTON_STATE_TOP,
+ BUTTON_STATE_TOP_NEW,
+ BUTTON_STATE_TOP_TO_IGNORE,
+ BUTTON_STATE_IGNORE,
};
enum scroll_state {
@@ -155,6 +162,7 @@ struct tp_dispatch {
struct {
bool is_clickpad; /* true for clickpads */
+ bool has_topbuttons;
bool use_clickfinger; /* number of fingers decides button number */
bool click_pending;
uint32_t state;
@@ -162,16 +170,21 @@ struct tp_dispatch {
uint32_t motion_dist; /* for pinned touches */
unsigned int active; /* currently active button, for release event */
- /* Only used for clickpads. The software button area is always
- * a horizontal strip across the touchpad. Depending on the
- * rightbutton_left_edge value, the buttons are split according to the
- * edge settings.
+ /* Only used for clickpads. The software button areas are
+ * always 2 horizontal stripes across the touchpad.
+ * The buttons are split according to the edge settings.
*/
struct {
int32_t top_edge;
int32_t rightbutton_left_edge;
} bottom_area;
+ struct {
+ int32_t bottom_edge;
+ int32_t rightbutton_left_edge;
+ int32_t leftbutton_right_edge;
+ } top_area;
+
unsigned int timeout; /* current timeout in ms */
int timer_fd;
--
1.9.3
More information about the wayland-devel
mailing list