mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-04 01:10:25 +01:00
Merge branch 'wip/3-finger-pinch-gesture'
This commit is contained in:
commit
a4adea1646
13 changed files with 1954 additions and 192 deletions
|
|
@ -88,4 +88,42 @@ thus suggesting a window movement. libinput only has knowledge of the finger
|
|||
coordinates (and even then only in device coordinates, not in screen
|
||||
coordinates) and thus cannot differentiate the two.
|
||||
|
||||
@section gestures_softbuttons Gestures with enabled software buttons
|
||||
|
||||
If the touchpad device is a @ref touchpads_buttons_clickpads "Clickpad", it
|
||||
is recommended that a caller switches to @ref clickfinger.
|
||||
Usually fingers placed in a @ref software_buttons "software button area" is not
|
||||
considered for gestures, resulting in some gestures to be interpreted as
|
||||
pointer motion or two-finger scroll events.
|
||||
|
||||
@image html pinch-gestures-softbuttons.svg "Interference of software buttons and pinch gestures"
|
||||
|
||||
In the example above, the software button area is highlighted in red. The
|
||||
user executes a three-finger pinch gesture, with the thumb remaining in the
|
||||
software button area. libinput ignores fingers within the software button
|
||||
areas, the movement of the remaining fingers is thus interpreted as a
|
||||
two-finger scroll motion.
|
||||
|
||||
@section gestures_twofinger_touchpads Gestures on two-finger touchpads
|
||||
|
||||
As of kernel 4.2, many @ref touchpads_touch_partial_mt provide only two
|
||||
slots. This affects how gestures can be interpreted. Touchpads with only two
|
||||
slots can identify two touches by position but can usually tell that there
|
||||
is a third (or fourth) finger down on the touchpad - without providing
|
||||
positional information for that finger.
|
||||
|
||||
Touchpoints are assigned in sequential order and only the first two touch
|
||||
points are trackable. For libinput this produces an ambiguity where it is
|
||||
impossible to detect whether a gesture is a pinch gesture or a swipe gesture
|
||||
whenever a user puts the index and middle finger down first. Since the third
|
||||
finger does not have positional information, it's location cannot be
|
||||
determined.
|
||||
|
||||
@image html gesture-2fg-ambiguity.svg "Ambiguity of three-finger gestures on two-finger touchpads"
|
||||
|
||||
The image above illustrates this ambiguity. The index and middle finger are
|
||||
set down first, the data stream from both finger positions looks identical.
|
||||
In this case, libinput assumes the fingers are in a horizontal arrangement
|
||||
(the right image above) and use a swipe gesture.
|
||||
|
||||
*/
|
||||
|
|
|
|||
496
doc/svg/gesture-2fg-ambiguity.svg
Normal file
496
doc/svg/gesture-2fg-ambiguity.svg
Normal file
|
|
@ -0,0 +1,496 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210.95885mm"
|
||||
height="65.170769mm"
|
||||
viewBox="0 0 747.49199 230.92005"
|
||||
id="svg4313"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="gesture-2fg-ambiguity.svg">
|
||||
<defs
|
||||
id="defs4315">
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4506"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4494"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4491"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||
transform="matrix(0.4,0,0,0.4,4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker7694"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path7696"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker7562"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path7564"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4995"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker7356"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Mstart">
|
||||
<path
|
||||
transform="matrix(0.4,0,0,0.4,4,0)"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path7358"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4992"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Sstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Sstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5007"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(0.3,0,0,0.3,-0.69,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker6499"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lstart">
|
||||
<path
|
||||
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path6501"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5837"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5839"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker5365"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend">
|
||||
<path
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path5367"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5291"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5293"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4980"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4977"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.8735525"
|
||||
inkscape:cx="423.84385"
|
||||
inkscape:cy="193.39486"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata4318">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-1.110285,-124.21518)">
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.76355982;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect2858-0"
|
||||
y="127.09696"
|
||||
x="3.992065"
|
||||
height="209.27208"
|
||||
width="309.33386" />
|
||||
<g
|
||||
id="g4897"
|
||||
transform="matrix(0.64785166,-0.12161418,0.12161418,0.64785166,-136.33634,-258.03322)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path4899"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path4901"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path4903"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.64785166,-0.12161418,0.12161418,0.64785166,-167.25783,-222.59332)"
|
||||
id="g5039">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path5041"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path5043"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path5045"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g7665"
|
||||
transform="matrix(0.98639446,-0.16439576,0.16439576,0.98639446,-43.838837,-4.728819)">
|
||||
<path
|
||||
sodipodi:nodetypes="sszzzcss"
|
||||
d="m 136.26948,381.29633 c -24.01774,-7.29937 -29.0012,-10.10221 -30.51977,-10.54973 -10.672936,-3.14527 -18.270506,-5.54063 -23.777576,-13.4704 -5.50707,-7.92977 -5.34967,-20.78347 8.87612,-26.31603 14.225796,-5.53258 39.343506,8.79596 60.130606,16.16341 20.7871,7.36743 33.04562,11.44544 39.33421,13.8755 -8.10021,18.05041 -7.22128,21.15857 -10.11054,33.34117 -0.0481,0.20261 -17.87458,-5.12433 -43.93305,-13.04392 z"
|
||||
id="path2824-1-1-3"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00100005;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
d="m 107.01743,369.53232 c -10.672936,-1.94747 -17.884406,-5.64477 -21.626906,-8.75386 -8.11652,-9.03765 -6.31775,-15.03428 -3.3272,-13.99784 8.90495,-0.9097 30.203836,9.01528 33.860416,10.17935 -5.80268,11.37909 -1.08919,13.70271 -8.90631,12.57235 z"
|
||||
id="path2824-7-1-4-3"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g9940"
|
||||
transform="matrix(0.64785166,-0.12161418,0.12161418,0.64785166,-167.25783,-222.59332)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path9942"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path9944"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path9946"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
<rect
|
||||
width="309.33386"
|
||||
height="209.27208"
|
||||
x="423.99207"
|
||||
y="127.09696"
|
||||
id="rect9948"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.76355982;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<g
|
||||
transform="matrix(0.64785166,-0.12161418,0.12161418,0.64785166,283.66366,-258.03322)"
|
||||
id="g9950">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path9952"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path9954"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path9956"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g9958"
|
||||
transform="matrix(0.64785166,-0.12161418,0.12161418,0.64785166,252.74217,-222.59332)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path9960"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path9962"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path9964"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.64785166,-0.12161418,0.12161418,0.64785166,252.74217,-222.59332)"
|
||||
id="g9972">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path9974"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path9976"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path9978"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g9980"
|
||||
transform="matrix(0.64785166,-0.12161418,0.12161418,0.64785166,342.56693,-256.56067)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path9982"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path9984"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path9986"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 146.82277,201.01077 419.52386,-1.0675"
|
||||
id="path9992"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
y="188.0482"
|
||||
x="330.96494"
|
||||
height="22.417305"
|
||||
width="77.393082"
|
||||
id="rect10086"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.97799999;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.78531075" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:17.5px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="336.83612"
|
||||
y="205.01161"
|
||||
id="text10074"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan10076"
|
||||
x="336.83612"
|
||||
y="205.01161">Touch 1</tspan></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path10082"
|
||||
d="m 180.82277,169.01077 419.52386,-1.0675"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.97799999;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.78531075"
|
||||
id="rect10084"
|
||||
width="77.393082"
|
||||
height="22.417305"
|
||||
x="330.96494"
|
||||
y="156.0482" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:17.5px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="335.76865"
|
||||
y="173.66182"
|
||||
id="text10078"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan10080"
|
||||
x="335.76865"
|
||||
y="173.66182">Touch 2</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 28 KiB |
365
doc/svg/pinch-gestures-softbuttons.svg
Normal file
365
doc/svg/pinch-gestures-softbuttons.svg
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="88.927498mm"
|
||||
height="60.687836mm"
|
||||
viewBox="0 0 315.09744 215.03564"
|
||||
id="svg4313"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="pinch-gestures-softbuttons.svg">
|
||||
<defs
|
||||
id="defs4315">
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4506"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4494"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4491"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||
transform="matrix(0.4,0,0,0.4,4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker7694"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path7696"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker7562"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path7564"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4995"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker7356"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Mstart">
|
||||
<path
|
||||
transform="matrix(0.4,0,0,0.4,4,0)"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path7358"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4992"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Sstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Sstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5007"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(0.3,0,0,0.3,-0.69,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker6499"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lstart">
|
||||
<path
|
||||
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path6501"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5837"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5839"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker5365"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend">
|
||||
<path
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path5367"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5291"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5293"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4980"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4977"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.6496034"
|
||||
inkscape:cx="131.47222"
|
||||
inkscape:cy="93.839318"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata4318">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-1.110285,-124.21518)">
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.76355982;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect2858-0"
|
||||
y="127.09696"
|
||||
x="3.992065"
|
||||
height="209.27208"
|
||||
width="309.33386" />
|
||||
<g
|
||||
id="g4897"
|
||||
transform="matrix(0.64785166,-0.12161418,0.12161418,0.64785166,-136.33634,-278.03322)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path4899"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path4901"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path4903"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
<rect
|
||||
style="opacity:0.92000002;fill:#ff0000;fill-opacity:0.31073447;stroke:#000000;stroke-width:0.97799999;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.78531075"
|
||||
id="rect8337"
|
||||
width="303.45676"
|
||||
height="57.133244"
|
||||
x="6.9702415"
|
||||
y="276.61765" />
|
||||
<g
|
||||
transform="matrix(0.64785166,-0.12161418,0.12161418,0.64785166,-167.25783,-242.59332)"
|
||||
id="g5039">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path5041"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path5043"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path5045"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g7665"
|
||||
transform="matrix(0.98639446,-0.16439576,0.16439576,0.98639446,-83.838837,-24.728819)">
|
||||
<path
|
||||
sodipodi:nodetypes="sszzzcss"
|
||||
d="m 136.26948,381.29633 c -24.01774,-7.29937 -29.0012,-10.10221 -30.51977,-10.54973 -10.672936,-3.14527 -18.270506,-5.54063 -23.777576,-13.4704 -5.50707,-7.92977 -5.34967,-20.78347 8.87612,-26.31603 14.225796,-5.53258 39.343506,8.79596 60.130606,16.16341 20.7871,7.36743 33.04562,11.44544 39.33421,13.8755 -8.10021,18.05041 -7.22128,21.15857 -10.11054,33.34117 -0.0481,0.20261 -17.87458,-5.12433 -43.93305,-13.04392 z"
|
||||
id="path2824-1-1-3"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00100005;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
d="m 107.01743,369.53232 c -10.672936,-1.94747 -17.884406,-5.64477 -21.626906,-8.75386 -8.11652,-9.03765 -6.31775,-15.03428 -3.3272,-13.99784 8.90495,-0.9097 30.203836,9.01528 33.860416,10.17935 -5.80268,11.37909 -1.08919,13.70271 -8.90631,12.57235 z"
|
||||
id="path2824-7-1-4-3"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||
d="m 126.40547,189.76337 -18.14734,34.1597"
|
||||
id="path8341"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8343"
|
||||
d="m 94.40547,249.76337 -18.14734,34.1597"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Lstart)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -78,47 +78,54 @@ button_event_to_str(enum button_event event) {
|
|||
}
|
||||
|
||||
static inline bool
|
||||
is_inside_bottom_button_area(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
is_inside_bottom_button_area(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t)
|
||||
{
|
||||
return t->point.y >= tp->buttons.bottom_area.top_edge;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_inside_bottom_right_area(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
is_inside_bottom_right_area(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t)
|
||||
{
|
||||
return is_inside_bottom_button_area(tp, t) &&
|
||||
t->point.x > tp->buttons.bottom_area.rightbutton_left_edge;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_inside_bottom_left_area(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
is_inside_bottom_left_area(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t)
|
||||
{
|
||||
return is_inside_bottom_button_area(tp, t) &&
|
||||
!is_inside_bottom_right_area(tp, t);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_inside_top_button_area(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
is_inside_top_button_area(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t)
|
||||
{
|
||||
return t->point.y <= tp->buttons.top_area.bottom_edge;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_inside_top_right_area(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
is_inside_top_right_area(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t)
|
||||
{
|
||||
return is_inside_top_button_area(tp, t) &&
|
||||
t->point.x > tp->buttons.top_area.rightbutton_left_edge;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_inside_top_left_area(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
is_inside_top_left_area(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t)
|
||||
{
|
||||
return is_inside_top_button_area(tp, t) &&
|
||||
t->point.x < tp->buttons.top_area.leftbutton_right_edge;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_inside_top_middle_area(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
is_inside_top_middle_area(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t)
|
||||
{
|
||||
return is_inside_top_button_area(tp, t) &&
|
||||
t->point.x >= tp->buttons.top_area.leftbutton_right_edge &&
|
||||
|
|
@ -1042,13 +1049,15 @@ tp_post_button_events(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
int
|
||||
tp_button_touch_active(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
tp_button_touch_active(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t)
|
||||
{
|
||||
return t->button.state == BUTTON_STATE_AREA;
|
||||
}
|
||||
|
||||
bool
|
||||
tp_button_is_inside_softbutton_area(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
tp_button_is_inside_softbutton_area(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t)
|
||||
{
|
||||
return is_inside_top_button_area(tp, t) ||
|
||||
is_inside_bottom_button_area(tp, t);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ edge_event_to_str(enum scroll_event event)
|
|||
}
|
||||
|
||||
uint32_t
|
||||
tp_touch_get_edge(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
tp_touch_get_edge(const struct tp_dispatch *tp, const struct tp_touch *t)
|
||||
{
|
||||
uint32_t edge = EDGE_NONE;
|
||||
|
||||
|
|
@ -455,7 +455,8 @@ tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
int
|
||||
tp_edge_scroll_touch_active(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
tp_edge_scroll_touch_active(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t)
|
||||
{
|
||||
return t->scroll.edge_state == EDGE_SCROLL_TOUCH_STATE_AREA;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,13 +33,14 @@
|
|||
#define DEFAULT_GESTURE_2FG_SCROLL_TIMEOUT ms2us(500)
|
||||
|
||||
static inline const char*
|
||||
gesture_state_to_str(enum tp_gesture_2fg_state state)
|
||||
gesture_state_to_str(enum tp_gesture_state state)
|
||||
{
|
||||
switch (state) {
|
||||
CASE_RETURN_STRING(GESTURE_2FG_STATE_NONE);
|
||||
CASE_RETURN_STRING(GESTURE_2FG_STATE_UNKNOWN);
|
||||
CASE_RETURN_STRING(GESTURE_2FG_STATE_SCROLL);
|
||||
CASE_RETURN_STRING(GESTURE_2FG_STATE_PINCH);
|
||||
CASE_RETURN_STRING(GESTURE_STATE_NONE);
|
||||
CASE_RETURN_STRING(GESTURE_STATE_UNKNOWN);
|
||||
CASE_RETURN_STRING(GESTURE_STATE_SCROLL);
|
||||
CASE_RETURN_STRING(GESTURE_STATE_PINCH);
|
||||
CASE_RETURN_STRING(GESTURE_STATE_SWIPE);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -94,33 +95,30 @@ tp_gesture_start(struct tp_dispatch *tp, uint64_t time)
|
|||
if (tp->gesture.started)
|
||||
return;
|
||||
|
||||
switch (tp->gesture.finger_count) {
|
||||
case 2:
|
||||
switch (tp->gesture.twofinger_state) {
|
||||
case GESTURE_2FG_STATE_NONE:
|
||||
case GESTURE_2FG_STATE_UNKNOWN:
|
||||
log_bug_libinput(libinput,
|
||||
"%s in unknown gesture mode\n",
|
||||
__func__);
|
||||
break;
|
||||
case GESTURE_2FG_STATE_SCROLL:
|
||||
/* NOP */
|
||||
break;
|
||||
case GESTURE_2FG_STATE_PINCH:
|
||||
gesture_notify_pinch(&tp->device->base, time,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
|
||||
&zero, &zero, 1.0, 0.0);
|
||||
break;
|
||||
}
|
||||
switch (tp->gesture.state) {
|
||||
case GESTURE_STATE_NONE:
|
||||
case GESTURE_STATE_UNKNOWN:
|
||||
log_bug_libinput(libinput,
|
||||
"%s in unknown gesture mode\n",
|
||||
__func__);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case GESTURE_STATE_SCROLL:
|
||||
/* NOP */
|
||||
break;
|
||||
case GESTURE_STATE_PINCH:
|
||||
gesture_notify_pinch(&tp->device->base, time,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
|
||||
tp->gesture.finger_count,
|
||||
&zero, &zero, 1.0, 0.0);
|
||||
break;
|
||||
case GESTURE_STATE_SWIPE:
|
||||
gesture_notify_swipe(&tp->device->base, time,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
|
||||
tp->gesture.finger_count,
|
||||
&zero, &zero);
|
||||
break;
|
||||
}
|
||||
|
||||
tp->gesture.started = true;
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +146,7 @@ tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static unsigned int
|
||||
tp_gesture_get_active_touches(struct tp_dispatch *tp,
|
||||
tp_gesture_get_active_touches(const struct tp_dispatch *tp,
|
||||
struct tp_touch **touches,
|
||||
unsigned int count)
|
||||
{
|
||||
|
|
@ -245,83 +243,146 @@ tp_gesture_set_scroll_buildup(struct tp_dispatch *tp)
|
|||
tp->device->scroll.buildup = tp_normalize_delta(tp, average);
|
||||
}
|
||||
|
||||
static enum tp_gesture_2fg_state
|
||||
tp_gesture_twofinger_handle_state_none(struct tp_dispatch *tp, uint64_t time)
|
||||
static enum tp_gesture_state
|
||||
tp_gesture_handle_state_none(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
struct tp_touch *first, *second;
|
||||
struct tp_touch *touches[4];
|
||||
unsigned int ntouches;
|
||||
unsigned int i;
|
||||
|
||||
if (tp_gesture_get_active_touches(tp, tp->gesture.touches, 2) != 2)
|
||||
return GESTURE_2FG_STATE_NONE;
|
||||
ntouches = tp_gesture_get_active_touches(tp, touches, 4);
|
||||
if (ntouches < 2)
|
||||
return GESTURE_STATE_NONE;
|
||||
|
||||
first = tp->gesture.touches[0];
|
||||
second = tp->gesture.touches[1];
|
||||
first = touches[0];
|
||||
second = touches[1];
|
||||
|
||||
/* For 3+ finger gestures we cheat. A human hand's finger
|
||||
* arrangement means that for a 3 or 4 finger swipe gesture, the
|
||||
* fingers are roughly arranged in a horizontal line.
|
||||
* They will all move in the same direction, so we can simply look
|
||||
* at the left and right-most ones only. If we have fake touches, we
|
||||
* just take the left/right-most real touch position, since the fake
|
||||
* touch has the same location as one of those.
|
||||
*
|
||||
* For a 3 or 4 finger pinch gesture, 2 or 3 fingers are roughly in
|
||||
* a horizontal line, with the thumb below and left (right-handed
|
||||
* users) or right (left-handed users). Again, the row of non-thumb
|
||||
* fingers moves identically so we can look at the left and
|
||||
* right-most only and then treat it like a two-finger
|
||||
* gesture.
|
||||
*/
|
||||
if (ntouches > 2) {
|
||||
second = touches[0];
|
||||
|
||||
for (i = 1; i < ntouches && i < tp->num_slots; i++) {
|
||||
if (touches[i]->point.x < first->point.x)
|
||||
first = touches[i];
|
||||
else if (touches[i]->point.x > second->point.x)
|
||||
second = touches[i];
|
||||
}
|
||||
|
||||
if (first == second)
|
||||
return GESTURE_STATE_NONE;
|
||||
}
|
||||
|
||||
tp->gesture.initial_time = time;
|
||||
first->gesture.initial = first->point;
|
||||
second->gesture.initial = second->point;
|
||||
tp->gesture.touches[0] = first;
|
||||
tp->gesture.touches[1] = second;
|
||||
|
||||
return GESTURE_2FG_STATE_UNKNOWN;
|
||||
return GESTURE_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
static enum tp_gesture_2fg_state
|
||||
tp_gesture_twofinger_handle_state_unknown(struct tp_dispatch *tp, uint64_t time)
|
||||
static inline int
|
||||
tp_gesture_same_directions(int dir1, int dir2)
|
||||
{
|
||||
/*
|
||||
* In some cases (semi-mt touchpads) we may seen one finger move
|
||||
* e.g. N/NE and the other W/NW so we not only check for overlapping
|
||||
* directions, but also for neighboring bits being set.
|
||||
* The ((dira & 0x80) && (dirb & 0x01)) checks are to check for bit 0
|
||||
* and 7 being set as they also represent neighboring directions.
|
||||
*/
|
||||
return ((dir1 | (dir1 >> 1)) & dir2) ||
|
||||
((dir2 | (dir2 >> 1)) & dir1) ||
|
||||
((dir1 & 0x80) && (dir2 & 0x01)) ||
|
||||
((dir2 & 0x80) && (dir1 & 0x01));
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_gesture_init_pinch( struct tp_dispatch *tp)
|
||||
{
|
||||
tp_gesture_get_pinch_info(tp,
|
||||
&tp->gesture.initial_distance,
|
||||
&tp->gesture.angle,
|
||||
&tp->gesture.center);
|
||||
tp->gesture.prev_scale = 1.0;
|
||||
}
|
||||
|
||||
static enum tp_gesture_state
|
||||
tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
struct tp_touch *first = tp->gesture.touches[0],
|
||||
*second = tp->gesture.touches[1];
|
||||
int dir1, dir2;
|
||||
int yres = tp->device->abs.absinfo_y->resolution;
|
||||
int vert_distance;
|
||||
|
||||
/* if fingers stay unmoving for a while, assume (slow) scroll */
|
||||
if (time > (tp->gesture.initial_time + DEFAULT_GESTURE_2FG_SCROLL_TIMEOUT)) {
|
||||
/* for two-finger gestures, if the fingers stay unmoving for a
|
||||
* while, assume (slow) scroll */
|
||||
if (tp->gesture.finger_count == 2 &&
|
||||
time > (tp->gesture.initial_time + DEFAULT_GESTURE_2FG_SCROLL_TIMEOUT)) {
|
||||
tp_gesture_set_scroll_buildup(tp);
|
||||
return GESTURE_2FG_STATE_SCROLL;
|
||||
return GESTURE_STATE_SCROLL;
|
||||
}
|
||||
|
||||
/* Else check if one finger is > 20mm below the others */
|
||||
vert_distance = abs(first->point.y - second->point.y);
|
||||
if (vert_distance > 20 * yres &&
|
||||
tp->gesture.enabled) {
|
||||
tp_gesture_init_pinch(tp);
|
||||
return GESTURE_STATE_PINCH;
|
||||
}
|
||||
|
||||
/* Else wait for both fingers to have moved */
|
||||
dir1 = tp_gesture_get_direction(tp, first);
|
||||
dir2 = tp_gesture_get_direction(tp, second);
|
||||
if (dir1 == UNDEFINED_DIRECTION || dir2 == UNDEFINED_DIRECTION)
|
||||
return GESTURE_2FG_STATE_UNKNOWN;
|
||||
return GESTURE_STATE_UNKNOWN;
|
||||
|
||||
/*
|
||||
* If both touches are moving in the same direction assume scroll.
|
||||
*
|
||||
* In some cases (semi-mt touchpads) We may seen one finger move
|
||||
* e.g. N/NE and the other W/NW so we not only check for overlapping
|
||||
* directions, but also for neighboring bits being set.
|
||||
* The ((dira & 0x80) && (dirb & 0x01)) checks are to check for bit 0
|
||||
* and 7 being set as they also represent neighboring directions.
|
||||
*/
|
||||
if (((dir1 | (dir1 >> 1)) & dir2) ||
|
||||
((dir2 | (dir2 >> 1)) & dir1) ||
|
||||
((dir1 & 0x80) && (dir2 & 0x01)) ||
|
||||
((dir2 & 0x80) && (dir1 & 0x01))) {
|
||||
tp_gesture_set_scroll_buildup(tp);
|
||||
return GESTURE_2FG_STATE_SCROLL;
|
||||
/* If both touches are moving in the same direction assume
|
||||
* scroll or swipe */
|
||||
if (tp_gesture_same_directions(dir1, dir2)) {
|
||||
if (tp->gesture.finger_count == 2) {
|
||||
tp_gesture_set_scroll_buildup(tp);
|
||||
return GESTURE_STATE_SCROLL;
|
||||
} else if (tp->gesture.enabled) {
|
||||
return GESTURE_STATE_SWIPE;
|
||||
}
|
||||
} else if (tp->gesture.enabled) {
|
||||
tp_gesture_get_pinch_info(tp,
|
||||
&tp->gesture.initial_distance,
|
||||
&tp->gesture.angle,
|
||||
&tp->gesture.center);
|
||||
tp->gesture.prev_scale = 1.0;
|
||||
return GESTURE_2FG_STATE_PINCH;
|
||||
tp_gesture_init_pinch(tp);
|
||||
return GESTURE_STATE_PINCH;
|
||||
}
|
||||
|
||||
return GESTURE_2FG_STATE_UNKNOWN;
|
||||
return GESTURE_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
static enum tp_gesture_2fg_state
|
||||
tp_gesture_twofinger_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
|
||||
static enum tp_gesture_state
|
||||
tp_gesture_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
struct normalized_coords delta;
|
||||
|
||||
if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG)
|
||||
return GESTURE_2FG_STATE_SCROLL;
|
||||
return GESTURE_STATE_SCROLL;
|
||||
|
||||
/* On some semi-mt models slot 0 is more accurate, so for semi-mt
|
||||
* we only use slot 0. */
|
||||
if (tp->semi_mt) {
|
||||
if (!tp->touches[0].dirty)
|
||||
return GESTURE_2FG_STATE_SCROLL;
|
||||
return GESTURE_STATE_SCROLL;
|
||||
|
||||
delta = tp_get_delta(&tp->touches[0]);
|
||||
} else {
|
||||
|
|
@ -332,7 +393,7 @@ tp_gesture_twofinger_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
|
|||
delta = tp_filter_motion_unaccelerated(tp, &delta, time);
|
||||
|
||||
if (normalized_is_zero(delta))
|
||||
return GESTURE_2FG_STATE_SCROLL;
|
||||
return GESTURE_STATE_SCROLL;
|
||||
|
||||
tp_gesture_start(tp, time);
|
||||
evdev_post_scroll(tp->device,
|
||||
|
|
@ -340,11 +401,30 @@ tp_gesture_twofinger_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
|
|||
LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
|
||||
&delta);
|
||||
|
||||
return GESTURE_2FG_STATE_SCROLL;
|
||||
return GESTURE_STATE_SCROLL;
|
||||
}
|
||||
|
||||
static enum tp_gesture_2fg_state
|
||||
tp_gesture_twofinger_handle_state_pinch(struct tp_dispatch *tp, uint64_t time)
|
||||
static enum tp_gesture_state
|
||||
tp_gesture_handle_state_swipe(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
struct normalized_coords delta, unaccel;
|
||||
|
||||
unaccel = tp_get_average_touches_delta(tp);
|
||||
delta = tp_filter_motion(tp, &unaccel, time);
|
||||
|
||||
if (!normalized_is_zero(delta) || !normalized_is_zero(unaccel)) {
|
||||
tp_gesture_start(tp, time);
|
||||
gesture_notify_swipe(&tp->device->base, time,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
|
||||
tp->gesture.finger_count,
|
||||
&delta, &unaccel);
|
||||
}
|
||||
|
||||
return GESTURE_STATE_SWIPE;
|
||||
}
|
||||
|
||||
static enum tp_gesture_state
|
||||
tp_gesture_handle_state_pinch(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
double angle, angle_delta, distance, scale;
|
||||
struct device_float_coords center, fdelta;
|
||||
|
|
@ -368,60 +448,48 @@ tp_gesture_twofinger_handle_state_pinch(struct tp_dispatch *tp, uint64_t time)
|
|||
|
||||
if (normalized_is_zero(delta) && normalized_is_zero(unaccel) &&
|
||||
scale == tp->gesture.prev_scale && angle_delta == 0.0)
|
||||
return GESTURE_2FG_STATE_PINCH;
|
||||
return GESTURE_STATE_PINCH;
|
||||
|
||||
tp_gesture_start(tp, time);
|
||||
gesture_notify_pinch(&tp->device->base, time,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
|
||||
tp->gesture.finger_count,
|
||||
&delta, &unaccel, scale, angle_delta);
|
||||
|
||||
tp->gesture.prev_scale = scale;
|
||||
|
||||
return GESTURE_2FG_STATE_PINCH;
|
||||
return GESTURE_STATE_PINCH;
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_post_twofinger(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_post_gesture(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
enum tp_gesture_2fg_state oldstate = tp->gesture.twofinger_state;
|
||||
enum tp_gesture_state oldstate = tp->gesture.state;
|
||||
|
||||
if (tp->gesture.twofinger_state == GESTURE_2FG_STATE_NONE)
|
||||
tp->gesture.twofinger_state =
|
||||
tp_gesture_twofinger_handle_state_none(tp, time);
|
||||
if (tp->gesture.state == GESTURE_STATE_NONE)
|
||||
tp->gesture.state =
|
||||
tp_gesture_handle_state_none(tp, time);
|
||||
|
||||
if (tp->gesture.twofinger_state == GESTURE_2FG_STATE_UNKNOWN)
|
||||
tp->gesture.twofinger_state =
|
||||
tp_gesture_twofinger_handle_state_unknown(tp, time);
|
||||
if (tp->gesture.state == GESTURE_STATE_UNKNOWN)
|
||||
tp->gesture.state =
|
||||
tp_gesture_handle_state_unknown(tp, time);
|
||||
|
||||
if (tp->gesture.twofinger_state == GESTURE_2FG_STATE_SCROLL)
|
||||
tp->gesture.twofinger_state =
|
||||
tp_gesture_twofinger_handle_state_scroll(tp, time);
|
||||
if (tp->gesture.state == GESTURE_STATE_SCROLL)
|
||||
tp->gesture.state =
|
||||
tp_gesture_handle_state_scroll(tp, time);
|
||||
|
||||
if (tp->gesture.twofinger_state == GESTURE_2FG_STATE_PINCH)
|
||||
tp->gesture.twofinger_state =
|
||||
tp_gesture_twofinger_handle_state_pinch(tp, time);
|
||||
if (tp->gesture.state == GESTURE_STATE_SWIPE)
|
||||
tp->gesture.state =
|
||||
tp_gesture_handle_state_swipe(tp, time);
|
||||
|
||||
if (tp->gesture.state == GESTURE_STATE_PINCH)
|
||||
tp->gesture.state =
|
||||
tp_gesture_handle_state_pinch(tp, time);
|
||||
|
||||
log_debug(tp_libinput_context(tp),
|
||||
"gesture state: %s → %s\n",
|
||||
gesture_state_to_str(oldstate),
|
||||
gesture_state_to_str(tp->gesture.twofinger_state));
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_post_swipe(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
struct normalized_coords delta, unaccel;
|
||||
|
||||
unaccel = tp_get_average_touches_delta(tp);
|
||||
delta = tp_filter_motion(tp, &unaccel, time);
|
||||
|
||||
if (!normalized_is_zero(delta) || !normalized_is_zero(unaccel)) {
|
||||
tp_gesture_start(tp, time);
|
||||
gesture_notify_swipe(&tp->device->base, time,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
|
||||
tp->gesture.finger_count,
|
||||
&delta, &unaccel);
|
||||
}
|
||||
gesture_state_to_str(tp->gesture.state));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -446,11 +514,9 @@ tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time)
|
|||
tp_gesture_post_pointer_motion(tp, time);
|
||||
break;
|
||||
case 2:
|
||||
tp_gesture_post_twofinger(tp, time);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
tp_gesture_post_swipe(tp, time);
|
||||
tp_gesture_post_gesture(tp, time);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -470,38 +536,37 @@ static void
|
|||
tp_gesture_end(struct tp_dispatch *tp, uint64_t time, bool cancelled)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
enum tp_gesture_2fg_state twofinger_state = tp->gesture.twofinger_state;
|
||||
enum tp_gesture_state state = tp->gesture.state;
|
||||
|
||||
tp->gesture.twofinger_state = GESTURE_2FG_STATE_NONE;
|
||||
tp->gesture.state = GESTURE_STATE_NONE;
|
||||
|
||||
if (!tp->gesture.started)
|
||||
return;
|
||||
|
||||
switch (tp->gesture.finger_count) {
|
||||
case 2:
|
||||
switch (twofinger_state) {
|
||||
case GESTURE_2FG_STATE_NONE:
|
||||
case GESTURE_2FG_STATE_UNKNOWN:
|
||||
log_bug_libinput(libinput,
|
||||
"%s in unknown gesture mode\n",
|
||||
__func__);
|
||||
break;
|
||||
case GESTURE_2FG_STATE_SCROLL:
|
||||
tp_gesture_stop_twofinger_scroll(tp, time);
|
||||
break;
|
||||
case GESTURE_2FG_STATE_PINCH:
|
||||
gesture_notify_pinch_end(&tp->device->base, time,
|
||||
tp->gesture.prev_scale,
|
||||
cancelled);
|
||||
break;
|
||||
}
|
||||
switch (state) {
|
||||
case GESTURE_STATE_NONE:
|
||||
case GESTURE_STATE_UNKNOWN:
|
||||
log_bug_libinput(libinput,
|
||||
"%s in unknown gesture mode\n",
|
||||
__func__);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
gesture_notify_swipe_end(&tp->device->base, time,
|
||||
tp->gesture.finger_count, cancelled);
|
||||
case GESTURE_STATE_SCROLL:
|
||||
tp_gesture_stop_twofinger_scroll(tp, time);
|
||||
break;
|
||||
case GESTURE_STATE_PINCH:
|
||||
gesture_notify_pinch_end(&tp->device->base, time,
|
||||
tp->gesture.finger_count,
|
||||
tp->gesture.prev_scale,
|
||||
cancelled);
|
||||
break;
|
||||
case GESTURE_STATE_SWIPE:
|
||||
gesture_notify_swipe_end(&tp->device->base,
|
||||
time,
|
||||
tp->gesture.finger_count,
|
||||
cancelled);
|
||||
break;
|
||||
}
|
||||
|
||||
tp->gesture.started = false;
|
||||
}
|
||||
|
||||
|
|
@ -573,7 +638,7 @@ tp_init_gesture(struct tp_dispatch *tp)
|
|||
else
|
||||
tp->gesture.enabled = true;
|
||||
|
||||
tp->gesture.twofinger_state = GESTURE_2FG_STATE_NONE;
|
||||
tp->gesture.state = GESTURE_STATE_NONE;
|
||||
|
||||
libinput_timer_init(&tp->gesture.finger_count_switch_timer,
|
||||
tp->device->base.seat->libinput,
|
||||
|
|
|
|||
|
|
@ -1022,7 +1022,7 @@ tp_tap_resume(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
bool
|
||||
tp_tap_dragging(struct tp_dispatch *tp)
|
||||
tp_tap_dragging(const struct tp_dispatch *tp)
|
||||
{
|
||||
switch (tp->tap.state) {
|
||||
case TAP_STATE_DRAGGING:
|
||||
|
|
|
|||
|
|
@ -140,6 +140,14 @@ tp_get_touch(struct tp_dispatch *tp, unsigned int slot)
|
|||
static inline unsigned int
|
||||
tp_fake_finger_count(struct tp_dispatch *tp)
|
||||
{
|
||||
/* Only one of BTN_TOOL_DOUBLETAP/TRIPLETAP/... may be set at any
|
||||
* time */
|
||||
if (__builtin_popcount(
|
||||
tp->fake_touches & ~(FAKE_FINGER_OVERFLOW|0x1)) > 1)
|
||||
log_bug_kernel(tp->device->base.seat->libinput,
|
||||
"Invalid fake finger state %#x\n",
|
||||
tp->fake_touches);
|
||||
|
||||
if (tp->fake_touches & FAKE_FINGER_OVERFLOW)
|
||||
return FAKE_FINGER_OVERFLOW;
|
||||
else /* don't count BTN_TOUCH */
|
||||
|
|
@ -510,7 +518,7 @@ tp_pin_fingers(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
int
|
||||
tp_touch_active(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
tp_touch_active(const struct tp_dispatch *tp, const struct tp_touch *t)
|
||||
{
|
||||
return (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE) &&
|
||||
t->palm.state == PALM_NONE &&
|
||||
|
|
@ -521,7 +529,7 @@ tp_touch_active(struct tp_dispatch *tp, struct tp_touch *t)
|
|||
}
|
||||
|
||||
bool
|
||||
tp_palm_tap_is_palm(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
tp_palm_tap_is_palm(const struct tp_dispatch *tp, const struct tp_touch *t)
|
||||
{
|
||||
if (t->state != TOUCH_BEGIN)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -130,11 +130,12 @@ enum tp_edge_scroll_touch_state {
|
|||
EDGE_SCROLL_TOUCH_STATE_AREA,
|
||||
};
|
||||
|
||||
enum tp_gesture_2fg_state {
|
||||
GESTURE_2FG_STATE_NONE,
|
||||
GESTURE_2FG_STATE_UNKNOWN,
|
||||
GESTURE_2FG_STATE_SCROLL,
|
||||
GESTURE_2FG_STATE_PINCH,
|
||||
enum tp_gesture_state {
|
||||
GESTURE_STATE_NONE,
|
||||
GESTURE_STATE_UNKNOWN,
|
||||
GESTURE_STATE_SCROLL,
|
||||
GESTURE_STATE_PINCH,
|
||||
GESTURE_STATE_SWIPE,
|
||||
};
|
||||
|
||||
enum tp_thumb_state {
|
||||
|
|
@ -251,7 +252,7 @@ struct tp_dispatch {
|
|||
unsigned int finger_count;
|
||||
unsigned int finger_count_pending;
|
||||
struct libinput_timer finger_count_switch_timer;
|
||||
enum tp_gesture_2fg_state twofinger_state;
|
||||
enum tp_gesture_state state;
|
||||
struct tp_touch *touches[2];
|
||||
uint64_t initial_time;
|
||||
double initial_distance;
|
||||
|
|
@ -357,7 +358,7 @@ struct tp_dispatch {
|
|||
for (unsigned int _i = 0; _i < (_tp)->ntouches && (_t = &(_tp)->touches[_i]); _i++)
|
||||
|
||||
static inline struct libinput*
|
||||
tp_libinput_context(struct tp_dispatch *tp)
|
||||
tp_libinput_context(const struct tp_dispatch *tp)
|
||||
{
|
||||
return tp->device->base.seat->libinput;
|
||||
}
|
||||
|
|
@ -402,7 +403,7 @@ tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
|
|||
uint64_t time);
|
||||
|
||||
int
|
||||
tp_touch_active(struct tp_dispatch *tp, struct tp_touch *t);
|
||||
tp_touch_active(const struct tp_dispatch *tp, const struct tp_touch *t);
|
||||
|
||||
int
|
||||
tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time);
|
||||
|
|
@ -440,10 +441,12 @@ int
|
|||
tp_button_handle_state(struct tp_dispatch *tp, uint64_t time);
|
||||
|
||||
int
|
||||
tp_button_touch_active(struct tp_dispatch *tp, struct tp_touch *t);
|
||||
tp_button_touch_active(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t);
|
||||
|
||||
bool
|
||||
tp_button_is_inside_softbutton_area(struct tp_dispatch *tp, struct tp_touch *t);
|
||||
tp_button_is_inside_softbutton_area(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t);
|
||||
|
||||
void
|
||||
tp_release_all_taps(struct tp_dispatch *tp,
|
||||
|
|
@ -456,7 +459,7 @@ void
|
|||
tp_tap_resume(struct tp_dispatch *tp, uint64_t time);
|
||||
|
||||
bool
|
||||
tp_tap_dragging(struct tp_dispatch *tp);
|
||||
tp_tap_dragging(const struct tp_dispatch *tp);
|
||||
|
||||
int
|
||||
tp_edge_scroll_init(struct tp_dispatch *tp, struct evdev_device *device);
|
||||
|
|
@ -474,10 +477,11 @@ void
|
|||
tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time);
|
||||
|
||||
int
|
||||
tp_edge_scroll_touch_active(struct tp_dispatch *tp, struct tp_touch *t);
|
||||
tp_edge_scroll_touch_active(const struct tp_dispatch *tp,
|
||||
const struct tp_touch *t);
|
||||
|
||||
uint32_t
|
||||
tp_touch_get_edge(struct tp_dispatch *tp, struct tp_touch *t);
|
||||
tp_touch_get_edge(const struct tp_dispatch *tp, const struct tp_touch *t);
|
||||
|
||||
int
|
||||
tp_init_gesture(struct tp_dispatch *tp);
|
||||
|
|
@ -501,6 +505,6 @@ void
|
|||
tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, uint64_t time);
|
||||
|
||||
bool
|
||||
tp_palm_tap_is_palm(struct tp_dispatch *tp, struct tp_touch *t);
|
||||
tp_palm_tap_is_palm(const struct tp_dispatch *tp, const struct tp_touch *t);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -429,6 +429,7 @@ void
|
|||
gesture_notify_pinch(struct libinput_device *device,
|
||||
uint64_t time,
|
||||
enum libinput_event_type type,
|
||||
int finger_count,
|
||||
const struct normalized_coords *delta,
|
||||
const struct normalized_coords *unaccel,
|
||||
double scale,
|
||||
|
|
@ -437,6 +438,7 @@ gesture_notify_pinch(struct libinput_device *device,
|
|||
void
|
||||
gesture_notify_pinch_end(struct libinput_device *device,
|
||||
uint64_t time,
|
||||
int finger_count,
|
||||
double scale,
|
||||
int cancelled);
|
||||
|
||||
|
|
|
|||
|
|
@ -1673,25 +1673,27 @@ void
|
|||
gesture_notify_pinch(struct libinput_device *device,
|
||||
uint64_t time,
|
||||
enum libinput_event_type type,
|
||||
int finger_count,
|
||||
const struct normalized_coords *delta,
|
||||
const struct normalized_coords *unaccel,
|
||||
double scale,
|
||||
double angle)
|
||||
{
|
||||
gesture_notify(device, time, type, 2, 0, delta, unaccel,
|
||||
scale, angle);
|
||||
gesture_notify(device, time, type, finger_count, 0,
|
||||
delta, unaccel, scale, angle);
|
||||
}
|
||||
|
||||
void
|
||||
gesture_notify_pinch_end(struct libinput_device *device,
|
||||
uint64_t time,
|
||||
int finger_count,
|
||||
double scale,
|
||||
int cancelled)
|
||||
{
|
||||
const struct normalized_coords zero = { 0.0, 0.0 };
|
||||
|
||||
gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_PINCH_END,
|
||||
2, cancelled, &zero, &zero, scale, 0.0);
|
||||
finger_count, cancelled, &zero, &zero, scale, 0.0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
822
test/gestures.c
822
test/gestures.c
|
|
@ -82,13 +82,13 @@ START_TEST(gestures_swipe_3fg)
|
|||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 40, 40);
|
||||
litest_touch_down(dev, 1, 40, 50);
|
||||
litest_touch_down(dev, 2, 40, 60);
|
||||
litest_touch_down(dev, 1, 50, 40);
|
||||
litest_touch_down(dev, 2, 60, 40);
|
||||
libinput_dispatch(li);
|
||||
litest_touch_move_three_touches(dev,
|
||||
40, 40,
|
||||
40, 50,
|
||||
40, 60,
|
||||
50, 40,
|
||||
60, 40,
|
||||
dir_x, dir_y,
|
||||
10, 2);
|
||||
libinput_dispatch(li);
|
||||
|
|
@ -110,7 +110,6 @@ START_TEST(gestures_swipe_3fg)
|
|||
|
||||
dx = libinput_event_gesture_get_dx(gevent);
|
||||
dy = libinput_event_gesture_get_dy(gevent);
|
||||
debug_trace("delta: %.2f/%.2f\n", dx, dy);
|
||||
if (dir_x == 0.0)
|
||||
ck_assert(dx == 0.0);
|
||||
else if (dir_x < 0.0)
|
||||
|
|
@ -157,6 +156,345 @@ START_TEST(gestures_swipe_3fg)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(gestures_swipe_3fg_btntool)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_gesture *gevent;
|
||||
double dx, dy;
|
||||
int cardinal = _i; /* ranged test */
|
||||
double dir_x, dir_y;
|
||||
int cardinals[8][2] = {
|
||||
{ 0, 30 },
|
||||
{ 30, 30 },
|
||||
{ 30, 0 },
|
||||
{ 30, -30 },
|
||||
{ 0, -30 },
|
||||
{ -30, -30 },
|
||||
{ -30, 0 },
|
||||
{ -30, 30 },
|
||||
};
|
||||
|
||||
if (libevdev_get_num_slots(dev->evdev) > 2 ||
|
||||
!libinput_device_has_capability(dev->libinput_device,
|
||||
LIBINPUT_DEVICE_CAP_GESTURE))
|
||||
return;
|
||||
|
||||
dir_x = cardinals[cardinal][0];
|
||||
dir_y = cardinals[cardinal][1];
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 40, 40);
|
||||
litest_touch_down(dev, 1, 50, 40);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
|
||||
libinput_dispatch(li);
|
||||
litest_touch_move_two_touches(dev,
|
||||
40, 40,
|
||||
50, 40,
|
||||
dir_x, dir_y,
|
||||
10, 2);
|
||||
libinput_dispatch(li);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
|
||||
3);
|
||||
dx = libinput_event_gesture_get_dx(gevent);
|
||||
dy = libinput_event_gesture_get_dy(gevent);
|
||||
ck_assert(dx == 0.0);
|
||||
ck_assert(dy == 0.0);
|
||||
libinput_event_destroy(event);
|
||||
|
||||
while ((event = libinput_get_event(li)) != NULL) {
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
|
||||
3);
|
||||
|
||||
dx = libinput_event_gesture_get_dx(gevent);
|
||||
dy = libinput_event_gesture_get_dy(gevent);
|
||||
if (dir_x == 0.0)
|
||||
ck_assert(dx == 0.0);
|
||||
else if (dir_x < 0.0)
|
||||
ck_assert(dx < 0.0);
|
||||
else if (dir_x > 0.0)
|
||||
ck_assert(dx > 0.0);
|
||||
|
||||
if (dir_y == 0.0)
|
||||
ck_assert(dy == 0.0);
|
||||
else if (dir_y < 0.0)
|
||||
ck_assert(dy < 0.0);
|
||||
else if (dir_y > 0.0)
|
||||
ck_assert(dy > 0.0);
|
||||
|
||||
dx = libinput_event_gesture_get_dx_unaccelerated(gevent);
|
||||
dy = libinput_event_gesture_get_dy_unaccelerated(gevent);
|
||||
if (dir_x == 0.0)
|
||||
ck_assert(dx == 0.0);
|
||||
else if (dir_x < 0.0)
|
||||
ck_assert(dx < 0.0);
|
||||
else if (dir_x > 0.0)
|
||||
ck_assert(dx > 0.0);
|
||||
|
||||
if (dir_y == 0.0)
|
||||
ck_assert(dy == 0.0);
|
||||
else if (dir_y < 0.0)
|
||||
ck_assert(dy < 0.0);
|
||||
else if (dir_y > 0.0)
|
||||
ck_assert(dy > 0.0);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
litest_touch_up(dev, 0);
|
||||
litest_touch_up(dev, 1);
|
||||
libinput_dispatch(li);
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_END,
|
||||
3);
|
||||
ck_assert(!libinput_event_gesture_get_cancelled(gevent));
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(gestures_swipe_4fg)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_gesture *gevent;
|
||||
double dx, dy;
|
||||
int cardinal = _i; /* ranged test */
|
||||
double dir_x, dir_y;
|
||||
int cardinals[8][2] = {
|
||||
{ 0, 3 },
|
||||
{ 3, 3 },
|
||||
{ 3, 0 },
|
||||
{ 3, -3 },
|
||||
{ 0, -3 },
|
||||
{ -3, -3 },
|
||||
{ -3, 0 },
|
||||
{ -3, 3 },
|
||||
};
|
||||
int i;
|
||||
|
||||
if (libevdev_get_num_slots(dev->evdev) < 4)
|
||||
return;
|
||||
|
||||
dir_x = cardinals[cardinal][0];
|
||||
dir_y = cardinals[cardinal][1];
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 40, 40);
|
||||
litest_touch_down(dev, 1, 50, 40);
|
||||
litest_touch_down(dev, 2, 60, 40);
|
||||
litest_touch_down(dev, 3, 70, 40);
|
||||
libinput_dispatch(li);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
litest_push_event_frame(dev);
|
||||
|
||||
dir_x += cardinals[cardinal][0];
|
||||
dir_y += cardinals[cardinal][1];
|
||||
|
||||
litest_touch_move(dev,
|
||||
0,
|
||||
40 + dir_x,
|
||||
40 + dir_y);
|
||||
litest_touch_move(dev,
|
||||
1,
|
||||
50 + dir_x,
|
||||
40 + dir_y);
|
||||
litest_touch_move(dev,
|
||||
2,
|
||||
60 + dir_x,
|
||||
40 + dir_y);
|
||||
litest_touch_move(dev,
|
||||
3,
|
||||
70 + dir_x,
|
||||
40 + dir_y);
|
||||
litest_pop_event_frame(dev);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
libinput_dispatch(li);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
|
||||
4);
|
||||
dx = libinput_event_gesture_get_dx(gevent);
|
||||
dy = libinput_event_gesture_get_dy(gevent);
|
||||
ck_assert(dx == 0.0);
|
||||
ck_assert(dy == 0.0);
|
||||
libinput_event_destroy(event);
|
||||
|
||||
while ((event = libinput_get_event(li)) != NULL) {
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
|
||||
4);
|
||||
|
||||
dx = libinput_event_gesture_get_dx(gevent);
|
||||
dy = libinput_event_gesture_get_dy(gevent);
|
||||
if (dir_x == 0.0)
|
||||
ck_assert(dx == 0.0);
|
||||
else if (dir_x < 0.0)
|
||||
ck_assert(dx < 0.0);
|
||||
else if (dir_x > 0.0)
|
||||
ck_assert(dx > 0.0);
|
||||
|
||||
if (dir_y == 0.0)
|
||||
ck_assert(dy == 0.0);
|
||||
else if (dir_y < 0.0)
|
||||
ck_assert(dy < 0.0);
|
||||
else if (dir_y > 0.0)
|
||||
ck_assert(dy > 0.0);
|
||||
|
||||
dx = libinput_event_gesture_get_dx_unaccelerated(gevent);
|
||||
dy = libinput_event_gesture_get_dy_unaccelerated(gevent);
|
||||
if (dir_x == 0.0)
|
||||
ck_assert(dx == 0.0);
|
||||
else if (dir_x < 0.0)
|
||||
ck_assert(dx < 0.0);
|
||||
else if (dir_x > 0.0)
|
||||
ck_assert(dx > 0.0);
|
||||
|
||||
if (dir_y == 0.0)
|
||||
ck_assert(dy == 0.0);
|
||||
else if (dir_y < 0.0)
|
||||
ck_assert(dy < 0.0);
|
||||
else if (dir_y > 0.0)
|
||||
ck_assert(dy > 0.0);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
litest_touch_up(dev, 0);
|
||||
litest_touch_up(dev, 1);
|
||||
litest_touch_up(dev, 2);
|
||||
litest_touch_up(dev, 3);
|
||||
libinput_dispatch(li);
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_END,
|
||||
4);
|
||||
ck_assert(!libinput_event_gesture_get_cancelled(gevent));
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(gestures_swipe_4fg_btntool)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_gesture *gevent;
|
||||
double dx, dy;
|
||||
int cardinal = _i; /* ranged test */
|
||||
double dir_x, dir_y;
|
||||
int cardinals[8][2] = {
|
||||
{ 0, 30 },
|
||||
{ 30, 30 },
|
||||
{ 30, 0 },
|
||||
{ 30, -30 },
|
||||
{ 0, -30 },
|
||||
{ -30, -30 },
|
||||
{ -30, 0 },
|
||||
{ -30, 30 },
|
||||
};
|
||||
|
||||
if (libevdev_get_num_slots(dev->evdev) > 2 ||
|
||||
!libinput_device_has_capability(dev->libinput_device,
|
||||
LIBINPUT_DEVICE_CAP_GESTURE))
|
||||
return;
|
||||
|
||||
dir_x = cardinals[cardinal][0];
|
||||
dir_y = cardinals[cardinal][1];
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 40, 40);
|
||||
litest_touch_down(dev, 1, 50, 40);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_QUADTAP, 1);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
|
||||
libinput_dispatch(li);
|
||||
litest_touch_move_two_touches(dev,
|
||||
40, 40,
|
||||
50, 40,
|
||||
dir_x, dir_y,
|
||||
10, 2);
|
||||
libinput_dispatch(li);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
|
||||
4);
|
||||
dx = libinput_event_gesture_get_dx(gevent);
|
||||
dy = libinput_event_gesture_get_dy(gevent);
|
||||
ck_assert(dx == 0.0);
|
||||
ck_assert(dy == 0.0);
|
||||
libinput_event_destroy(event);
|
||||
|
||||
while ((event = libinput_get_event(li)) != NULL) {
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
|
||||
4);
|
||||
|
||||
dx = libinput_event_gesture_get_dx(gevent);
|
||||
dy = libinput_event_gesture_get_dy(gevent);
|
||||
if (dir_x == 0.0)
|
||||
ck_assert(dx == 0.0);
|
||||
else if (dir_x < 0.0)
|
||||
ck_assert(dx < 0.0);
|
||||
else if (dir_x > 0.0)
|
||||
ck_assert(dx > 0.0);
|
||||
|
||||
if (dir_y == 0.0)
|
||||
ck_assert(dy == 0.0);
|
||||
else if (dir_y < 0.0)
|
||||
ck_assert(dy < 0.0);
|
||||
else if (dir_y > 0.0)
|
||||
ck_assert(dy > 0.0);
|
||||
|
||||
dx = libinput_event_gesture_get_dx_unaccelerated(gevent);
|
||||
dy = libinput_event_gesture_get_dy_unaccelerated(gevent);
|
||||
if (dir_x == 0.0)
|
||||
ck_assert(dx == 0.0);
|
||||
else if (dir_x < 0.0)
|
||||
ck_assert(dx < 0.0);
|
||||
else if (dir_x > 0.0)
|
||||
ck_assert(dx > 0.0);
|
||||
|
||||
if (dir_y == 0.0)
|
||||
ck_assert(dy == 0.0);
|
||||
else if (dir_y < 0.0)
|
||||
ck_assert(dy < 0.0);
|
||||
else if (dir_y > 0.0)
|
||||
ck_assert(dy > 0.0);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
litest_touch_up(dev, 0);
|
||||
litest_touch_up(dev, 1);
|
||||
libinput_dispatch(li);
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_END,
|
||||
4);
|
||||
ck_assert(!libinput_event_gesture_get_cancelled(gevent));
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(gestures_pinch)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
|
|
@ -180,7 +518,9 @@ START_TEST(gestures_pinch)
|
|||
{ -30, 30 },
|
||||
};
|
||||
|
||||
if (libevdev_get_num_slots(dev->evdev) < 3)
|
||||
if (libevdev_get_num_slots(dev->evdev) < 2 ||
|
||||
!libinput_device_has_capability(dev->libinput_device,
|
||||
LIBINPUT_DEVICE_CAP_GESTURE))
|
||||
return;
|
||||
|
||||
dir_x = cardinals[cardinal][0];
|
||||
|
|
@ -195,13 +535,13 @@ START_TEST(gestures_pinch)
|
|||
for (i = 0; i < 8; i++) {
|
||||
litest_push_event_frame(dev);
|
||||
if (dir_x > 0.0)
|
||||
dir_x -= 3;
|
||||
dir_x -= 2;
|
||||
else if (dir_x < 0.0)
|
||||
dir_x += 3;
|
||||
dir_x += 2;
|
||||
if (dir_y > 0.0)
|
||||
dir_y -= 3;
|
||||
dir_y -= 2;
|
||||
else if (dir_y < 0.0)
|
||||
dir_y += 3;
|
||||
dir_y += 2;
|
||||
litest_touch_move(dev,
|
||||
0,
|
||||
50 + dir_x,
|
||||
|
|
@ -256,6 +596,430 @@ START_TEST(gestures_pinch)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(gestures_pinch_3fg)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_gesture *gevent;
|
||||
double dx, dy;
|
||||
int cardinal = _i; /* ranged test */
|
||||
double dir_x, dir_y;
|
||||
int i;
|
||||
double scale, oldscale;
|
||||
double angle;
|
||||
int cardinals[8][2] = {
|
||||
{ 0, 30 },
|
||||
{ 30, 30 },
|
||||
{ 30, 0 },
|
||||
{ 30, -30 },
|
||||
{ 0, -30 },
|
||||
{ -30, -30 },
|
||||
{ -30, 0 },
|
||||
{ -30, 30 },
|
||||
};
|
||||
|
||||
if (libevdev_get_num_slots(dev->evdev) < 3)
|
||||
return;
|
||||
|
||||
dir_x = cardinals[cardinal][0];
|
||||
dir_y = cardinals[cardinal][1];
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
|
||||
litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
|
||||
litest_touch_down(dev, 2, 51 - dir_x, 51 - dir_y);
|
||||
libinput_dispatch(li);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
litest_push_event_frame(dev);
|
||||
if (dir_x > 0.0)
|
||||
dir_x -= 2;
|
||||
else if (dir_x < 0.0)
|
||||
dir_x += 2;
|
||||
if (dir_y > 0.0)
|
||||
dir_y -= 2;
|
||||
else if (dir_y < 0.0)
|
||||
dir_y += 2;
|
||||
litest_touch_move(dev,
|
||||
0,
|
||||
50 + dir_x,
|
||||
50 + dir_y);
|
||||
litest_touch_move(dev,
|
||||
1,
|
||||
50 - dir_x,
|
||||
50 - dir_y);
|
||||
litest_touch_move(dev,
|
||||
2,
|
||||
51 - dir_x,
|
||||
51 - dir_y);
|
||||
litest_pop_event_frame(dev);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
|
||||
3);
|
||||
dx = libinput_event_gesture_get_dx(gevent);
|
||||
dy = libinput_event_gesture_get_dy(gevent);
|
||||
scale = libinput_event_gesture_get_scale(gevent);
|
||||
ck_assert(dx == 0.0);
|
||||
ck_assert(dy == 0.0);
|
||||
ck_assert(scale == 1.0);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
|
||||
while ((event = libinput_get_event(li)) != NULL) {
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
|
||||
3);
|
||||
|
||||
oldscale = scale;
|
||||
scale = libinput_event_gesture_get_scale(gevent);
|
||||
|
||||
ck_assert(scale < oldscale);
|
||||
|
||||
angle = libinput_event_gesture_get_angle_delta(gevent);
|
||||
ck_assert_double_le(fabs(angle), 1.0);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
litest_touch_up(dev, 0);
|
||||
litest_touch_up(dev, 1);
|
||||
litest_touch_up(dev, 2);
|
||||
libinput_dispatch(li);
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_END,
|
||||
3);
|
||||
ck_assert(!libinput_event_gesture_get_cancelled(gevent));
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(gestures_pinch_3fg_btntool)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_gesture *gevent;
|
||||
double dx, dy;
|
||||
int cardinal = _i; /* ranged test */
|
||||
double dir_x, dir_y;
|
||||
int i;
|
||||
double scale, oldscale;
|
||||
double angle;
|
||||
int cardinals[8][2] = {
|
||||
{ 0, 30 },
|
||||
{ 30, 30 },
|
||||
{ 30, 0 },
|
||||
{ 30, -30 },
|
||||
{ 0, -30 },
|
||||
{ -30, -30 },
|
||||
{ -30, 0 },
|
||||
{ -30, 30 },
|
||||
};
|
||||
|
||||
if (libevdev_get_num_slots(dev->evdev) > 2 ||
|
||||
!libinput_device_has_capability(dev->libinput_device,
|
||||
LIBINPUT_DEVICE_CAP_GESTURE))
|
||||
return;
|
||||
|
||||
dir_x = cardinals[cardinal][0];
|
||||
dir_y = cardinals[cardinal][1];
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
|
||||
litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
libinput_dispatch(li);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
litest_push_event_frame(dev);
|
||||
if (dir_x > 0.0)
|
||||
dir_x -= 2;
|
||||
else if (dir_x < 0.0)
|
||||
dir_x += 2;
|
||||
if (dir_y > 0.0)
|
||||
dir_y -= 2;
|
||||
else if (dir_y < 0.0)
|
||||
dir_y += 2;
|
||||
litest_touch_move(dev,
|
||||
0,
|
||||
50 + dir_x,
|
||||
50 + dir_y);
|
||||
litest_touch_move(dev,
|
||||
1,
|
||||
50 - dir_x,
|
||||
50 - dir_y);
|
||||
litest_pop_event_frame(dev);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
|
||||
3);
|
||||
dx = libinput_event_gesture_get_dx(gevent);
|
||||
dy = libinput_event_gesture_get_dy(gevent);
|
||||
scale = libinput_event_gesture_get_scale(gevent);
|
||||
ck_assert(dx == 0.0);
|
||||
ck_assert(dy == 0.0);
|
||||
ck_assert(scale == 1.0);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
|
||||
while ((event = libinput_get_event(li)) != NULL) {
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
|
||||
3);
|
||||
|
||||
oldscale = scale;
|
||||
scale = libinput_event_gesture_get_scale(gevent);
|
||||
|
||||
ck_assert(scale < oldscale);
|
||||
|
||||
angle = libinput_event_gesture_get_angle_delta(gevent);
|
||||
ck_assert_double_le(fabs(angle), 1.0);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
litest_touch_up(dev, 0);
|
||||
litest_touch_up(dev, 1);
|
||||
libinput_dispatch(li);
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_END,
|
||||
3);
|
||||
ck_assert(!libinput_event_gesture_get_cancelled(gevent));
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(gestures_pinch_4fg)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_gesture *gevent;
|
||||
double dx, dy;
|
||||
int cardinal = _i; /* ranged test */
|
||||
double dir_x, dir_y;
|
||||
int i;
|
||||
double scale, oldscale;
|
||||
double angle;
|
||||
int cardinals[8][2] = {
|
||||
{ 0, 30 },
|
||||
{ 30, 30 },
|
||||
{ 30, 0 },
|
||||
{ 30, -30 },
|
||||
{ 0, -30 },
|
||||
{ -30, -30 },
|
||||
{ -30, 0 },
|
||||
{ -30, 30 },
|
||||
};
|
||||
|
||||
if (libevdev_get_num_slots(dev->evdev) < 4)
|
||||
return;
|
||||
|
||||
dir_x = cardinals[cardinal][0];
|
||||
dir_y = cardinals[cardinal][1];
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
|
||||
litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
|
||||
litest_touch_down(dev, 2, 51 - dir_x, 51 - dir_y);
|
||||
litest_touch_down(dev, 3, 52 - dir_x, 52 - dir_y);
|
||||
libinput_dispatch(li);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
litest_push_event_frame(dev);
|
||||
if (dir_x > 0.0)
|
||||
dir_x -= 2;
|
||||
else if (dir_x < 0.0)
|
||||
dir_x += 2;
|
||||
if (dir_y > 0.0)
|
||||
dir_y -= 2;
|
||||
else if (dir_y < 0.0)
|
||||
dir_y += 2;
|
||||
litest_touch_move(dev,
|
||||
0,
|
||||
50 + dir_x,
|
||||
50 + dir_y);
|
||||
litest_touch_move(dev,
|
||||
1,
|
||||
50 - dir_x,
|
||||
50 - dir_y);
|
||||
litest_touch_move(dev,
|
||||
2,
|
||||
51 - dir_x,
|
||||
51 - dir_y);
|
||||
litest_touch_move(dev,
|
||||
3,
|
||||
52 - dir_x,
|
||||
52 - dir_y);
|
||||
litest_pop_event_frame(dev);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
|
||||
4);
|
||||
dx = libinput_event_gesture_get_dx(gevent);
|
||||
dy = libinput_event_gesture_get_dy(gevent);
|
||||
scale = libinput_event_gesture_get_scale(gevent);
|
||||
ck_assert(dx == 0.0);
|
||||
ck_assert(dy == 0.0);
|
||||
ck_assert(scale == 1.0);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
|
||||
while ((event = libinput_get_event(li)) != NULL) {
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
|
||||
4);
|
||||
|
||||
oldscale = scale;
|
||||
scale = libinput_event_gesture_get_scale(gevent);
|
||||
|
||||
ck_assert(scale < oldscale);
|
||||
|
||||
angle = libinput_event_gesture_get_angle_delta(gevent);
|
||||
ck_assert_double_le(fabs(angle), 1.0);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
litest_touch_up(dev, 0);
|
||||
litest_touch_up(dev, 1);
|
||||
litest_touch_up(dev, 2);
|
||||
litest_touch_up(dev, 3);
|
||||
libinput_dispatch(li);
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_END,
|
||||
4);
|
||||
ck_assert(!libinput_event_gesture_get_cancelled(gevent));
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(gestures_pinch_4fg_btntool)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_gesture *gevent;
|
||||
double dx, dy;
|
||||
int cardinal = _i; /* ranged test */
|
||||
double dir_x, dir_y;
|
||||
int i;
|
||||
double scale, oldscale;
|
||||
double angle;
|
||||
int cardinals[8][2] = {
|
||||
{ 0, 30 },
|
||||
{ 30, 30 },
|
||||
{ 30, 0 },
|
||||
{ 30, -30 },
|
||||
{ 0, -30 },
|
||||
{ -30, -30 },
|
||||
{ -30, 0 },
|
||||
{ -30, 30 },
|
||||
};
|
||||
|
||||
if (libevdev_get_num_slots(dev->evdev) > 2 ||
|
||||
!libinput_device_has_capability(dev->libinput_device,
|
||||
LIBINPUT_DEVICE_CAP_GESTURE))
|
||||
return;
|
||||
|
||||
dir_x = cardinals[cardinal][0];
|
||||
dir_y = cardinals[cardinal][1];
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
|
||||
litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
|
||||
litest_event(dev, EV_KEY, BTN_TOOL_QUADTAP, 1);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
libinput_dispatch(li);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
litest_push_event_frame(dev);
|
||||
if (dir_x > 0.0)
|
||||
dir_x -= 2;
|
||||
else if (dir_x < 0.0)
|
||||
dir_x += 2;
|
||||
if (dir_y > 0.0)
|
||||
dir_y -= 2;
|
||||
else if (dir_y < 0.0)
|
||||
dir_y += 2;
|
||||
litest_touch_move(dev,
|
||||
0,
|
||||
50 + dir_x,
|
||||
50 + dir_y);
|
||||
litest_touch_move(dev,
|
||||
1,
|
||||
50 - dir_x,
|
||||
50 - dir_y);
|
||||
litest_pop_event_frame(dev);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
|
||||
4);
|
||||
dx = libinput_event_gesture_get_dx(gevent);
|
||||
dy = libinput_event_gesture_get_dy(gevent);
|
||||
scale = libinput_event_gesture_get_scale(gevent);
|
||||
ck_assert(dx == 0.0);
|
||||
ck_assert(dy == 0.0);
|
||||
ck_assert(scale == 1.0);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
|
||||
while ((event = libinput_get_event(li)) != NULL) {
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
|
||||
4);
|
||||
|
||||
oldscale = scale;
|
||||
scale = libinput_event_gesture_get_scale(gevent);
|
||||
|
||||
ck_assert(scale < oldscale);
|
||||
|
||||
angle = libinput_event_gesture_get_angle_delta(gevent);
|
||||
ck_assert_double_le(fabs(angle), 1.0);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
litest_touch_up(dev, 0);
|
||||
litest_touch_up(dev, 1);
|
||||
libinput_dispatch(li);
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_PINCH_END,
|
||||
4);
|
||||
ck_assert(!libinput_event_gesture_get_cancelled(gevent));
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(gestures_spread)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
|
|
@ -269,17 +1033,19 @@ START_TEST(gestures_spread)
|
|||
double scale, oldscale;
|
||||
double angle;
|
||||
int cardinals[8][2] = {
|
||||
{ 0, 1 },
|
||||
{ 1, 1 },
|
||||
{ 1, 0 },
|
||||
{ 1, -1 },
|
||||
{ 0, -1 },
|
||||
{ -1, -1 },
|
||||
{ -1, 0 },
|
||||
{ -1, 1 },
|
||||
{ 0, 30 },
|
||||
{ 30, 30 },
|
||||
{ 30, 0 },
|
||||
{ 30, -30 },
|
||||
{ 0, -30 },
|
||||
{ -30, -30 },
|
||||
{ -30, 0 },
|
||||
{ -30, 30 },
|
||||
};
|
||||
|
||||
if (libevdev_get_num_slots(dev->evdev) < 3)
|
||||
if (libevdev_get_num_slots(dev->evdev) < 2 ||
|
||||
!libinput_device_has_capability(dev->libinput_device,
|
||||
LIBINPUT_DEVICE_CAP_GESTURE))
|
||||
return;
|
||||
|
||||
dir_x = cardinals[cardinal][0];
|
||||
|
|
@ -366,18 +1132,17 @@ START_TEST(gestures_time_usec)
|
|||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 40, 40);
|
||||
litest_touch_down(dev, 1, 40, 50);
|
||||
litest_touch_down(dev, 2, 40, 60);
|
||||
litest_touch_down(dev, 1, 50, 40);
|
||||
litest_touch_down(dev, 2, 60, 40);
|
||||
libinput_dispatch(li);
|
||||
litest_touch_move_three_touches(dev,
|
||||
40, 40,
|
||||
40, 50,
|
||||
40, 60,
|
||||
50, 40,
|
||||
60, 40,
|
||||
0, 30,
|
||||
4, 2);
|
||||
|
||||
litest_wait_for_event(li);
|
||||
|
||||
libinput_dispatch(li);
|
||||
event = libinput_get_event(li);
|
||||
gevent = litest_is_gesture_event(event,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
|
||||
|
|
@ -398,7 +1163,14 @@ litest_setup_tests(void)
|
|||
litest_add("gestures:cap", gestures_nocap, LITEST_ANY, LITEST_TOUCHPAD);
|
||||
|
||||
litest_add_ranged("gestures:swipe", gestures_swipe_3fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
|
||||
litest_add_ranged("gestures:swipe", gestures_swipe_3fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
|
||||
litest_add_ranged("gestures:swipe", gestures_swipe_4fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
|
||||
litest_add_ranged("gestures:swipe", gestures_swipe_4fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
|
||||
litest_add_ranged("gestures:pinch", gestures_pinch, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
|
||||
litest_add_ranged("gestures:pinch", gestures_pinch_3fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
|
||||
litest_add_ranged("gestures:pinch", gestures_pinch_3fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
|
||||
litest_add_ranged("gestures:pinch", gestures_pinch_4fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
|
||||
litest_add_ranged("gestures:pinch", gestures_pinch_4fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
|
||||
litest_add_ranged("gestures:pinch", gestures_spread, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
|
||||
|
||||
litest_add("gesture:time", gestures_time_usec, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
|
||||
|
|
|
|||
|
|
@ -289,11 +289,11 @@ START_TEST(touchpad_2fg_scroll_semi_mt)
|
|||
litest_touch_down(dev, 0, 20, 20);
|
||||
litest_touch_down(dev, 1, 30, 20);
|
||||
libinput_dispatch(li);
|
||||
litest_touch_move_to(dev, 1, 30, 20, 30, 70, 10, 5);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_touch_move_to(dev, 0, 20, 20, 20, 70, 10, 5);
|
||||
litest_touch_move_two_touches(dev,
|
||||
20, 20,
|
||||
30, 20,
|
||||
30, 40,
|
||||
10, 1);
|
||||
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue