mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-01-03 13:50:13 +01:00
Merge branch 'master' into tablet-support
sendevents config tests currently disabled for LITEST_TABLET until that gains the matching bits in the dispatch. Conflicts: src/evdev.c src/libinput.c test/litest.c test/litest.h
This commit is contained in:
commit
a6f18c9cca
42 changed files with 4871 additions and 1319 deletions
|
|
@ -1,7 +1,7 @@
|
|||
AC_PREREQ([2.64])
|
||||
|
||||
m4_define([libinput_major_version], [0])
|
||||
m4_define([libinput_minor_version], [4])
|
||||
m4_define([libinput_minor_version], [6])
|
||||
m4_define([libinput_micro_version], [0])
|
||||
m4_define([libinput_version],
|
||||
[libinput_major_version.libinput_minor_version.libinput_micro_version])
|
||||
|
|
@ -30,7 +30,7 @@ AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz subdir-objects])
|
|||
# - If binary compatibility has been broken (eg removed or changed interfaces)
|
||||
# change to C+1:0:0
|
||||
# - If the interface is the same as the previous version, change to C:R+1:A
|
||||
LIBINPUT_LT_VERSION=3:0:0
|
||||
LIBINPUT_LT_VERSION=5:0:0
|
||||
AC_SUBST(LIBINPUT_LT_VERSION)
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
|
|
@ -96,7 +96,7 @@ AC_ARG_ENABLE(tests,
|
|||
[build_tests="$enableval"],
|
||||
[build_tests="auto"])
|
||||
|
||||
PKG_CHECK_MODULES(CHECK, [check >= 0.9.9], [HAVE_CHECK="yes"], [HAVE_CHECK="no"])
|
||||
PKG_CHECK_MODULES(CHECK, [check >= 0.9.10], [HAVE_CHECK="yes"], [HAVE_CHECK="no"])
|
||||
|
||||
if test "x$build_tests" = "xauto"; then
|
||||
build_tests="$HAVE_CHECK"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="2190px" height="1624px" version="1.1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="2180px" height="1624px" version="1.1">
|
||||
<defs/>
|
||||
<g transform="translate(0.5,0.5)">
|
||||
<path d="M 862 441 L 894 441" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
|
|
@ -68,13 +68,13 @@
|
|||
<path d="M 712 441 L 668 441 Q 658 441 658 451 L 658 762" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 786 62 L 786 81 Q 786 91 786 101 L 786 114" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 786 120 L 783 113 L 786 114 L 790 113 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<rect x="1753" y="472" width="120" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<rect x="1753" y="412" width="120" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="1813" y="489">Check state of</text>
|
||||
<text x="1813" y="503">all touches</text>
|
||||
<text x="1813" y="429">Check state of</text>
|
||||
<text x="1813" y="443">all touches</text>
|
||||
</g>
|
||||
<path d="M 1813 512 L 1813 518 Q 1813 524 1813 529 L 1813 534" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 526 L 1813 535 L 1818 526" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 452 L 1813 458 Q 1813 465 1813 470 L 1813 475" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 467 L 1813 476 L 1818 467" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<ellipse cx="1813" cy="72" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
|
||||
<path d="M 1813 87 L 1813 115 Q 1813 125 1813 135 L 1813 160" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 152 L 1813 161 L 1818 152" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
|
|
@ -82,88 +82,89 @@
|
|||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="1813" y="41">tp_post_softbutton_buttons()</text>
|
||||
</g>
|
||||
<path d="M 1813 212 L 1908 267 L 1813 322 L 1718 267 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 192 L 1908 247 L 1813 302 L 1718 247 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="1813" y="264">!buttons.click_pend</text>
|
||||
<text x="1813" y="278">&& current == old</text>
|
||||
<text x="1813" y="244">!buttons.click_pend</text>
|
||||
<text x="1813" y="258">&& current == old</text>
|
||||
</g>
|
||||
<path d="M 1908 267 L 1968 267 Q 1978 267 1988 267 L 2056 267" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 2048 272 L 2057 267 L 2048 263" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1908 247 L 1968 247 Q 1978 247 1988 247 L 2056 247" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 2048 252 L 2057 247 L 2048 243" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1998" y="252" width="18" height="14" stroke-width="0"/>
|
||||
<text x="1999" y="261">yes</text>
|
||||
<rect fill="#ffffff" stroke="none" x="1998" y="228" width="24" height="18" stroke-width="0"/>
|
||||
<text x="1999" y="241">yes</text>
|
||||
</g>
|
||||
<path d="M 1813 322 L 1813 332 Q 1813 342 1813 351 L 1813 360" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 352 L 1813 361 L 1818 352" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 302 L 1813 307 Q 1813 313 1813 317 L 1813 321" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 313 L 1813 322 L 1818 313" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1815" y="330" width="15" height="14" stroke-width="0"/>
|
||||
<text x="1815" y="339">no</text>
|
||||
<rect fill="#ffffff" stroke="none" x="1830" y="310" width="18" height="18" stroke-width="0"/>
|
||||
<text x="1830" y="319">no</text>
|
||||
</g>
|
||||
<ellipse cx="2073" cy="267" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
|
||||
<ellipse cx="2073" cy="267" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
|
||||
<rect x="1708" y="112" width="200" height="60" rx="24" ry="24" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<ellipse cx="2073" cy="247" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
|
||||
<ellipse cx="2073" cy="247" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
|
||||
<rect x="1713" y="102" width="200" height="70" rx="28" ry="28" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="1808" y="132">current = buttons.state & 0x01</text>
|
||||
<text x="1808" y="146">old = buttons.old_state & 0x01</text>
|
||||
<text x="1808" y="160">button = 0</text>
|
||||
<text x="1813" y="120">current = buttons.state & 0x01</text>
|
||||
<text x="1813" y="134">old = buttons.old_state & 0x01</text>
|
||||
<text x="1813" y="148">button = 0</text>
|
||||
<text x="1813" y="162">is_top = 0</text>
|
||||
</g>
|
||||
<path d="M 1813 172 L 1813 182 Q 1813 192 1813 201 L 1813 210" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 202 L 1813 211 L 1818 202" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 536 L 1928 607 L 1813 678 L 1698 607 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 172 L 1813 177 Q 1813 182 1813 186 L 1813 190" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 182 L 1813 191 L 1818 182" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 568 L 1918 626 L 1813 684 L 1708 626 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="1813" y="611">All touches are in state none</text>
|
||||
<text x="1813" y="630">All touches are in state none</text>
|
||||
</g>
|
||||
<path d="M 1813 678 L 1813 684 Q 1813 690 1813 695 L 1813 700" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 692 L 1813 701 L 1818 692" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 684 L 1813 691 Q 1813 697 1813 702 L 1813 708" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 700 L 1813 709 L 1818 700" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1820" y="687" width="15" height="14" stroke-width="0"/>
|
||||
<text x="1820" y="696">no</text>
|
||||
<rect fill="#ffffff" stroke="none" x="1820" y="691" width="18" height="18" stroke-width="0"/>
|
||||
<text x="1820" y="704">no</text>
|
||||
</g>
|
||||
<path d="M 1928 607 L 1938 607 Q 1948 607 1957 607 L 1966 607" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1958 612 L 1967 607 L 1958 603" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1918 626 L 1936 626 Q 1946 626 1955 626 L 1971 626" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1963 631 L 1972 626 L 1963 622" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1930" y="615" width="18" height="14" stroke-width="0"/>
|
||||
<text x="1930" y="624">yes</text>
|
||||
<rect fill="#ffffff" stroke="none" x="1920" y="634" width="24" height="18" stroke-width="0"/>
|
||||
<text x="1920" y="643">yes</text>
|
||||
</g>
|
||||
<rect x="1968" y="587" width="150" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<rect x="1973" y="606" width="150" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="2043" y="611">buttons.click_pend = 1</text>
|
||||
<text x="2048" y="630">buttons.click_pend = 1</text>
|
||||
</g>
|
||||
<path d="M 2118 607 L 2128 607 Q 2138 607 2147 607 L 2156 607" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 2148 612 L 2157 607 L 2148 603" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 702 L 1938 787 L 1813 872 L 1688 787 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 2123 626 L 2128 626 Q 2133 626 2137 626 L 2141 626" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 2133 631 L 2142 626 L 2133 622" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 710 L 1938 795 L 1813 880 L 1688 795 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="1813" y="777">(Some touches are in middle) ||</text>
|
||||
<text x="1813" y="791">((Some touches are in right) &&</text>
|
||||
<text x="1813" y="805">(Some touches are in left))</text>
|
||||
<text x="1813" y="785">(Some touches are in middle) ||</text>
|
||||
<text x="1813" y="799">((Some touches are in right) &&</text>
|
||||
<text x="1813" y="813">(Some touches are in left))</text>
|
||||
</g>
|
||||
<path d="M 1938 787 L 1943 787 Q 1948 787 1957 787 L 1966 787" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1958 792 L 1967 787 L 1958 783" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1938 795 L 1943 795 Q 1948 795 1957 795 L 1966 795" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1958 800 L 1967 795 L 1958 791" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1941" y="795" width="18" height="14" stroke-width="0"/>
|
||||
<text x="1942" y="804">yes</text>
|
||||
<rect fill="#ffffff" stroke="none" x="1941" y="803" width="24" height="18" stroke-width="0"/>
|
||||
<text x="1942" y="812">yes</text>
|
||||
</g>
|
||||
<rect x="1968" y="767" width="160" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<rect x="1968" y="775" width="160" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="2048" y="791">button = BTN_MIDDLE</text>
|
||||
<text x="2048" y="799">button = BTN_MIDDLE</text>
|
||||
</g>
|
||||
<path d="M 2128 787 L 2158 787 Q 2168 787 2168 797 L 2168 1207 Q 2168 1217 2158 1217 L 1913 1217" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1921 1213 L 1912 1217 L 1921 1222" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 362 L 1876 396 L 1813 431 L 1751 396 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 2128 795 L 2158 795 Q 2168 795 2168 805 L 2168 1197 Q 2168 1207 2158 1207 L 1913 1207" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1921 1203 L 1912 1207 L 1921 1212" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 323 L 1876 357 L 1813 392 L 1751 357 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="1813" y="400">current</text>
|
||||
<text x="1813" y="361">current</text>
|
||||
</g>
|
||||
<path d="M 1751 396 L 1601 396 Q 1591 396 1591 406 L 1591 1172 Q 1591 1182 1591 1182 L 1592 1182" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1596 1180 L 1591 1182 L 1596 1184" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1751 357 L 1606 357 Q 1596 357 1596 367 L 1596 1160" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1592 1152 L 1596 1161 L 1601 1152" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1688" y="381" width="15" height="14" stroke-width="0"/>
|
||||
<text x="1688" y="390">no</text>
|
||||
<rect fill="#ffffff" stroke="none" x="1687" y="338" width="18" height="18" stroke-width="0"/>
|
||||
<text x="1687" y="351">no</text>
|
||||
</g>
|
||||
<path d="M 1813 431 L 1813 441 Q 1813 451 1813 461 L 1813 470" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 462 L 1813 471 L 1818 462" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 392 L 1813 397 Q 1813 402 1813 406 L 1813 410" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 402 L 1813 411 L 1818 402" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1815" y="438" width="18" height="14" stroke-width="0"/>
|
||||
<text x="1815" y="448">yes</text>
|
||||
<rect fill="#ffffff" stroke="none" x="1830" y="390" width="24" height="18" stroke-width="0"/>
|
||||
<text x="1830" y="399">yes</text>
|
||||
</g>
|
||||
<path d="M 1813 902 L 1909 967 L 1813 1032 L 1717 967 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
|
|
@ -172,13 +173,13 @@
|
|||
<path d="M 1909 967 L 1928 967 Q 1938 967 1948 967 L 1966 967" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1958 972 L 1967 967 L 1958 963" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1930" y="975" width="18" height="14" stroke-width="0"/>
|
||||
<rect fill="#ffffff" stroke="none" x="1930" y="975" width="24" height="18" stroke-width="0"/>
|
||||
<text x="1930" y="984">yes</text>
|
||||
</g>
|
||||
<path d="M 1813 872 L 1813 880 Q 1813 887 1813 893 L 1813 900" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 880 L 1813 886 Q 1813 891 1813 895 L 1813 900" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 892 L 1813 901 L 1818 892" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1820" y="887" width="15" height="14" stroke-width="0"/>
|
||||
<rect fill="#ffffff" stroke="none" x="1820" y="883" width="18" height="18" stroke-width="0"/>
|
||||
<text x="1820" y="896">no</text>
|
||||
</g>
|
||||
<rect x="1968" y="947" width="160" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
|
|
@ -192,25 +193,28 @@
|
|||
<path d="M 1813 1032 L 1813 1047 Q 1813 1057 1813 1067 L 1813 1080" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 1072 L 1813 1081 L 1818 1072" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1815" y="1044" width="15" height="14" stroke-width="0"/>
|
||||
<rect fill="#ffffff" stroke="none" x="1815" y="1040" width="18" height="18" stroke-width="0"/>
|
||||
<text x="1815" y="1053">no</text>
|
||||
</g>
|
||||
<rect x="1716" y="1182" width="195" height="70" rx="28" ry="28" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<rect x="1716" y="1162" width="195" height="90" rx="36" ry="36" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="1813" y="1214">buttons.active = button</text>
|
||||
<text x="1813" y="1228">state = BUTTON_PRESSED</text>
|
||||
<text x="1814" y="1197">buttons.active = button</text>
|
||||
<text x="1814" y="1211">buttons.active_is_top = is_top</text>
|
||||
<text x="1814" y="1225">state = BUTTON_PRESSED</text>
|
||||
</g>
|
||||
<path d="M 1813 1252 L 1813 1282 Q 1813 1292 1803 1292 L 1713 1292 Q 1703 1292 1703 1302 L 1703 1330" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1814 1252 L 1814 1282 Q 1814 1292 1804 1292 L 1713 1292 Q 1703 1292 1703 1302 L 1703 1330" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1699 1322 L 1703 1331 L 1708 1322" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 1122 L 1813 1142 Q 1813 1152 1813 1162 L 1813 1180" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 1172 L 1813 1181 L 1818 1172" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 2128 967 L 2158 967 Q 2168 967 2168 977 L 2168 1207 Q 2168 1217 2158 1217 L 1913 1217" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1921 1213 L 1912 1217 L 1921 1222" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<rect x="1493" y="1182" width="195" height="70" rx="28" ry="28" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<path d="M 1813 1122 L 1813 1122 Q 1813 1122 1813 1132 L 1813 1152 Q 1813 1162 1813 1161 L 1813 1160" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 1152 L 1813 1161 L 1818 1152" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 2128 967 L 2158 967 Q 2168 967 2168 977 L 2168 1197 Q 2168 1207 2158 1207 L 1913 1207" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1921 1203 L 1912 1207 L 1921 1212" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<rect x="1493" y="1162" width="205" height="90" rx="36" ry="36" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="1591" y="1207">button = buttons.active</text>
|
||||
<text x="1591" y="1221">buttons.active = 0</text>
|
||||
<text x="1591" y="1235">state = BUTTON_RELEASED</text>
|
||||
<text x="1596" y="1183">button = buttons.active</text>
|
||||
<text x="1596" y="1197">is_top = buttons.active_is_top</text>
|
||||
<text x="1596" y="1211">buttons.active = 0</text>
|
||||
<text x="1596" y="1225">buttons.active_is_top = 0</text>
|
||||
<text x="1596" y="1239">state = BUTTON_RELEASED</text>
|
||||
</g>
|
||||
<rect x="1628" y="1332" width="150" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
|
|
@ -218,7 +222,7 @@
|
|||
</g>
|
||||
<path d="M 1703 1372 L 1703 1380 Q 1703 1387 1703 1393 L 1703 1400" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1699 1392 L 1703 1401 L 1708 1392" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1591 1252 L 1591 1282 Q 1591 1292 1601 1292 L 1693 1292 Q 1703 1292 1703 1302 L 1703 1330" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1596 1252 L 1596 1282 Q 1596 1292 1606 1292 L 1693 1292 Q 1703 1292 1703 1302 L 1703 1330" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1699 1322 L 1703 1331 L 1708 1322" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1703 1402 L 1743 1422 L 1703 1442 L 1663 1422 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
|
|
@ -227,26 +231,26 @@
|
|||
<path d="M 1743 1422 L 1808 1422 Q 1818 1422 1818 1432 L 1818 1597 Q 1818 1607 1808 1607 L 1720 1607" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1728 1603 L 1719 1607 L 1728 1612" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1745" y="1407" width="15" height="14" stroke-width="0"/>
|
||||
<rect fill="#ffffff" stroke="none" x="1745" y="1403" width="18" height="18" stroke-width="0"/>
|
||||
<text x="1745" y="1416">no</text>
|
||||
</g>
|
||||
<path d="M 1703 1442 L 1703 1452 Q 1703 1462 1703 1471 L 1703 1480" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1699 1472 L 1703 1481 L 1708 1472" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1705" y="1450" width="18" height="14" stroke-width="0"/>
|
||||
<rect fill="#ffffff" stroke="none" x="1705" y="1450" width="24" height="18" stroke-width="0"/>
|
||||
<text x="1705" y="1459">yes</text>
|
||||
</g>
|
||||
<rect x="1618" y="1482" width="170" height="40" rx="16" ry="16" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="1703" y="1499">pointer_notify_button(</text>
|
||||
<text x="1703" y="1513">button, state)</text>
|
||||
<text x="1703" y="1499">tp_notify_softbutton(</text>
|
||||
<text x="1703" y="1513">button, is_top, state)</text>
|
||||
</g>
|
||||
<path d="M 1703 1522 L 1703 1542 Q 1703 1552 1703 1562 L 1703 1590" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1699 1582 L 1703 1591 L 1708 1582" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<ellipse cx="1703" cy="1607" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
|
||||
<ellipse cx="1703" cy="1607" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
|
||||
<ellipse cx="2173" cy="607" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
|
||||
<ellipse cx="2173" cy="607" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
|
||||
<ellipse cx="2158" cy="626" rx="11" ry="11" fill="#000000" stroke="#ff0000" pointer-events="none"/>
|
||||
<ellipse cx="2158" cy="626" rx="15" ry="15" fill="transparent" stroke="#ff0000" pointer-events="none"/>
|
||||
<path d="M 456 232 C 458 229 461 227 464 227 L 490 227 C 493 227 496 229 498 232 L 514 256 C 514 257 514 259 514 260 L 498 284 C 496 287 493 289 490 289 L 464 289 C 461 289 458 287 456 284 L 440 260 C 440 259 440 257 440 256 L 456 232 Z" fill="#ffd966" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="477" y="255">finger in</text>
|
||||
|
|
@ -261,8 +265,8 @@
|
|||
<text x="477" y="453">curr = button</text>
|
||||
<text x="477" y="467">start enter timeout</text>
|
||||
</g>
|
||||
<path d="M 477 289 L 477 385" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 477 391 L 474 384 L 477 385 L 481 384 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 477 289 L 477 330 Q 477 340 477 350 L 477 385" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 477 391 L 473 384 L 477 385 L 480 384 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 552 442 L 648 442 Q 658 442 658 452 L 658 762" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<rect x="412" y="712" width="130" height="100" rx="6" ry="6" fill="#ccffcc" stroke="#000000" stroke-width="2" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
|
|
@ -356,5 +360,27 @@
|
|||
<path d="M 737 32 L 730 36 L 732 32 L 730 29 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 66 762 L 18 762 Q 8 762 8 752 L 8 42 Q 8 32 18 32 L 732 32" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 737 32 L 730 36 L 732 32 L 730 29 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 477 L 1876 511 L 1813 546 L 1751 511 Z" fill="#ffffc0" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="1813" y="515">touches in top?</text>
|
||||
</g>
|
||||
<path d="M 1876 511 L 1928 511 Q 1938 511 1938 518 L 1938 524" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1934 516 L 1938 525 L 1943 516" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1890" y="500" width="24" height="18" stroke-width="0"/>
|
||||
<text x="1890" y="509">yes</text>
|
||||
</g>
|
||||
<rect x="1898" y="526" width="80" height="30" rx="12" ry="12" fill="#ffffc0" stroke="#ff0000" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" text-anchor="middle" font-size="12px">
|
||||
<text x="1938" y="545">is_top = 1</text>
|
||||
</g>
|
||||
<path d="M 1938 556 L 1938 562 Q 1938 568 1928 568 L 1815 568" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1823 564 L 1814 568 L 1823 573" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1813 546 L 1813 554 Q 1813 562 1813 564 L 1813 566" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1809 558 L 1813 567 L 1818 558" fill="none" stroke="#ff0000" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#000000" font-family="Helvetica" font-size="11px">
|
||||
<rect fill="#ffffff" stroke="none" x="1820" y="550" width="18" height="18" stroke-width="0"/>
|
||||
<text x="1820" y="559">no</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 34 KiB |
File diff suppressed because it is too large
Load diff
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
|
@ -163,6 +163,7 @@ struct input_keymap_entry {
|
|||
#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */
|
||||
#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
|
||||
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
|
||||
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
|
||||
|
||||
#define INPUT_PROP_MAX 0x1f
|
||||
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ libinput_la_CFLAGS = -I$(top_srcdir)/include \
|
|||
$(LIBEVDEV_CFLAGS) \
|
||||
$(GCC_CFLAGS)
|
||||
|
||||
libinput_la_LDFLAGS = -version-info $(LIBINPUT_LT_VERSION)
|
||||
libinput_la_LDFLAGS = -version-info $(LIBINPUT_LT_VERSION) -shared
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libinput.pc
|
||||
|
|
|
|||
|
|
@ -484,6 +484,67 @@ tp_process_button(struct tp_dispatch *tp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
tp_release_all_buttons(struct tp_dispatch *tp,
|
||||
uint64_t time)
|
||||
{
|
||||
if (tp->buttons.state) {
|
||||
tp->buttons.state = 0;
|
||||
tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tp_init_softbuttons(struct tp_dispatch *tp,
|
||||
struct evdev_device *device,
|
||||
double topbutton_size_mult)
|
||||
{
|
||||
int width, height;
|
||||
const struct input_absinfo *absinfo_x, *absinfo_y;
|
||||
int xoffset, yoffset;
|
||||
int yres;
|
||||
|
||||
absinfo_x = device->abs.absinfo_x;
|
||||
absinfo_y = device->abs.absinfo_y;
|
||||
|
||||
xoffset = absinfo_x->minimum,
|
||||
yoffset = absinfo_y->minimum;
|
||||
yres = absinfo_y->resolution;
|
||||
width = abs(absinfo_x->maximum - absinfo_x->minimum);
|
||||
height = abs(absinfo_y->maximum - absinfo_y->minimum);
|
||||
|
||||
/* button height: 10mm or 15% of the touchpad height,
|
||||
whichever is smaller */
|
||||
if (yres > 1 && (height * 0.15/yres) > 10) {
|
||||
tp->buttons.bottom_area.top_edge =
|
||||
absinfo_y->maximum - 10 * yres;
|
||||
} else {
|
||||
tp->buttons.bottom_area.top_edge = height * .85 + yoffset;
|
||||
}
|
||||
|
||||
tp->buttons.bottom_area.rightbutton_left_edge = width/2 + xoffset;
|
||||
|
||||
if (tp->buttons.has_topbuttons) {
|
||||
/* T440s has the top button line 5mm from the top, event
|
||||
analysis has shown events to start down to ~10mm from the
|
||||
top - which maps to 15%. We allow the caller to enlarge the
|
||||
area using a multiplier for the touchpad disabled case. */
|
||||
double topsize_mm = 10 * topbutton_size_mult;
|
||||
double topsize_pct = .15 * topbutton_size_mult;
|
||||
|
||||
if (yres > 1) {
|
||||
tp->buttons.top_area.bottom_edge =
|
||||
yoffset + topsize_mm * yres;
|
||||
} else {
|
||||
tp->buttons.top_area.bottom_edge = height * topsize_pct + yoffset;
|
||||
}
|
||||
tp->buttons.top_area.rightbutton_left_edge = width * .58 + xoffset;
|
||||
tp->buttons.top_area.leftbutton_right_edge = width * .42 + xoffset;
|
||||
} else {
|
||||
tp->buttons.top_area.bottom_edge = INT_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
tp_init_buttons(struct tp_dispatch *tp,
|
||||
struct evdev_device *device)
|
||||
|
|
@ -521,39 +582,11 @@ tp_init_buttons(struct tp_dispatch *tp,
|
|||
|
||||
tp->buttons.motion_dist = diagonal * DEFAULT_BUTTON_MOTION_THRESHOLD;
|
||||
|
||||
if (libevdev_get_id_vendor(device->evdev) == 0x5ac) /* Apple */
|
||||
if (libevdev_get_id_vendor(device->evdev) == VENDOR_ID_APPLE)
|
||||
tp->buttons.use_clickfinger = true;
|
||||
|
||||
if (tp->buttons.is_clickpad && !tp->buttons.use_clickfinger) {
|
||||
int xoffset = absinfo_x->minimum,
|
||||
yoffset = absinfo_y->minimum;
|
||||
int yres = absinfo_y->resolution;
|
||||
|
||||
/* button height: 10mm or 15% of the touchpad height,
|
||||
whichever is smaller */
|
||||
if (yres > 1 && (height * 0.15/yres) > 10) {
|
||||
tp->buttons.bottom_area.top_edge =
|
||||
absinfo_y->maximum - 10 * yres;
|
||||
} else {
|
||||
tp->buttons.bottom_area.top_edge = height * .85 + yoffset;
|
||||
}
|
||||
|
||||
tp->buttons.bottom_area.rightbutton_left_edge = width/2 + xoffset;
|
||||
|
||||
if (tp->buttons.has_topbuttons) {
|
||||
/* T440s has the top button line 5mm from the top,
|
||||
make the buttons 6mm high */
|
||||
if (yres > 1) {
|
||||
tp->buttons.top_area.bottom_edge =
|
||||
yoffset + 6 * yres;
|
||||
} else {
|
||||
tp->buttons.top_area.bottom_edge = height * .08 + yoffset;
|
||||
}
|
||||
tp->buttons.top_area.rightbutton_left_edge = width * .58 + xoffset;
|
||||
tp->buttons.top_area.leftbutton_right_edge = width * .42 + xoffset;
|
||||
} else {
|
||||
tp->buttons.top_area.bottom_edge = INT_MIN;
|
||||
}
|
||||
tp_init_softbuttons(tp, device, 1.0);
|
||||
} else {
|
||||
tp->buttons.bottom_area.top_edge = INT_MAX;
|
||||
tp->buttons.top_area.bottom_edge = INT_MIN;
|
||||
|
|
@ -606,11 +639,12 @@ tp_post_clickfinger_buttons(struct tp_dispatch *tp, uint64_t time)
|
|||
state = LIBINPUT_BUTTON_STATE_RELEASED;
|
||||
}
|
||||
|
||||
if (button)
|
||||
pointer_notify_button(&tp->device->base,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
if (button) {
|
||||
evdev_pointer_notify_button(tp->device,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -632,10 +666,10 @@ tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
|
|||
else
|
||||
state = LIBINPUT_BUTTON_STATE_RELEASED;
|
||||
|
||||
pointer_notify_button(&tp->device->base,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
evdev_pointer_notify_button(tp->device,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
}
|
||||
|
||||
button++;
|
||||
|
|
@ -646,16 +680,46 @@ tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tp_notify_softbutton(struct tp_dispatch *tp,
|
||||
uint64_t time,
|
||||
uint32_t button,
|
||||
uint32_t is_topbutton,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
/* If we've a trackpoint, send top buttons through the trackpoint */
|
||||
if (is_topbutton && tp->buttons.trackpoint) {
|
||||
struct evdev_dispatch *dispatch = tp->buttons.trackpoint->dispatch;
|
||||
struct input_event event;
|
||||
|
||||
event.time.tv_sec = time/1000;
|
||||
event.time.tv_usec = (time % 1000) * 1000;
|
||||
event.type = EV_KEY;
|
||||
event.code = button;
|
||||
event.value = (state == LIBINPUT_BUTTON_STATE_PRESSED) ? 1 : 0;
|
||||
dispatch->interface->process(dispatch, tp->buttons.trackpoint,
|
||||
&event, time);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ignore button events not for the trackpoint while suspended */
|
||||
if (tp->device->suspended)
|
||||
return;
|
||||
|
||||
evdev_pointer_notify_button(tp->device, time, button, state);
|
||||
}
|
||||
|
||||
static int
|
||||
tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
uint32_t current, old, button;
|
||||
uint32_t current, old, button, is_top;
|
||||
enum libinput_button_state state;
|
||||
enum { AREA = 0x01, LEFT = 0x02, MIDDLE = 0x04, RIGHT = 0x08 };
|
||||
|
||||
current = tp->buttons.state;
|
||||
old = tp->buttons.old_state;
|
||||
button = 0;
|
||||
is_top = 0;
|
||||
|
||||
if (!tp->buttons.click_pending && current == old)
|
||||
return 0;
|
||||
|
|
@ -668,15 +732,18 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
|
|||
case BUTTON_EVENT_IN_AREA:
|
||||
button |= AREA;
|
||||
break;
|
||||
case BUTTON_EVENT_IN_BOTTOM_L:
|
||||
case BUTTON_EVENT_IN_TOP_L:
|
||||
is_top = 1;
|
||||
case BUTTON_EVENT_IN_BOTTOM_L:
|
||||
button |= LEFT;
|
||||
break;
|
||||
case BUTTON_EVENT_IN_TOP_M:
|
||||
is_top = 1;
|
||||
button |= MIDDLE;
|
||||
break;
|
||||
case BUTTON_EVENT_IN_BOTTOM_R:
|
||||
case BUTTON_EVENT_IN_TOP_R:
|
||||
is_top = 1;
|
||||
case BUTTON_EVENT_IN_BOTTOM_R:
|
||||
button |= RIGHT;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -698,20 +765,21 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
|
|||
button = BTN_LEFT;
|
||||
|
||||
tp->buttons.active = button;
|
||||
tp->buttons.active_is_topbutton = is_top;
|
||||
state = LIBINPUT_BUTTON_STATE_PRESSED;
|
||||
} else {
|
||||
button = tp->buttons.active;
|
||||
is_top = tp->buttons.active_is_topbutton;
|
||||
tp->buttons.active = 0;
|
||||
tp->buttons.active_is_topbutton = 0;
|
||||
state = LIBINPUT_BUTTON_STATE_RELEASED;
|
||||
}
|
||||
|
||||
tp->buttons.click_pending = false;
|
||||
|
||||
if (button)
|
||||
pointer_notify_button(&tp->device->base,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
tp_notify_softbutton(tp, time, button, is_top, state);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,10 +113,10 @@ tp_tap_notify(struct tp_dispatch *tp,
|
|||
return;
|
||||
}
|
||||
|
||||
pointer_notify_button(&tp->device->base,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
evdev_pointer_notify_button(tp->device,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -221,7 +221,6 @@ tp_tap_tapped_handle_event(struct tp_dispatch *tp,
|
|||
break;
|
||||
case TAP_EVENT_TOUCH:
|
||||
tp->tap.state = TAP_STATE_DRAGGING_OR_DOUBLETAP;
|
||||
tp_tap_clear_timer(tp);
|
||||
break;
|
||||
case TAP_EVENT_TIMEOUT:
|
||||
tp->tap.state = TAP_STATE_IDLE;
|
||||
|
|
@ -253,6 +252,7 @@ tp_tap_touch2_handle_event(struct tp_dispatch *tp,
|
|||
break;
|
||||
case TAP_EVENT_MOTION:
|
||||
tp_tap_clear_timer(tp);
|
||||
/* fallthrough */
|
||||
case TAP_EVENT_TIMEOUT:
|
||||
tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
|
||||
break;
|
||||
|
|
@ -541,7 +541,10 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
|
|||
struct tp_touch *t;
|
||||
int filter_motion = 0;
|
||||
|
||||
if (tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS)
|
||||
/* Handle queued button pressed events from clickpads. For touchpads
|
||||
* with separate physical buttons, ignore button pressed events so they
|
||||
* don't interfere with tapping. */
|
||||
if (tp->buttons.is_clickpad && tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS)
|
||||
tp_tap_handle_event(tp, NULL, TAP_EVENT_BUTTON, time);
|
||||
|
||||
tp_for_each_touch(tp, t) {
|
||||
|
|
@ -616,7 +619,7 @@ static int
|
|||
tp_tap_config_count(struct libinput_device *device)
|
||||
{
|
||||
struct evdev_dispatch *dispatch;
|
||||
struct tp_dispatch *tp;
|
||||
struct tp_dispatch *tp = NULL;
|
||||
|
||||
dispatch = ((struct evdev_device *) device)->dispatch;
|
||||
tp = container_of(dispatch, tp, base);
|
||||
|
|
@ -625,32 +628,34 @@ tp_tap_config_count(struct libinput_device *device)
|
|||
}
|
||||
|
||||
static enum libinput_config_status
|
||||
tp_tap_config_set_enabled(struct libinput_device *device, int enabled)
|
||||
tp_tap_config_set_enabled(struct libinput_device *device,
|
||||
enum libinput_config_tap_state enabled)
|
||||
{
|
||||
struct evdev_dispatch *dispatch;
|
||||
struct tp_dispatch *tp;
|
||||
struct tp_dispatch *tp = NULL;
|
||||
|
||||
dispatch = ((struct evdev_device *) device)->dispatch;
|
||||
tp = container_of(dispatch, tp, base);
|
||||
|
||||
tp->tap.enabled = enabled;
|
||||
tp->tap.enabled = (enabled == LIBINPUT_CONFIG_TAP_ENABLED);
|
||||
|
||||
return LIBINPUT_CONFIG_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
static enum libinput_config_tap_state
|
||||
tp_tap_config_is_enabled(struct libinput_device *device)
|
||||
{
|
||||
struct evdev_dispatch *dispatch;
|
||||
struct tp_dispatch *tp;
|
||||
struct tp_dispatch *tp = NULL;
|
||||
|
||||
dispatch = ((struct evdev_device *) device)->dispatch;
|
||||
tp = container_of(dispatch, tp, base);
|
||||
|
||||
return tp->tap.enabled;
|
||||
return tp->tap.enabled ? LIBINPUT_CONFIG_TAP_ENABLED :
|
||||
LIBINPUT_CONFIG_TAP_DISABLED;
|
||||
}
|
||||
|
||||
static int
|
||||
static enum libinput_config_tap_state
|
||||
tp_tap_config_get_default(struct libinput_device *device)
|
||||
{
|
||||
/**
|
||||
|
|
@ -662,7 +667,7 @@ tp_tap_config_get_default(struct libinput_device *device)
|
|||
* usually know where to enable it, or at least you can search for
|
||||
* it.
|
||||
*/
|
||||
return false;
|
||||
return LIBINPUT_CONFIG_TAP_DISABLED;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -688,3 +693,9 @@ tp_destroy_tap(struct tp_dispatch *tp)
|
|||
{
|
||||
libinput_timer_cancel(&tp->tap.timer);
|
||||
}
|
||||
|
||||
void
|
||||
tp_release_all_taps(struct tp_dispatch *tp, uint64_t now)
|
||||
{
|
||||
tp_tap_handle_timeout(now, tp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,23 +128,25 @@ tp_get_touch(struct tp_dispatch *tp, unsigned int slot)
|
|||
}
|
||||
|
||||
static inline void
|
||||
tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
{
|
||||
if (t->state != TOUCH_UPDATE) {
|
||||
tp_motion_history_reset(t);
|
||||
t->dirty = true;
|
||||
t->state = TOUCH_BEGIN;
|
||||
t->pinned.is_pinned = false;
|
||||
tp->nfingers_down++;
|
||||
assert(tp->nfingers_down >= 1);
|
||||
tp->queued |= TOUCHPAD_EVENT_MOTION;
|
||||
}
|
||||
if (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE)
|
||||
return;
|
||||
|
||||
tp_motion_history_reset(t);
|
||||
t->dirty = true;
|
||||
t->state = TOUCH_BEGIN;
|
||||
t->pinned.is_pinned = false;
|
||||
t->millis = time;
|
||||
tp->nfingers_down++;
|
||||
assert(tp->nfingers_down >= 1);
|
||||
tp->queued |= TOUCHPAD_EVENT_MOTION;
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t)
|
||||
tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
{
|
||||
if (t->state == TOUCH_NONE)
|
||||
if (t->state == TOUCH_END || t->state == TOUCH_NONE)
|
||||
return;
|
||||
|
||||
t->dirty = true;
|
||||
|
|
@ -152,6 +154,7 @@ tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t)
|
|||
t->palm.is_palm = false;
|
||||
t->state = TOUCH_END;
|
||||
t->pinned.is_pinned = false;
|
||||
t->millis = time;
|
||||
assert(tp->nfingers_down >= 1);
|
||||
tp->nfingers_down--;
|
||||
tp->queued |= TOUCHPAD_EVENT_MOTION;
|
||||
|
|
@ -160,7 +163,7 @@ tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t)
|
|||
static double
|
||||
tp_estimate_delta(int x0, int x1, int x2, int x3)
|
||||
{
|
||||
return (x0 + x1 - x2 - x3) / 4;
|
||||
return (x0 + x1 - x2 - x3) / 4.0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -206,11 +209,10 @@ tp_process_absolute(struct tp_dispatch *tp,
|
|||
tp->slot = e->value;
|
||||
break;
|
||||
case ABS_MT_TRACKING_ID:
|
||||
t->millis = time;
|
||||
if (e->value != -1)
|
||||
tp_begin_touch(tp, t);
|
||||
tp_begin_touch(tp, t, time);
|
||||
else
|
||||
tp_end_touch(tp, t);
|
||||
tp_end_touch(tp, t, time);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -245,7 +247,7 @@ tp_process_fake_touch(struct tp_dispatch *tp,
|
|||
struct tp_touch *t;
|
||||
unsigned int fake_touches;
|
||||
unsigned int nfake_touches;
|
||||
unsigned int i;
|
||||
unsigned int i, start;
|
||||
unsigned int shift;
|
||||
|
||||
if (e->code != BTN_TOUCH &&
|
||||
|
|
@ -266,23 +268,18 @@ tp_process_fake_touch(struct tp_dispatch *tp,
|
|||
fake_touches >>= 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < tp->ntouches; i++) {
|
||||
/* For single touch tps we use BTN_TOUCH for begin / end of touch 0 */
|
||||
start = tp->has_mt ? tp->real_touches : 0;
|
||||
for (i = start; i < tp->ntouches; i++) {
|
||||
t = tp_get_touch(tp, i);
|
||||
if (i >= nfake_touches) {
|
||||
if (t->state != TOUCH_NONE) {
|
||||
tp_end_touch(tp, t);
|
||||
t->millis = time;
|
||||
}
|
||||
} else if (t->state != TOUCH_UPDATE &&
|
||||
t->state != TOUCH_BEGIN) {
|
||||
t->state = TOUCH_NONE;
|
||||
tp_begin_touch(tp, t);
|
||||
t->millis = time;
|
||||
t->fake =true;
|
||||
}
|
||||
if (i < nfake_touches)
|
||||
tp_begin_touch(tp, t, time);
|
||||
else
|
||||
tp_end_touch(tp, t, time);
|
||||
}
|
||||
|
||||
assert(tp->nfingers_down == nfake_touches);
|
||||
/* On mt the actual touch info may arrive after BTN_TOOL_FOO */
|
||||
assert(tp->has_mt || tp->nfingers_down == nfake_touches);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -300,8 +297,7 @@ tp_process_key(struct tp_dispatch *tp,
|
|||
case BTN_TOOL_DOUBLETAP:
|
||||
case BTN_TOOL_TRIPLETAP:
|
||||
case BTN_TOOL_QUADTAP:
|
||||
if (!tp->has_mt)
|
||||
tp_process_fake_touch(tp, e, time);
|
||||
tp_process_fake_touch(tp, e, time);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -406,17 +402,25 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
|
|||
{
|
||||
struct tp_touch *t;
|
||||
struct tp_touch *first = tp_get_touch(tp, 0);
|
||||
unsigned int i;
|
||||
|
||||
tp_for_each_touch(tp, t) {
|
||||
if (!tp->has_mt && t != first && first->fake) {
|
||||
for (i = 0; i < tp->ntouches; i++) {
|
||||
t = tp_get_touch(tp, i);
|
||||
|
||||
/* semi-mt finger postions may "jump" when nfingers changes */
|
||||
if (tp->semi_mt && tp->nfingers_down != tp->old_nfingers_down)
|
||||
tp_motion_history_reset(t);
|
||||
|
||||
if (i >= tp->real_touches && t->state != TOUCH_NONE) {
|
||||
t->x = first->x;
|
||||
t->y = first->y;
|
||||
if (!t->dirty)
|
||||
t->dirty = first->dirty;
|
||||
} else if (!t->dirty) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!t->dirty)
|
||||
continue;
|
||||
|
||||
tp_palm_detect(tp, t, time);
|
||||
|
||||
tp_motion_hysteresis(tp, t);
|
||||
|
|
@ -447,15 +451,15 @@ tp_post_process_state(struct tp_dispatch *tp, uint64_t time)
|
|||
if (!t->dirty)
|
||||
continue;
|
||||
|
||||
if (t->state == TOUCH_END) {
|
||||
if (t->state == TOUCH_END)
|
||||
t->state = TOUCH_NONE;
|
||||
t->fake = false;
|
||||
} else if (t->state == TOUCH_BEGIN)
|
||||
else if (t->state == TOUCH_BEGIN)
|
||||
t->state = TOUCH_UPDATE;
|
||||
|
||||
t->dirty = false;
|
||||
}
|
||||
|
||||
tp->old_nfingers_down = tp->nfingers_down;
|
||||
tp->buttons.old_state = tp->buttons.state;
|
||||
|
||||
tp->queued = TOUCHPAD_EVENT_NONE;
|
||||
|
|
@ -488,47 +492,7 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
|
|||
dy /= nchanged;
|
||||
|
||||
tp_filter_motion(tp, &dx, &dy, time);
|
||||
|
||||
/* Require at least five px scrolling to start */
|
||||
if (dy <= -5.0 || dy >= 5.0)
|
||||
tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
|
||||
|
||||
if (dx <= -5.0 || dx >= 5.0)
|
||||
tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
|
||||
|
||||
if (dy != 0.0 &&
|
||||
(tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))) {
|
||||
pointer_notify_axis(&tp->device->base,
|
||||
time,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
|
||||
dy);
|
||||
}
|
||||
|
||||
if (dx != 0.0 &&
|
||||
(tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))) {
|
||||
pointer_notify_axis(&tp->device->base,
|
||||
time,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
|
||||
dx);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tp_stop_scroll_events(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
/* terminate scrolling with a zero scroll event */
|
||||
if (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
|
||||
pointer_notify_axis(&tp->device->base,
|
||||
time,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
|
||||
0);
|
||||
if (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
|
||||
pointer_notify_axis(&tp->device->base,
|
||||
time,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
|
||||
0);
|
||||
|
||||
tp->scroll.direction = 0;
|
||||
evdev_post_scroll(tp->device, time, dx, dy);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -544,7 +508,7 @@ tp_post_scroll_events(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
if (nfingers_down != 2) {
|
||||
tp_stop_scroll_events(tp, time);
|
||||
evdev_stop_scroll(tp->device, time);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -559,11 +523,17 @@ tp_post_events(struct tp_dispatch *tp, uint64_t time)
|
|||
double dx, dy;
|
||||
int consumed = 0;
|
||||
|
||||
/* Only post (top) button events while suspended */
|
||||
if (tp->device->suspended) {
|
||||
tp_post_button_events(tp, time);
|
||||
return;
|
||||
}
|
||||
|
||||
consumed |= tp_tap_handle_state(tp, time);
|
||||
consumed |= tp_post_button_events(tp, time);
|
||||
|
||||
if (consumed) {
|
||||
tp_stop_scroll_events(tp, time);
|
||||
evdev_stop_scroll(tp->device, time);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -589,6 +559,15 @@ tp_post_events(struct tp_dispatch *tp, uint64_t time)
|
|||
pointer_notify_motion(&tp->device->base, time, dx, dy);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_handle_state(struct tp_dispatch *tp,
|
||||
uint64_t time)
|
||||
{
|
||||
tp_process_state(tp, time);
|
||||
tp_post_events(tp, time);
|
||||
tp_post_process_state(tp, time);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_process(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
|
|
@ -609,9 +588,7 @@ tp_process(struct evdev_dispatch *dispatch,
|
|||
tp_process_key(tp, e, time);
|
||||
break;
|
||||
case EV_SYN:
|
||||
tp_process_state(tp, time);
|
||||
tp_post_events(tp, time);
|
||||
tp_post_process_state(tp, time);
|
||||
tp_handle_state(tp, time);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -630,9 +607,144 @@ tp_destroy(struct evdev_dispatch *dispatch)
|
|||
free(tp);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_clear_state(struct tp_dispatch *tp, struct evdev_device *device)
|
||||
{
|
||||
uint64_t now = libinput_now(tp->device->base.seat->libinput);
|
||||
struct tp_touch *t;
|
||||
|
||||
/* Unroll the touchpad state.
|
||||
* Release buttons first. If tp is a clickpad, the button event
|
||||
* must come before the touch up. If it isn't, the order doesn't
|
||||
* matter anyway
|
||||
*
|
||||
* Then cancel all timeouts on the taps, triggering the last set
|
||||
* of events.
|
||||
*
|
||||
* Then lift all touches so the touchpad is in a neutral state.
|
||||
*
|
||||
*/
|
||||
tp_release_all_buttons(tp, now);
|
||||
tp_release_all_taps(tp, now);
|
||||
|
||||
tp_for_each_touch(tp, t) {
|
||||
tp_end_touch(tp, t, now);
|
||||
}
|
||||
|
||||
tp_handle_state(tp, now);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_suspend(struct tp_dispatch *tp, struct evdev_device *device)
|
||||
{
|
||||
tp_clear_state(tp, device);
|
||||
|
||||
/* On devices with top softwarebuttons we don't actually suspend the
|
||||
* device, to keep the "trackpoint" buttons working. tp_post_events()
|
||||
* will only send events for the trackpoint while suspended.
|
||||
*/
|
||||
if (tp->buttons.has_topbuttons) {
|
||||
evdev_notify_suspended_device(device);
|
||||
/* Enlarge topbutton area while suspended */
|
||||
tp_init_softbuttons(tp, device, 1.5);
|
||||
} else {
|
||||
evdev_device_suspend(device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
|
||||
{
|
||||
if (tp->buttons.has_topbuttons) {
|
||||
/* tap state-machine is offline while suspended, reset state */
|
||||
tp_clear_state(tp, device);
|
||||
/* restore original topbutton area size */
|
||||
tp_init_softbuttons(tp, device, 1.0);
|
||||
evdev_notify_resumed_device(device);
|
||||
} else {
|
||||
evdev_device_resume(device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tp_device_added(struct evdev_device *device,
|
||||
struct evdev_device *added_device)
|
||||
{
|
||||
struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
|
||||
|
||||
if (tp->buttons.trackpoint == NULL &&
|
||||
(added_device->tags & EVDEV_TAG_TRACKPOINT)) {
|
||||
/* Don't send any pending releases to the new trackpoint */
|
||||
tp->buttons.active_is_topbutton = false;
|
||||
tp->buttons.trackpoint = added_device;
|
||||
}
|
||||
|
||||
if (tp->sendevents.current_mode !=
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
|
||||
return;
|
||||
|
||||
if (added_device->tags & EVDEV_TAG_EXTERNAL_MOUSE)
|
||||
tp_suspend(tp, device);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_device_removed(struct evdev_device *device,
|
||||
struct evdev_device *removed_device)
|
||||
{
|
||||
struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
|
||||
struct libinput_device *dev;
|
||||
|
||||
if (removed_device == tp->buttons.trackpoint) {
|
||||
/* Clear any pending releases for the trackpoint */
|
||||
if (tp->buttons.active && tp->buttons.active_is_topbutton) {
|
||||
tp->buttons.active = 0;
|
||||
tp->buttons.active_is_topbutton = false;
|
||||
}
|
||||
tp->buttons.trackpoint = NULL;
|
||||
}
|
||||
|
||||
if (tp->sendevents.current_mode !=
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
|
||||
return;
|
||||
|
||||
list_for_each(dev, &device->base.seat->devices_list, link) {
|
||||
struct evdev_device *d = (struct evdev_device*)dev;
|
||||
if (d != removed_device &&
|
||||
(d->tags & EVDEV_TAG_EXTERNAL_MOUSE)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tp_resume(tp, device);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_tag_device(struct evdev_device *device,
|
||||
struct udev_device *udev_device)
|
||||
{
|
||||
int bustype;
|
||||
|
||||
/* simple approach: touchpads on USB or Bluetooth are considered
|
||||
* external, anything else is internal. Exception is Apple -
|
||||
* internal touchpads are connected over USB and it doesn't have
|
||||
* external USB touchpads anyway.
|
||||
*/
|
||||
bustype = libevdev_get_id_bustype(device->evdev);
|
||||
if (bustype == BUS_USB) {
|
||||
if (libevdev_get_id_vendor(device->evdev) == VENDOR_ID_APPLE)
|
||||
device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
|
||||
} else if (bustype != BUS_BLUETOOTH)
|
||||
device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
|
||||
}
|
||||
|
||||
static struct evdev_dispatch_interface tp_interface = {
|
||||
tp_process,
|
||||
tp_destroy
|
||||
tp_destroy,
|
||||
tp_device_added,
|
||||
tp_device_removed,
|
||||
tp_device_removed, /* device_suspended, treat as remove */
|
||||
tp_device_added, /* device_resumed, treat as add */
|
||||
tp_tag_device,
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
@ -646,41 +758,43 @@ static int
|
|||
tp_init_slots(struct tp_dispatch *tp,
|
||||
struct evdev_device *device)
|
||||
{
|
||||
size_t i;
|
||||
const struct input_absinfo *absinfo;
|
||||
struct map {
|
||||
unsigned int code;
|
||||
int ntouches;
|
||||
} max_touches[] = {
|
||||
{ BTN_TOOL_QUINTTAP, 5 },
|
||||
{ BTN_TOOL_QUADTAP, 4 },
|
||||
{ BTN_TOOL_TRIPLETAP, 3 },
|
||||
{ BTN_TOOL_DOUBLETAP, 2 },
|
||||
};
|
||||
struct map *m;
|
||||
unsigned int i, n_btn_tool_touches = 1;
|
||||
|
||||
absinfo = libevdev_get_abs_info(device->evdev, ABS_MT_SLOT);
|
||||
if (absinfo) {
|
||||
tp->ntouches = absinfo->maximum + 1;
|
||||
tp->real_touches = absinfo->maximum + 1;
|
||||
tp->slot = absinfo->value;
|
||||
tp->has_mt = true;
|
||||
} else {
|
||||
struct map {
|
||||
unsigned int code;
|
||||
int ntouches;
|
||||
} max_touches[] = {
|
||||
{ BTN_TOOL_QUINTTAP, 5 },
|
||||
{ BTN_TOOL_QUADTAP, 4 },
|
||||
{ BTN_TOOL_TRIPLETAP, 3 },
|
||||
{ BTN_TOOL_DOUBLETAP, 2 },
|
||||
};
|
||||
struct map *m;
|
||||
|
||||
tp->real_touches = 1;
|
||||
tp->slot = 0;
|
||||
tp->has_mt = false;
|
||||
tp->ntouches = 1;
|
||||
}
|
||||
|
||||
ARRAY_FOR_EACH(max_touches, m) {
|
||||
if (libevdev_has_event_code(device->evdev,
|
||||
EV_KEY,
|
||||
m->code)) {
|
||||
tp->ntouches = m->ntouches;
|
||||
break;
|
||||
}
|
||||
tp->semi_mt = libevdev_has_property(device->evdev, INPUT_PROP_SEMI_MT);
|
||||
|
||||
ARRAY_FOR_EACH(max_touches, m) {
|
||||
if (libevdev_has_event_code(device->evdev,
|
||||
EV_KEY,
|
||||
m->code)) {
|
||||
n_btn_tool_touches = m->ntouches;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tp->touches = calloc(tp->ntouches,
|
||||
sizeof(struct tp_touch));
|
||||
|
||||
tp->ntouches = max(tp->real_touches, n_btn_tool_touches);
|
||||
tp->touches = calloc(tp->ntouches, sizeof(struct tp_touch));
|
||||
if (!tp->touches)
|
||||
return -1;
|
||||
|
||||
|
|
@ -740,14 +854,6 @@ tp_init_accel(struct tp_dispatch *tp, double diagonal)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tp_init_scroll(struct tp_dispatch *tp)
|
||||
{
|
||||
tp->scroll.direction = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tp_init_palmdetect(struct tp_dispatch *tp,
|
||||
struct evdev_device *device)
|
||||
|
|
@ -757,17 +863,20 @@ tp_init_palmdetect(struct tp_dispatch *tp,
|
|||
tp->palm.right_edge = INT_MAX;
|
||||
tp->palm.left_edge = INT_MIN;
|
||||
|
||||
/* We don't know how big the touchpad is */
|
||||
if (device->abs.absinfo_x->resolution == 1)
|
||||
return 0;
|
||||
|
||||
width = abs(device->abs.absinfo_x->maximum -
|
||||
device->abs.absinfo_x->minimum);
|
||||
|
||||
/* Enable palm detection on touchpads >= 80 mm. Anything smaller
|
||||
probably won't need it, until we find out it does */
|
||||
if (width/device->abs.absinfo_x->resolution < 80)
|
||||
return 0;
|
||||
/* Apple touchpads are always big enough to warrant palm detection */
|
||||
if (evdev_device_get_id_vendor(device) != VENDOR_ID_APPLE) {
|
||||
/* We don't know how big the touchpad is */
|
||||
if (device->abs.absinfo_x->resolution == 1)
|
||||
return 0;
|
||||
|
||||
/* Enable palm detection on touchpads >= 80 mm. Anything smaller
|
||||
probably won't need it, until we find out it does */
|
||||
if (width/device->abs.absinfo_x->resolution < 80)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* palm edges are 5% of the width on each side */
|
||||
tp->palm.right_edge = device->abs.absinfo_x->maximum - width * 0.05;
|
||||
|
|
@ -776,7 +885,6 @@ tp_init_palmdetect(struct tp_dispatch *tp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
tp_init(struct tp_dispatch *tp,
|
||||
struct evdev_device *device)
|
||||
|
|
@ -801,9 +909,6 @@ tp_init(struct tp_dispatch *tp,
|
|||
tp->hysteresis.margin_y =
|
||||
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
|
||||
|
||||
if (tp_init_scroll(tp) != 0)
|
||||
return -1;
|
||||
|
||||
if (tp_init_accel(tp, diagonal) != 0)
|
||||
return -1;
|
||||
|
||||
|
|
@ -816,9 +921,83 @@ tp_init(struct tp_dispatch *tp,
|
|||
if (tp_init_palmdetect(tp, device) != 0)
|
||||
return -1;
|
||||
|
||||
device->seat_caps |= EVDEV_DEVICE_POINTER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
tp_sendevents_get_modes(struct libinput_device *device)
|
||||
{
|
||||
struct evdev_device *evdev = (struct evdev_device*)device;
|
||||
uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED |
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
|
||||
|
||||
if (evdev->tags & EVDEV_TAG_INTERNAL_TOUCHPAD)
|
||||
modes |= LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
static void
|
||||
tp_suspend_conditional(struct tp_dispatch *tp,
|
||||
struct evdev_device *device)
|
||||
{
|
||||
struct libinput_device *dev;
|
||||
|
||||
list_for_each(dev, &device->base.seat->devices_list, link) {
|
||||
struct evdev_device *d = (struct evdev_device*)dev;
|
||||
if (d->tags & EVDEV_TAG_EXTERNAL_MOUSE) {
|
||||
tp_suspend(tp, device);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static enum libinput_config_status
|
||||
tp_sendevents_set_mode(struct libinput_device *device,
|
||||
enum libinput_config_send_events_mode mode)
|
||||
{
|
||||
struct evdev_device *evdev = (struct evdev_device*)device;
|
||||
struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
|
||||
|
||||
if (mode == tp->sendevents.current_mode)
|
||||
return LIBINPUT_CONFIG_STATUS_SUCCESS;
|
||||
|
||||
switch(mode) {
|
||||
case LIBINPUT_CONFIG_SEND_EVENTS_ENABLED:
|
||||
tp_resume(tp, evdev);
|
||||
break;
|
||||
case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
|
||||
tp_suspend(tp, evdev);
|
||||
break;
|
||||
case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
|
||||
tp_suspend_conditional(tp, evdev);
|
||||
break;
|
||||
default:
|
||||
return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
tp->sendevents.current_mode = mode;
|
||||
|
||||
return LIBINPUT_CONFIG_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum libinput_config_send_events_mode
|
||||
tp_sendevents_get_mode(struct libinput_device *device)
|
||||
{
|
||||
struct evdev_device *evdev = (struct evdev_device*)device;
|
||||
struct tp_dispatch *dispatch = (struct tp_dispatch*)evdev->dispatch;
|
||||
|
||||
return dispatch->sendevents.current_mode;
|
||||
}
|
||||
|
||||
static enum libinput_config_send_events_mode
|
||||
tp_sendevents_get_default_mode(struct libinput_device *device)
|
||||
{
|
||||
return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
}
|
||||
|
||||
struct evdev_dispatch *
|
||||
evdev_mt_touchpad_create(struct evdev_device *device)
|
||||
{
|
||||
|
|
@ -833,5 +1012,13 @@ evdev_mt_touchpad_create(struct evdev_device *device)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
device->base.config.sendevents = &tp->sendevents.config;
|
||||
|
||||
tp->sendevents.current_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
tp->sendevents.config.get_modes = tp_sendevents_get_modes;
|
||||
tp->sendevents.config.set_mode = tp_sendevents_set_mode;
|
||||
tp->sendevents.config.get_mode = tp_sendevents_get_mode;
|
||||
tp->sendevents.config.get_default_mode = tp_sendevents_get_default_mode;
|
||||
|
||||
return &tp->base;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
#define TOUCHPAD_HISTORY_LENGTH 4
|
||||
#define TOUCHPAD_MIN_SAMPLES 4
|
||||
|
||||
#define VENDOR_ID_APPLE 0x5ac
|
||||
|
||||
enum touchpad_event {
|
||||
TOUCHPAD_EVENT_NONE = 0,
|
||||
TOUCHPAD_EVENT_MOTION = (1 << 0),
|
||||
|
|
@ -101,7 +103,6 @@ struct tp_touch {
|
|||
struct tp_dispatch *tp;
|
||||
enum touch_state state;
|
||||
bool dirty;
|
||||
bool fake; /* a fake touch */
|
||||
bool is_pointer; /* the pointer-controlling touch */
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
|
|
@ -151,10 +152,13 @@ struct tp_dispatch {
|
|||
struct evdev_dispatch base;
|
||||
struct evdev_device *device;
|
||||
unsigned int nfingers_down; /* number of fingers down */
|
||||
unsigned int old_nfingers_down; /* previous no fingers down */
|
||||
unsigned int slot; /* current slot */
|
||||
bool has_mt;
|
||||
bool semi_mt;
|
||||
|
||||
unsigned int ntouches; /* number of slots */
|
||||
unsigned int real_touches; /* number of slots */
|
||||
unsigned int ntouches; /* no slots inc. fakes */
|
||||
struct tp_touch *touches; /* len == ntouches */
|
||||
unsigned int fake_touches; /* fake touch mask */
|
||||
|
||||
|
|
@ -179,6 +183,7 @@ struct tp_dispatch {
|
|||
uint32_t old_state;
|
||||
uint32_t motion_dist; /* for pinned touches */
|
||||
unsigned int active; /* currently active button, for release event */
|
||||
bool active_is_topbutton; /* is active a top button? */
|
||||
|
||||
/* Only used for clickpads. The software button areas are
|
||||
* always 2 horizontal stripes across the touchpad.
|
||||
|
|
@ -194,11 +199,9 @@ struct tp_dispatch {
|
|||
int32_t rightbutton_left_edge;
|
||||
int32_t leftbutton_right_edge;
|
||||
} top_area;
|
||||
} buttons; /* physical buttons */
|
||||
|
||||
struct {
|
||||
enum libinput_pointer_axis direction;
|
||||
} scroll;
|
||||
struct evdev_device *trackpoint;
|
||||
} buttons; /* physical buttons */
|
||||
|
||||
enum touchpad_event queued;
|
||||
|
||||
|
|
@ -213,6 +216,11 @@ struct tp_dispatch {
|
|||
int32_t right_edge;
|
||||
int32_t left_edge;
|
||||
} palm;
|
||||
|
||||
struct {
|
||||
struct libinput_device_config_send_events config;
|
||||
enum libinput_config_send_events_mode current_mode;
|
||||
} sendevents;
|
||||
};
|
||||
|
||||
#define tp_for_each_touch(_tp, _t) \
|
||||
|
|
@ -236,6 +244,11 @@ tp_destroy_tap(struct tp_dispatch *tp);
|
|||
int
|
||||
tp_init_buttons(struct tp_dispatch *tp, struct evdev_device *device);
|
||||
|
||||
void
|
||||
tp_init_softbuttons(struct tp_dispatch *tp,
|
||||
struct evdev_device *device,
|
||||
double topbutton_size_mult);
|
||||
|
||||
void
|
||||
tp_destroy_buttons(struct tp_dispatch *tp);
|
||||
|
||||
|
|
@ -244,6 +257,10 @@ tp_process_button(struct tp_dispatch *tp,
|
|||
const struct input_event *e,
|
||||
uint64_t time);
|
||||
|
||||
void
|
||||
tp_release_all_buttons(struct tp_dispatch *tp,
|
||||
uint64_t time);
|
||||
|
||||
int
|
||||
tp_post_button_events(struct tp_dispatch *tp, uint64_t time);
|
||||
|
||||
|
|
@ -256,4 +273,8 @@ tp_button_touch_active(struct tp_dispatch *tp, struct tp_touch *t);
|
|||
bool
|
||||
tp_button_is_inside_softbutton_area(struct tp_dispatch *tp, struct tp_touch *t);
|
||||
|
||||
void
|
||||
tp_release_all_taps(struct tp_dispatch *tp,
|
||||
uint64_t time);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
809
src/evdev.c
809
src/evdev.c
File diff suppressed because it is too large
Load diff
104
src/evdev.h
104
src/evdev.h
|
|
@ -26,10 +26,12 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "linux/input.h"
|
||||
#include <libevdev/libevdev.h>
|
||||
|
||||
#include "libinput-private.h"
|
||||
#include "timer.h"
|
||||
|
||||
enum evdev_event_type {
|
||||
EVDEV_NONE,
|
||||
|
|
@ -49,6 +51,12 @@ enum evdev_device_seat_capability {
|
|||
EVDEV_DEVICE_TABLET = (1 << 3),
|
||||
};
|
||||
|
||||
enum evdev_device_tags {
|
||||
EVDEV_TAG_EXTERNAL_MOUSE = (1 << 0),
|
||||
EVDEV_TAG_INTERNAL_TOUCHPAD = (1 << 1),
|
||||
EVDEV_TAG_TRACKPOINT = (1 << 2),
|
||||
};
|
||||
|
||||
struct mt_slot {
|
||||
int32_t seat_slot;
|
||||
int32_t x, y;
|
||||
|
|
@ -64,16 +72,20 @@ struct evdev_device {
|
|||
char *output_name;
|
||||
char *devnode;
|
||||
char *sysname;
|
||||
char *syspath;
|
||||
const char *devname;
|
||||
int fd;
|
||||
struct {
|
||||
const struct input_absinfo *absinfo_x, *absinfo_y;
|
||||
int32_t x, y;
|
||||
int fake_resolution;
|
||||
|
||||
int32_t x, y;
|
||||
int32_t seat_slot;
|
||||
|
||||
int apply_calibration;
|
||||
float calibration[6];
|
||||
struct matrix calibration;
|
||||
struct matrix default_calibration; /* from LIBINPUT_CALIBRATION_MATRIX */
|
||||
struct matrix usermatrix; /* as supplied by the caller */
|
||||
} abs;
|
||||
|
||||
struct {
|
||||
|
|
@ -87,14 +99,31 @@ struct evdev_device {
|
|||
int dx, dy;
|
||||
} rel;
|
||||
|
||||
struct {
|
||||
struct libinput_timer timer;
|
||||
bool has_middle_button_scroll;
|
||||
bool middle_button_scroll_active;
|
||||
double threshold;
|
||||
uint32_t direction;
|
||||
} scroll;
|
||||
|
||||
enum evdev_event_type pending_event;
|
||||
enum evdev_device_seat_capability seat_caps;
|
||||
enum evdev_device_tags tags;
|
||||
|
||||
int is_mt;
|
||||
int suspended;
|
||||
|
||||
struct {
|
||||
struct motion_filter *filter;
|
||||
} pointer;
|
||||
|
||||
/* Bitmask of pressed keys used to ignore initial release events from
|
||||
* the kernel. */
|
||||
unsigned long hw_key_mask[NLONGS(KEY_CNT)];
|
||||
/* Key counter used for multiplexing button events internally in
|
||||
* libinput. */
|
||||
uint8_t key_count[KEY_CNT];
|
||||
};
|
||||
|
||||
#define EVDEV_UNHANDLED_DEVICE ((struct evdev_device *) 1)
|
||||
|
|
@ -110,16 +139,43 @@ struct evdev_dispatch_interface {
|
|||
|
||||
/* Destroy an event dispatch handler and free all its resources. */
|
||||
void (*destroy)(struct evdev_dispatch *dispatch);
|
||||
|
||||
/* A new device was added */
|
||||
void (*device_added)(struct evdev_device *device,
|
||||
struct evdev_device *added_device);
|
||||
|
||||
/* A device was removed */
|
||||
void (*device_removed)(struct evdev_device *device,
|
||||
struct evdev_device *removed_device);
|
||||
|
||||
/* A device was suspended */
|
||||
void (*device_suspended)(struct evdev_device *device,
|
||||
struct evdev_device *suspended_device);
|
||||
|
||||
/* A device was resumed */
|
||||
void (*device_resumed)(struct evdev_device *device,
|
||||
struct evdev_device *resumed_device);
|
||||
|
||||
/* Tag device with one of EVDEV_TAG */
|
||||
void (*tag_device)(struct evdev_device *device,
|
||||
struct udev_device *udev_device);
|
||||
};
|
||||
|
||||
struct evdev_dispatch {
|
||||
struct evdev_dispatch_interface *interface;
|
||||
struct libinput_device_config_calibration calibration;
|
||||
|
||||
struct {
|
||||
struct libinput_device_config_send_events config;
|
||||
enum libinput_config_send_events_mode current_mode;
|
||||
} sendevents;
|
||||
};
|
||||
|
||||
struct evdev_device *
|
||||
evdev_device_create(struct libinput_seat *seat,
|
||||
const char *devnode,
|
||||
const char *sysname);
|
||||
const char *sysname,
|
||||
const char *syspath);
|
||||
|
||||
struct evdev_dispatch *
|
||||
evdev_touchpad_create(struct evdev_device *device);
|
||||
|
|
@ -130,9 +186,6 @@ evdev_mt_touchpad_create(struct evdev_device *device);
|
|||
struct evdev_dispatch *
|
||||
evdev_tablet_create(struct evdev_device *device);
|
||||
|
||||
void
|
||||
evdev_device_proces_event(struct libinput_event *event);
|
||||
|
||||
void
|
||||
evdev_device_led_update(struct evdev_device *device, enum libinput_led leds);
|
||||
|
||||
|
|
@ -155,7 +208,11 @@ unsigned int
|
|||
evdev_device_get_id_vendor(struct evdev_device *device);
|
||||
|
||||
void
|
||||
evdev_device_calibrate(struct evdev_device *device, float calibration[6]);
|
||||
evdev_device_set_default_calibration(struct evdev_device *device,
|
||||
const float calibration[6]);
|
||||
void
|
||||
evdev_device_calibrate(struct evdev_device *device,
|
||||
const float calibration[6]);
|
||||
|
||||
int
|
||||
evdev_device_has_capability(struct evdev_device *device,
|
||||
|
|
@ -175,6 +232,39 @@ double
|
|||
evdev_device_transform_y(struct evdev_device *device,
|
||||
double y,
|
||||
uint32_t height);
|
||||
int
|
||||
evdev_device_suspend(struct evdev_device *device);
|
||||
|
||||
int
|
||||
evdev_device_resume(struct evdev_device *device);
|
||||
|
||||
void
|
||||
evdev_notify_suspended_device(struct evdev_device *device);
|
||||
|
||||
void
|
||||
evdev_notify_resumed_device(struct evdev_device *device);
|
||||
|
||||
void
|
||||
evdev_keyboard_notify_key(struct evdev_device *device,
|
||||
uint32_t time,
|
||||
int key,
|
||||
enum libinput_key_state state);
|
||||
|
||||
void
|
||||
evdev_pointer_notify_button(struct evdev_device *device,
|
||||
uint32_t time,
|
||||
int button,
|
||||
enum libinput_button_state state);
|
||||
|
||||
void
|
||||
evdev_post_scroll(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
double dx,
|
||||
double dy);
|
||||
|
||||
|
||||
void
|
||||
evdev_stop_scroll(struct evdev_device *device, uint64_t time);
|
||||
|
||||
void
|
||||
evdev_device_remove(struct evdev_device *device);
|
||||
|
|
|
|||
|
|
@ -52,9 +52,6 @@ struct motion_filter {
|
|||
struct motion_filter_interface *interface;
|
||||
};
|
||||
|
||||
struct motion_filter *
|
||||
create_linear_acceleration_filter(double speed);
|
||||
|
||||
typedef double (*accel_profile_func_t)(struct motion_filter *filter,
|
||||
void *data,
|
||||
double velocity,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#ifndef LIBINPUT_PRIVATE_H
|
||||
#define LIBINPUT_PRIVATE_H
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "linux/input.h"
|
||||
|
||||
#include "libinput.h"
|
||||
|
|
@ -86,13 +88,33 @@ struct libinput_seat {
|
|||
struct libinput_device_config_tap {
|
||||
int (*count)(struct libinput_device *device);
|
||||
enum libinput_config_status (*set_enabled)(struct libinput_device *device,
|
||||
int enable);
|
||||
int (*get_enabled)(struct libinput_device *device);
|
||||
int (*get_default)(struct libinput_device *device);
|
||||
enum libinput_config_tap_state enable);
|
||||
enum libinput_config_tap_state (*get_enabled)(struct libinput_device *device);
|
||||
enum libinput_config_tap_state (*get_default)(struct libinput_device *device);
|
||||
};
|
||||
|
||||
struct libinput_device_config_calibration {
|
||||
int (*has_matrix)(struct libinput_device *device);
|
||||
enum libinput_config_status (*set_matrix)(struct libinput_device *device,
|
||||
const float matrix[6]);
|
||||
int (*get_matrix)(struct libinput_device *device,
|
||||
float matrix[6]);
|
||||
int (*get_default_matrix)(struct libinput_device *device,
|
||||
float matrix[6]);
|
||||
};
|
||||
|
||||
struct libinput_device_config_send_events {
|
||||
uint32_t (*get_modes)(struct libinput_device *device);
|
||||
enum libinput_config_status (*set_mode)(struct libinput_device *device,
|
||||
enum libinput_config_send_events_mode mode);
|
||||
enum libinput_config_send_events_mode (*get_mode)(struct libinput_device *device);
|
||||
enum libinput_config_send_events_mode (*get_default_mode)(struct libinput_device *device);
|
||||
};
|
||||
|
||||
struct libinput_device_config {
|
||||
struct libinput_device_config_tap *tap;
|
||||
struct libinput_device_config_calibration *calibration;
|
||||
struct libinput_device_config_send_events *sendevents;
|
||||
};
|
||||
|
||||
struct libinput_device {
|
||||
|
|
@ -120,8 +142,8 @@ typedef void (*libinput_source_dispatch_t)(void *data);
|
|||
#define log_info(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_INFO, __VA_ARGS__)
|
||||
#define log_error(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, __VA_ARGS__)
|
||||
#define log_bug_kernel(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, "kernel bug: " __VA_ARGS__)
|
||||
#define log_bug_libinput(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, "libinput bug: " __VA_ARGS__);
|
||||
#define log_bug_client(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, "client bug: " __VA_ARGS__);
|
||||
#define log_bug_libinput(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, "libinput bug: " __VA_ARGS__)
|
||||
#define log_bug_client(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, "client bug: " __VA_ARGS__)
|
||||
|
||||
void
|
||||
log_msg(struct libinput *libinput,
|
||||
|
|
@ -255,4 +277,17 @@ tablet_notify_button(struct libinput_device *device,
|
|||
void
|
||||
touch_notify_frame(struct libinput_device *device,
|
||||
uint32_t time);
|
||||
|
||||
static inline uint64_t
|
||||
libinput_now(struct libinput *libinput)
|
||||
{
|
||||
struct timespec ts = { 0, 0 };
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
|
||||
log_error(libinput, "clock_gettime failed: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000;
|
||||
}
|
||||
#endif /* LIBINPUT_PRIVATE_H */
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "libinput.h"
|
||||
|
||||
|
|
@ -72,9 +74,11 @@ int list_empty(const struct list *list);
|
|||
pos = tmp, \
|
||||
tmp = container_of(pos->member.next, tmp, member))
|
||||
|
||||
#define LONG_BITS (sizeof(long) * 8)
|
||||
#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
|
||||
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
||||
#define ARRAY_FOR_EACH(_arr, _elem) \
|
||||
for (size_t _i = 0; (_elem = &_arr[_i]) && _i < ARRAY_LENGTH(_arr); _i++)
|
||||
for (size_t _i = 0; _i < ARRAY_LENGTH(_arr) && (_elem = &_arr[_i]); _i++)
|
||||
|
||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
|
@ -174,4 +178,130 @@ vector_get_direction(int dx, int dy)
|
|||
return dir;
|
||||
}
|
||||
|
||||
static inline int
|
||||
long_bit_is_set(const unsigned long *array, int bit)
|
||||
{
|
||||
return !!(array[bit / LONG_BITS] & (1LL << (bit % LONG_BITS)));
|
||||
}
|
||||
|
||||
static inline void
|
||||
long_set_bit(unsigned long *array, int bit)
|
||||
{
|
||||
array[bit / LONG_BITS] |= (1LL << (bit % LONG_BITS));
|
||||
}
|
||||
|
||||
static inline void
|
||||
long_clear_bit(unsigned long *array, int bit)
|
||||
{
|
||||
array[bit / LONG_BITS] &= ~(1LL << (bit % LONG_BITS));
|
||||
}
|
||||
|
||||
static inline void
|
||||
long_set_bit_state(unsigned long *array, int bit, int state)
|
||||
{
|
||||
if (state)
|
||||
long_set_bit(array, bit);
|
||||
else
|
||||
long_clear_bit(array, bit);
|
||||
}
|
||||
|
||||
struct matrix {
|
||||
float val[3][3]; /* [row][col] */
|
||||
};
|
||||
|
||||
static inline void
|
||||
matrix_init_identity(struct matrix *m)
|
||||
{
|
||||
memset(m, 0, sizeof(*m));
|
||||
m->val[0][0] = 1;
|
||||
m->val[1][1] = 1;
|
||||
m->val[2][2] = 1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
matrix_from_farray6(struct matrix *m, const float values[6])
|
||||
{
|
||||
matrix_init_identity(m);
|
||||
m->val[0][0] = values[0];
|
||||
m->val[0][1] = values[1];
|
||||
m->val[0][2] = values[2];
|
||||
m->val[1][0] = values[3];
|
||||
m->val[1][1] = values[4];
|
||||
m->val[1][2] = values[5];
|
||||
}
|
||||
|
||||
static inline void
|
||||
matrix_init_scale(struct matrix *m, float sx, float sy)
|
||||
{
|
||||
matrix_init_identity(m);
|
||||
m->val[0][0] = sx;
|
||||
m->val[1][1] = sy;
|
||||
}
|
||||
|
||||
static inline void
|
||||
matrix_init_translate(struct matrix *m, float x, float y)
|
||||
{
|
||||
matrix_init_identity(m);
|
||||
m->val[0][2] = x;
|
||||
m->val[1][2] = y;
|
||||
}
|
||||
|
||||
static inline int
|
||||
matrix_is_identity(struct matrix *m)
|
||||
{
|
||||
return (m->val[0][0] == 1 &&
|
||||
m->val[0][1] == 0 &&
|
||||
m->val[0][2] == 0 &&
|
||||
m->val[1][0] == 0 &&
|
||||
m->val[1][1] == 1 &&
|
||||
m->val[1][2] == 0 &&
|
||||
m->val[2][0] == 0 &&
|
||||
m->val[2][1] == 0 &&
|
||||
m->val[2][2] == 1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
matrix_mult(struct matrix *dest,
|
||||
const struct matrix *m1,
|
||||
const struct matrix *m2)
|
||||
{
|
||||
struct matrix m; /* allow for dest == m1 or dest == m2 */
|
||||
int row, col, i;
|
||||
|
||||
for (row = 0; row < 3; row++) {
|
||||
for (col = 0; col < 3; col++) {
|
||||
double v = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
v += m1->val[row][i] * m2->val[i][col];
|
||||
}
|
||||
m.val[row][col] = v;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(dest, &m, sizeof(m));
|
||||
}
|
||||
|
||||
static inline void
|
||||
matrix_mult_vec(struct matrix *m, int *x, int *y)
|
||||
{
|
||||
int tx, ty;
|
||||
|
||||
tx = *x * m->val[0][0] + *y * m->val[0][1] + m->val[0][2];
|
||||
ty = *x * m->val[1][0] + *y * m->val[1][1] + m->val[1][2];
|
||||
|
||||
*x = tx;
|
||||
*y = ty;
|
||||
}
|
||||
|
||||
static inline void
|
||||
matrix_to_farray6(const struct matrix *m, float out[6])
|
||||
{
|
||||
out[0] = m->val[0][0];
|
||||
out[1] = m->val[0][1];
|
||||
out[2] = m->val[0][2];
|
||||
out[3] = m->val[1][0];
|
||||
out[4] = m->val[1][1];
|
||||
out[5] = m->val[1][2];
|
||||
}
|
||||
|
||||
#endif /* LIBINPUT_UTIL_H */
|
||||
|
|
|
|||
|
|
@ -662,7 +662,6 @@ libinput_add_fd(struct libinput *libinput,
|
|||
ep.data.ptr = source;
|
||||
|
||||
if (epoll_ctl(libinput->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) {
|
||||
close(source->fd);
|
||||
free(source);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1605,8 +1604,12 @@ libinput_device_config_tap_get_finger_count(struct libinput_device *device)
|
|||
|
||||
LIBINPUT_EXPORT enum libinput_config_status
|
||||
libinput_device_config_tap_set_enabled(struct libinput_device *device,
|
||||
int enable)
|
||||
enum libinput_config_tap_state enable)
|
||||
{
|
||||
if (enable != LIBINPUT_CONFIG_TAP_ENABLED &&
|
||||
enable != LIBINPUT_CONFIG_TAP_DISABLED)
|
||||
return LIBINPUT_CONFIG_STATUS_INVALID;
|
||||
|
||||
if (enable &&
|
||||
libinput_device_config_tap_get_finger_count(device) == 0)
|
||||
return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
|
||||
|
|
@ -1614,20 +1617,96 @@ libinput_device_config_tap_set_enabled(struct libinput_device *device,
|
|||
return device->config.tap->set_enabled(device, enable);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
LIBINPUT_EXPORT enum libinput_config_tap_state
|
||||
libinput_device_config_tap_get_enabled(struct libinput_device *device)
|
||||
{
|
||||
if (libinput_device_config_tap_get_finger_count(device) == 0)
|
||||
return 0;
|
||||
return LIBINPUT_CONFIG_TAP_DISABLED;
|
||||
|
||||
return device->config.tap->get_enabled(device);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
LIBINPUT_EXPORT enum libinput_config_tap_state
|
||||
libinput_device_config_tap_get_default_enabled(struct libinput_device *device)
|
||||
{
|
||||
if (libinput_device_config_tap_get_finger_count(device) == 0)
|
||||
return 0;
|
||||
return LIBINPUT_CONFIG_TAP_DISABLED;
|
||||
|
||||
return device->config.tap->get_default(device);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
libinput_device_config_calibration_has_matrix(struct libinput_device *device)
|
||||
{
|
||||
return device->config.calibration ?
|
||||
device->config.calibration->has_matrix(device) : 0;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT enum libinput_config_status
|
||||
libinput_device_config_calibration_set_matrix(struct libinput_device *device,
|
||||
const float matrix[6])
|
||||
{
|
||||
if (!libinput_device_config_calibration_has_matrix(device))
|
||||
return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
|
||||
|
||||
return device->config.calibration->set_matrix(device, matrix);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
libinput_device_config_calibration_get_matrix(struct libinput_device *device,
|
||||
float matrix[6])
|
||||
{
|
||||
if (!libinput_device_config_calibration_has_matrix(device))
|
||||
return 0;
|
||||
|
||||
return device->config.calibration->get_matrix(device, matrix);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
libinput_device_config_calibration_get_default_matrix(struct libinput_device *device,
|
||||
float matrix[6])
|
||||
{
|
||||
if (!libinput_device_config_calibration_has_matrix(device))
|
||||
return 0;
|
||||
|
||||
return device->config.calibration->get_default_matrix(device, matrix);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT uint32_t
|
||||
libinput_device_config_send_events_get_modes(struct libinput_device *device)
|
||||
{
|
||||
uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
|
||||
if (device->config.sendevents)
|
||||
modes |= device->config.sendevents->get_modes(device);
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT enum libinput_config_status
|
||||
libinput_device_config_send_events_set_mode(struct libinput_device *device,
|
||||
enum libinput_config_send_events_mode mode)
|
||||
{
|
||||
if ((libinput_device_config_send_events_get_modes(device) & mode) == 0)
|
||||
return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
|
||||
|
||||
if (device->config.sendevents)
|
||||
return device->config.sendevents->set_mode(device, mode);
|
||||
else /* mode must be _ENABLED to get here */
|
||||
return LIBINPUT_CONFIG_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT enum libinput_config_send_events_mode
|
||||
libinput_device_config_send_events_get_mode(struct libinput_device *device)
|
||||
{
|
||||
if (device->config.sendevents)
|
||||
return device->config.sendevents->get_mode(device);
|
||||
else
|
||||
return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT enum libinput_config_send_events_mode
|
||||
libinput_device_config_send_events_get_default_mode(struct libinput_device *device)
|
||||
{
|
||||
return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
}
|
||||
|
|
|
|||
306
src/libinput.h
306
src/libinput.h
|
|
@ -103,6 +103,38 @@ extern "C" {
|
|||
* middle button click.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page udev_config Static device configuration via udev
|
||||
*
|
||||
* libinput supports some static configuration through udev properties.
|
||||
* These propertiesare read when the device is initially added
|
||||
* to libinput's device list, i.e. before the @ref
|
||||
* LIBINPUT_EVENT_DEVICE_ADDED event is generated.
|
||||
*
|
||||
* The following udev properties are supported:
|
||||
* <dl>
|
||||
* <dt>LIBINPUT_CALIBRATION_MATRIX</dt>
|
||||
* <dd>Sets the calibration matrix, see
|
||||
* libinput_device_config_calibration_get_default_matrix(). If unset,
|
||||
* defaults to the identity matrix.</dd>
|
||||
* <dt>ID_SEAT</dt>
|
||||
* <dd>Assigns the physical seat for this device. See
|
||||
* libinput_seat_get_physical_name(). Defaults to "seat0".</dd>
|
||||
* <dt>WL_SEAT</dt>
|
||||
* <dd>Assigns the logical seat for this device. See
|
||||
* libinput_seat_get_logical_name()
|
||||
* context. Defaults to "default".</dd>
|
||||
* </dl>
|
||||
*
|
||||
* Below is an example udev rule to assign "seat1" to a device from vendor
|
||||
* 0x012a with the model ID of 0x034b.
|
||||
* @code
|
||||
* ACTION=="add|change", KERNEL=="event[0-9]*", ENV{ID_VENDOR_ID}=="012a", \
|
||||
* ENV{ID_MODEL_ID}=="034b", ENV{ID_SEAT}="seat1"
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Log priority for internal logging messages.
|
||||
*/
|
||||
|
|
@ -513,6 +545,9 @@ libinput_event_pointer_get_time(struct libinput_event_pointer *event);
|
|||
* events that are not of type LIBINPUT_EVENT_POINTER_MOTION, this function
|
||||
* returns 0.
|
||||
*
|
||||
* If a device employs pointer acceleration, the delta returned by this
|
||||
* function is the accelerated delta.
|
||||
*
|
||||
* @note It is an application bug to call this function for events other than
|
||||
* LIBINPUT_EVENT_POINTER_MOTION.
|
||||
*
|
||||
|
|
@ -528,6 +563,9 @@ libinput_event_pointer_get_dx(struct libinput_event_pointer *event);
|
|||
* events that are not of type LIBINPUT_EVENT_POINTER_MOTION, this function
|
||||
* returns 0.
|
||||
*
|
||||
* If a device employs pointer acceleration, the delta returned by this
|
||||
* function is the accelerated delta.
|
||||
*
|
||||
* @note It is an application bug to call this function for events other than
|
||||
* LIBINPUT_EVENT_POINTER_MOTION.
|
||||
*
|
||||
|
|
@ -1676,24 +1714,18 @@ libinput_device_led_update(struct libinput_device *device,
|
|||
*/
|
||||
int
|
||||
libinput_device_get_keys(struct libinput_device *device,
|
||||
char *keys, size_t size);
|
||||
char *keys, size_t size)
|
||||
LIBINPUT_ATTRIBUTE_DEPRECATED;
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
*
|
||||
* Apply the 3x3 transformation matrix to absolute device coordinates. This
|
||||
* matrix has no effect on relative events.
|
||||
*
|
||||
* Given a 6-element array [a, b, c, d, e, f], the matrix is applied as
|
||||
* @code
|
||||
* [ a b c ] [ x ]
|
||||
* [ d e f ] * [ y ]
|
||||
* [ 0 0 1 ] [ 1 ]
|
||||
* @endcode
|
||||
* @deprecated Use libinput_device_config_calibration_set_matrix() instead.
|
||||
*/
|
||||
void
|
||||
libinput_device_calibrate(struct libinput_device *device,
|
||||
float calibration[6]);
|
||||
float calibration[6])
|
||||
LIBINPUT_ATTRIBUTE_DEPRECATED;
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
|
|
@ -1764,6 +1796,16 @@ enum libinput_config_status {
|
|||
const char *
|
||||
libinput_config_status_to_str(enum libinput_config_status status);
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*/
|
||||
enum libinput_config_tap_state {
|
||||
LIBINPUT_CONFIG_TAP_DISABLED, /**< Tapping is to be disabled, or is
|
||||
currently disabled */
|
||||
LIBINPUT_CONFIG_TAP_ENABLED, /**< Tapping is to be enabled, or is
|
||||
currently enabled */
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*
|
||||
|
|
@ -1776,7 +1818,7 @@ libinput_config_status_to_str(enum libinput_config_status status);
|
|||
*
|
||||
* @see libinput_device_config_tap_set_enabled
|
||||
* @see libinput_device_config_tap_get_enabled
|
||||
* @see libinput_device_config_tap_set_enabled_get_default
|
||||
* @see libinput_device_config_tap_get_default_enabled
|
||||
*/
|
||||
int
|
||||
libinput_device_config_tap_get_finger_count(struct libinput_device *device);
|
||||
|
|
@ -1791,7 +1833,8 @@ libinput_device_config_tap_get_finger_count(struct libinput_device *device);
|
|||
* libinput_device_config_tap_get_finger_count().
|
||||
*
|
||||
* @param device The device to configure
|
||||
* @param enable Non-zero to enable, zero to disable
|
||||
* @param enable @ref LIBINPUT_CONFIG_TAP_ENABLED to enable tapping or @ref
|
||||
* LIBINPUT_CONFIG_TAP_DISABLED to disable tapping
|
||||
*
|
||||
* @return A config status code. Disabling tapping on a device that does not
|
||||
* support tapping always succeeds.
|
||||
|
|
@ -1802,7 +1845,7 @@ libinput_device_config_tap_get_finger_count(struct libinput_device *device);
|
|||
*/
|
||||
enum libinput_config_status
|
||||
libinput_device_config_tap_set_enabled(struct libinput_device *device,
|
||||
int enable);
|
||||
enum libinput_config_tap_state enable);
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
|
|
@ -1812,13 +1855,14 @@ libinput_device_config_tap_set_enabled(struct libinput_device *device,
|
|||
*
|
||||
* @param device The device to configure
|
||||
*
|
||||
* @return 1 if enabled, 0 otherwise.
|
||||
* @return @ref LIBINPUT_CONFIG_TAP_ENABLED if tapping is currently enabled,
|
||||
* or @ref LIBINPUT_CONFIG_TAP_DISABLED is currently disabled
|
||||
*
|
||||
* @see libinput_device_config_tap_get_finger_count
|
||||
* @see libinput_device_config_tap_set_enabled
|
||||
* @see libinput_device_config_tap_get_default_enabled
|
||||
*/
|
||||
int
|
||||
enum libinput_config_tap_state
|
||||
libinput_device_config_tap_get_enabled(struct libinput_device *device);
|
||||
|
||||
/**
|
||||
|
|
@ -1827,15 +1871,241 @@ libinput_device_config_tap_get_enabled(struct libinput_device *device);
|
|||
* Return the default setting for whether tapping is enabled on this device.
|
||||
*
|
||||
* @param device The device to configure
|
||||
* @return 1 if tapping is enabled by default, or 0 otherwise
|
||||
* @return @ref LIBINPUT_CONFIG_TAP_ENABLED if tapping is enabled by default,
|
||||
* or @ref LIBINPUT_CONFIG_TAP_DISABLED is disabled by default
|
||||
*
|
||||
* @see libinput_device_config_tap_get_finger_count
|
||||
* @see libinput_device_config_tap_set_enabled
|
||||
* @see libinput_device_config_tap_get_enabled
|
||||
*/
|
||||
int
|
||||
enum libinput_config_tap_state
|
||||
libinput_device_config_tap_get_default_enabled(struct libinput_device *device);
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*
|
||||
* Check if the device can be calibrated via a calibration matrix.
|
||||
*
|
||||
* @param device The device to check
|
||||
* @return non-zero if the device can be calibrated, zero otherwise.
|
||||
*
|
||||
* @see libinput_device_config_calibration_set_matrix
|
||||
* @see libinput_device_config_calibration_get_matrix
|
||||
* @see libinput_device_config_calibration_get_default_matrix
|
||||
*/
|
||||
int
|
||||
libinput_device_config_calibration_has_matrix(struct libinput_device *device);
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*
|
||||
* Apply the 3x3 transformation matrix to absolute device coordinates. This
|
||||
* matrix has no effect on relative events.
|
||||
*
|
||||
* Given a 6-element array [a, b, c, d, e, f], the matrix is applied as
|
||||
* @code
|
||||
* [ a b c ] [ x ]
|
||||
* [ d e f ] * [ y ]
|
||||
* [ 0 0 1 ] [ 1 ]
|
||||
* @endcode
|
||||
*
|
||||
* The translation component (c, f) is expected to be normalized to the
|
||||
* device coordinate range. For example, the matrix
|
||||
* @code
|
||||
* [ 1 0 1 ]
|
||||
* [ 0 1 -1 ]
|
||||
* [ 0 0 1 ]
|
||||
* @endcode
|
||||
* moves all coordinates by 1 device-width to the right and 1 device-height
|
||||
* up.
|
||||
*
|
||||
* The rotation matrix for rotation around the origin is defined as
|
||||
* @code
|
||||
* [ cos(a) -sin(a) 0 ]
|
||||
* [ sin(a) cos(a) 0 ]
|
||||
* [ 0 0 1 ]
|
||||
* @endcode
|
||||
* Note that any rotation requires an additional translation component to
|
||||
* translate the rotated coordinates back into the original device space.
|
||||
* The rotation matrixes for 90, 180 and 270 degrees clockwise are:
|
||||
* @code
|
||||
* 90 deg cw: 180 deg cw: 270 deg cw:
|
||||
* [ 0 -1 1] [ -1 0 1] [ 0 1 0 ]
|
||||
* [ 1 0 0] [ 0 -1 1] [ -1 0 1 ]
|
||||
* [ 0 0 1] [ 0 0 1] [ 0 0 1 ]
|
||||
* @endcode
|
||||
*
|
||||
* @param device The device to configure
|
||||
* @param matrix An array representing the first two rows of a 3x3 matrix as
|
||||
* described above.
|
||||
*
|
||||
* @return A config status code.
|
||||
*
|
||||
* @see libinput_device_config_calibration_has_matrix
|
||||
* @see libinput_device_config_calibration_get_matrix
|
||||
* @see libinput_device_config_calibration_get_default_matrix
|
||||
*/
|
||||
enum libinput_config_status
|
||||
libinput_device_config_calibration_set_matrix(struct libinput_device *device,
|
||||
const float matrix[6]);
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*
|
||||
* Return the current calibration matrix for this device.
|
||||
*
|
||||
* @param device The device to configure
|
||||
* @param matrix Set to the array representing the first two rows of a 3x3 matrix as
|
||||
* described in libinput_device_config_calibration_set_matrix().
|
||||
*
|
||||
* @return 0 if no calibration is set and the returned matrix is the
|
||||
* identity matrix, 1 otherwise
|
||||
*
|
||||
* @see libinput_device_config_calibration_has_matrix
|
||||
* @see libinput_device_config_calibration_set_matrix
|
||||
* @see libinput_device_config_calibration_get_default_matrix
|
||||
*/
|
||||
int
|
||||
libinput_device_config_calibration_get_matrix(struct libinput_device *device,
|
||||
float matrix[6]);
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*
|
||||
* Return the default calibration matrix for this device. On most devices,
|
||||
* this is the identity matrix. If the udev property
|
||||
* <b>LIBINPUT_CALIBRATION_MATRIX</b> is set on the respective udev device,
|
||||
* that property's value becomes the default matrix.
|
||||
*
|
||||
* The udev property is parsed as 6 floating point numbers separated by a
|
||||
* single space each (scanf(3) format "%f %f %f %f %f %f").
|
||||
* The 6 values represent the first two rows of the calibration matrix as
|
||||
* described in libinput_device_config_calibration_set_matrix().
|
||||
*
|
||||
* Example values are:
|
||||
* @code
|
||||
* ENV{LIBINPUT_CALIBRATION_MATRIX}="1 0 0 0 1 0" # default
|
||||
* ENV{LIBINPUT_CALIBRATION_MATRIX}="0 -1 1 1 0 0" # 90 degree clockwise
|
||||
* ENV{LIBINPUT_CALIBRATION_MATRIX}="-1 0 1 0 -1 1" # 180 degree clockwise
|
||||
* ENV{LIBINPUT_CALIBRATION_MATRIX}="0 1 0 -1 0 1" # 270 degree clockwise
|
||||
* ENV{LIBINPUT_CALIBRATION_MATRIX}="-1 0 1 1 0 0" # reflect along y axis
|
||||
* @endcode
|
||||
*
|
||||
* @param device The device to configure
|
||||
* @param matrix Set to the array representing the first two rows of a 3x3 matrix as
|
||||
* described in libinput_device_config_calibration_set_matrix().
|
||||
*
|
||||
* @return 0 if no calibration is set and the returned matrix is the
|
||||
* identity matrix, 1 otherwise
|
||||
*
|
||||
* @see libinput_device_config_calibration_has_matrix
|
||||
* @see libinput_device_config_calibration_set_matrix
|
||||
* @see libinput_device_config_calibration_get_default_matrix
|
||||
*/
|
||||
int
|
||||
libinput_device_config_calibration_get_default_matrix(struct libinput_device *device,
|
||||
float matrix[6]);
|
||||
|
||||
/**
|
||||
* The send-event mode of a device defines when a device may generate events
|
||||
* and pass those events to the caller.
|
||||
*/
|
||||
enum libinput_config_send_events_mode {
|
||||
/**
|
||||
* Send events from this device normally.
|
||||
*/
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED = (1 << 0),
|
||||
/**
|
||||
* Do not send events through this device. Depending on the device,
|
||||
* this may close all file descriptors on the device or it may leave
|
||||
* the file descriptors open and route events through a different
|
||||
* device.
|
||||
*/
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED = (1 << 1),
|
||||
/**
|
||||
* If an external pointer device is plugged in, do not send events
|
||||
* from this device. This option may be available on built-in
|
||||
* touchpads.
|
||||
*/
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE = (1 << 2),
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*
|
||||
* Return the possible send-event modes for this device. These modes define
|
||||
* when a device may process and send events.
|
||||
*
|
||||
* @param device The device to configure
|
||||
*
|
||||
* @return A bitmask of possible modes.
|
||||
*
|
||||
* @see libinput_device_config_send_events_set_mode
|
||||
* @see libinput_device_config_send_events_get_mode
|
||||
* @see libinput_device_config_send_events_get_default_mode
|
||||
*/
|
||||
uint32_t
|
||||
libinput_device_config_send_events_get_modes(struct libinput_device *device);
|
||||
|
||||
/**
|
||||
* Set the send-event mode for this device. The mode defines when the device
|
||||
* processes and sends events to the caller.
|
||||
*
|
||||
* The selected mode may not take effect immediately. Events already
|
||||
* received and processed from this device are unaffected and will be passed
|
||||
* to the caller on the next call to libinput_get_event().
|
||||
*
|
||||
* If the mode is one of @ref LIBINPUT_CONFIG_SEND_EVENTS_DISABLED or
|
||||
* @ref LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE, the device
|
||||
* may wait for or generate events until it is in a neutral state.
|
||||
* For example, this may include waiting for or generating button release
|
||||
* events.
|
||||
*
|
||||
* If the device is already suspended, this function does nothing and
|
||||
* returns success. Changing the send-event mode on a device that has been
|
||||
* removed is permitted.
|
||||
*
|
||||
* @param device The device to configure
|
||||
* @param mode The send-event mode for this device.
|
||||
*
|
||||
* @return A config status code.
|
||||
*
|
||||
* @see libinput_device_config_send_events_get_modes
|
||||
* @see libinput_device_config_send_events_get_mode
|
||||
* @see libinput_device_config_send_events_get_default_mode
|
||||
*/
|
||||
enum libinput_config_status
|
||||
libinput_device_config_send_events_set_mode(struct libinput_device *device,
|
||||
enum libinput_config_send_events_mode mode);
|
||||
|
||||
/**
|
||||
* Get the send-event mode for this device. The mode defines when the device
|
||||
* processes and sends events to the caller.
|
||||
*
|
||||
* @param device The device to configure
|
||||
* @return The current send-event mode for this device.
|
||||
*
|
||||
* @see libinput_device_config_send_events_get_modes
|
||||
* @see libinput_device_config_send_events_set_mode
|
||||
* @see libinput_device_config_send_events_get_default_mode
|
||||
*/
|
||||
enum libinput_config_send_events_mode
|
||||
libinput_device_config_send_events_get_mode(struct libinput_device *device);
|
||||
|
||||
/**
|
||||
* Get the default send-event mode for this device. The mode defines when
|
||||
* the device processes and sends events to the caller.
|
||||
*
|
||||
* @param device The device to configure
|
||||
* @return The current send-event mode for this device.
|
||||
*
|
||||
* @see libinput_device_config_send_events_get_modes
|
||||
* @see libinput_device_config_send_events_set_mode
|
||||
* @see libinput_device_config_send_events_get_default_mode
|
||||
*/
|
||||
enum libinput_config_send_events_mode
|
||||
libinput_device_config_send_events_get_default_mode(struct libinput_device *device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ path_seat_get_named(struct path_input *input,
|
|||
static int
|
||||
path_get_udev_properties(const char *path,
|
||||
char **sysname,
|
||||
char **syspath,
|
||||
char **seat_name,
|
||||
char **seat_logical_name)
|
||||
{
|
||||
|
|
@ -133,6 +134,7 @@ path_get_udev_properties(const char *path,
|
|||
goto out;
|
||||
|
||||
*sysname = strdup(udev_device_get_sysname(device));
|
||||
*syspath = strdup(udev_device_get_syspath(device));
|
||||
|
||||
seat = udev_device_get_property_value(device, "ID_SEAT");
|
||||
*seat_name = strdup(seat ? seat : default_seat);
|
||||
|
|
@ -155,10 +157,10 @@ path_device_enable(struct path_input *input, const char *devnode)
|
|||
{
|
||||
struct path_seat *seat;
|
||||
struct evdev_device *device = NULL;
|
||||
char *sysname = NULL;
|
||||
char *sysname = NULL, *syspath = NULL;
|
||||
char *seat_name = NULL, *seat_logical_name = NULL;
|
||||
|
||||
if (path_get_udev_properties(devnode, &sysname,
|
||||
if (path_get_udev_properties(devnode, &sysname, &syspath,
|
||||
&seat_name, &seat_logical_name) == -1) {
|
||||
log_info(&input->base,
|
||||
"failed to obtain sysname for device '%s'.\n",
|
||||
|
|
@ -180,7 +182,7 @@ path_device_enable(struct path_input *input, const char *devnode)
|
|||
}
|
||||
}
|
||||
|
||||
device = evdev_device_create(&seat->base, devnode, sysname);
|
||||
device = evdev_device_create(&seat->base, devnode, sysname, syspath);
|
||||
libinput_seat_unref(&seat->base);
|
||||
|
||||
if (device == EVDEV_UNHANDLED_DEVICE) {
|
||||
|
|
@ -198,6 +200,7 @@ path_device_enable(struct path_input *input, const char *devnode)
|
|||
|
||||
out:
|
||||
free(sysname);
|
||||
free(syspath);
|
||||
free(seat_name);
|
||||
free(seat_logical_name);
|
||||
|
||||
|
|
|
|||
29
src/timer.c
29
src/timer.c
|
|
@ -67,19 +67,12 @@ void
|
|||
libinput_timer_set(struct libinput_timer *timer, uint64_t expire)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
|
||||
uint64_t now = ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000;
|
||||
if (abs(expire - now) > 5000)
|
||||
log_bug_libinput(timer->libinput,
|
||||
"timer offset more than 5s, now %"
|
||||
PRIu64 " expire %" PRIu64 "\n",
|
||||
now, expire);
|
||||
} else {
|
||||
log_error(timer->libinput,
|
||||
"clock_gettime error: %s\n", strerror(errno));
|
||||
}
|
||||
uint64_t now = libinput_now(timer->libinput);
|
||||
if (abs(expire - now) > 5000)
|
||||
log_bug_libinput(timer->libinput,
|
||||
"timer offset more than 5s, now %"
|
||||
PRIu64 " expire %" PRIu64 "\n",
|
||||
now, expire);
|
||||
#endif
|
||||
|
||||
assert(expire);
|
||||
|
|
@ -107,17 +100,11 @@ libinput_timer_handler(void *data)
|
|||
{
|
||||
struct libinput *libinput = data;
|
||||
struct libinput_timer *timer, *tmp;
|
||||
struct timespec ts;
|
||||
uint64_t now;
|
||||
int r;
|
||||
|
||||
r = clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
if (r) {
|
||||
log_error(libinput, "clock_gettime error: %s\n", strerror(errno));
|
||||
now = libinput_now(libinput);
|
||||
if (now == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
now = ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000;
|
||||
|
||||
list_for_each_safe(timer, tmp, &libinput->timer.list, link) {
|
||||
if (timer->expire <= now) {
|
||||
|
|
|
|||
|
|
@ -47,8 +47,10 @@ device_added(struct udev_device *udev_device, struct udev_input *input)
|
|||
struct evdev_device *device;
|
||||
const char *devnode;
|
||||
const char *sysname;
|
||||
const char *syspath;
|
||||
const char *device_seat, *seat_name, *output_name;
|
||||
const char *calibration_values;
|
||||
float calibration[6];
|
||||
struct udev_seat *seat;
|
||||
|
||||
device_seat = udev_device_get_property_value(udev_device, "ID_SEAT");
|
||||
|
|
@ -60,6 +62,7 @@ device_added(struct udev_device *udev_device, struct udev_input *input)
|
|||
|
||||
devnode = udev_device_get_devnode(udev_device);
|
||||
sysname = udev_device_get_sysname(udev_device);
|
||||
syspath = udev_device_get_syspath(udev_device);
|
||||
|
||||
/* Search for matching logical seat */
|
||||
seat_name = udev_device_get_property_value(udev_device, "WL_SEAT");
|
||||
|
|
@ -76,7 +79,7 @@ device_added(struct udev_device *udev_device, struct udev_input *input)
|
|||
return -1;
|
||||
}
|
||||
|
||||
device = evdev_device_create(&seat->base, devnode, sysname);
|
||||
device = evdev_device_create(&seat->base, devnode, sysname, syspath);
|
||||
libinput_seat_unref(&seat->base);
|
||||
|
||||
if (device == EVDEV_UNHANDLED_DEVICE) {
|
||||
|
|
@ -89,25 +92,25 @@ device_added(struct udev_device *udev_device, struct udev_input *input)
|
|||
|
||||
calibration_values =
|
||||
udev_device_get_property_value(udev_device,
|
||||
"WL_CALIBRATION");
|
||||
"LIBINPUT_CALIBRATION_MATRIX");
|
||||
|
||||
if (calibration_values && sscanf(calibration_values,
|
||||
"%f %f %f %f %f %f",
|
||||
&device->abs.calibration[0],
|
||||
&device->abs.calibration[1],
|
||||
&device->abs.calibration[2],
|
||||
&device->abs.calibration[3],
|
||||
&device->abs.calibration[4],
|
||||
&device->abs.calibration[5]) == 6) {
|
||||
device->abs.apply_calibration = 1;
|
||||
&calibration[0],
|
||||
&calibration[1],
|
||||
&calibration[2],
|
||||
&calibration[3],
|
||||
&calibration[4],
|
||||
&calibration[5]) == 6) {
|
||||
evdev_device_set_default_calibration(device, calibration);
|
||||
log_info(&input->base,
|
||||
"Applying calibration: %f %f %f %f %f %f\n",
|
||||
device->abs.calibration[0],
|
||||
device->abs.calibration[1],
|
||||
device->abs.calibration[2],
|
||||
device->abs.calibration[3],
|
||||
device->abs.calibration[4],
|
||||
device->abs.calibration[5]);
|
||||
calibration[0],
|
||||
calibration[1],
|
||||
calibration[2],
|
||||
calibration[3],
|
||||
calibration[4],
|
||||
calibration[5]);
|
||||
}
|
||||
|
||||
output_name = udev_device_get_property_value(udev_device, "WL_OUTPUT");
|
||||
|
|
@ -216,7 +219,6 @@ udev_input_remove_devices(struct udev_input *input)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
udev_input_disable(struct libinput *libinput)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@ liblitest_la_SOURCES = \
|
|||
../src/libinput-util.c \
|
||||
litest.h \
|
||||
litest-int.h \
|
||||
litest-alps-semi-mt.c \
|
||||
litest-bcm5974.c \
|
||||
litest-generic-singletouch.c \
|
||||
litest-keyboard.c \
|
||||
litest-mouse.c \
|
||||
litest-synaptics.c \
|
||||
|
|
@ -37,8 +39,10 @@ run_tests = \
|
|||
test-log \
|
||||
test-tablet \
|
||||
test-touchpad \
|
||||
test-trackpoint \
|
||||
test-misc \
|
||||
test-keyboard
|
||||
test-keyboard \
|
||||
test-device
|
||||
build_tests = \
|
||||
test-build-cxx \
|
||||
test-build-linker \
|
||||
|
|
@ -52,23 +56,23 @@ TESTS = $(run_tests)
|
|||
|
||||
test_udev_SOURCES = udev.c
|
||||
test_udev_LDADD = $(TEST_LIBS)
|
||||
test_udev_LDFLAGS = -static
|
||||
test_udev_LDFLAGS = -no-install
|
||||
|
||||
test_path_SOURCES = path.c
|
||||
test_path_LDADD = $(TEST_LIBS)
|
||||
test_path_LDFLAGS = -static
|
||||
test_path_LDFLAGS = -no-install
|
||||
|
||||
test_pointer_SOURCES = pointer.c
|
||||
test_pointer_LDADD = $(TEST_LIBS)
|
||||
test_pointer_LDFLAGS = -static
|
||||
test_pointer_LDFLAGS = -no-install
|
||||
|
||||
test_touch_SOURCES = touch.c
|
||||
test_touch_LDADD = $(TEST_LIBS)
|
||||
test_touch_LDFLAGS = -static
|
||||
test_touch_LDFLAGS = -no-install
|
||||
|
||||
test_log_SOURCES = log.c
|
||||
test_log_LDADD = $(TEST_LIBS)
|
||||
test_log_LDFLAGS = -static
|
||||
test_log_LDFLAGS = -no-install
|
||||
|
||||
test_tablet_SOURCES = tablet.c
|
||||
test_tablet_CFLAGS = $(AM_CPPFLAGS)
|
||||
|
|
@ -77,15 +81,23 @@ test_tablet_LDFLAGS = -static
|
|||
|
||||
test_touchpad_SOURCES = touchpad.c
|
||||
test_touchpad_LDADD = $(TEST_LIBS)
|
||||
test_touchpad_LDFLAGS = -static
|
||||
test_touchpad_LDFLAGS = -no-install
|
||||
|
||||
test_trackpoint_SOURCES = trackpoint.c
|
||||
test_trackpoint_LDADD = $(TEST_LIBS)
|
||||
test_trackpoint_LDFLAGS = -no-install
|
||||
|
||||
test_misc_SOURCES = misc.c
|
||||
test_misc_LDADD = $(TEST_LIBS)
|
||||
test_misc_LDFLAGS = -static
|
||||
test_misc_LDFLAGS = -no-install
|
||||
|
||||
test_keyboard_SOURCES = keyboard.c
|
||||
test_keyboard_LDADD = $(TEST_LIBS)
|
||||
test_keyboard_LDFLAGS = -static
|
||||
test_keyboard_LDFLAGS = -no-install
|
||||
|
||||
test_device_SOURCES = device.c
|
||||
test_device_LDADD = $(TEST_LIBS)
|
||||
test_device_LDFLAGS = -no-install
|
||||
|
||||
# build-test only
|
||||
test_build_pedantic_c99_SOURCES = build-pedantic.c
|
||||
|
|
|
|||
589
test/device.c
Normal file
589
test/device.c
Normal file
|
|
@ -0,0 +1,589 @@
|
|||
/*
|
||||
* Copyright © 2014 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the copyright holders not be used in
|
||||
* advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The copyright holders make
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <check.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <libinput.h>
|
||||
#include <libudev.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "litest.h"
|
||||
#include "libinput-util.h"
|
||||
|
||||
START_TEST(device_sendevents_config)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput_device *device;
|
||||
uint32_t modes;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
modes = libinput_device_config_send_events_get_modes(device);
|
||||
ck_assert_int_eq(modes,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED|
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_sendevents_config_touchpad)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput_device *device;
|
||||
uint32_t modes;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
modes = libinput_device_config_send_events_get_modes(device);
|
||||
ck_assert_int_eq(modes,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED|
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE|
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_sendevents_config_default)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput_device *device;
|
||||
uint32_t mode;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
mode = libinput_device_config_send_events_get_mode(device);
|
||||
ck_assert_int_eq(mode,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
|
||||
|
||||
mode = libinput_device_config_send_events_get_default_mode(device);
|
||||
ck_assert_int_eq(mode,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_disable)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *device;
|
||||
enum libinput_config_status status;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
/* no event from disabling */
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
/* no event from disabled device */
|
||||
litest_event(dev, EV_REL, REL_X, 10);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
/* no event from resuming */
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_disable_touchpad)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *device;
|
||||
enum libinput_config_status status;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
/* no event from disabling */
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_touch_down(dev, 0, 50, 50);
|
||||
litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10);
|
||||
litest_touch_up(dev, 0);
|
||||
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
/* no event from resuming */
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_disable_events_pending)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *device;
|
||||
enum libinput_config_status status;
|
||||
struct libinput_event *event;
|
||||
int i;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
/* put a couple of events in the queue, enough to
|
||||
feed the ptraccel trackers */
|
||||
for (i = 0; i < 10; i++) {
|
||||
litest_event(dev, EV_REL, REL_X, 10);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
}
|
||||
libinput_dispatch(li);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
/* expect above events */
|
||||
litest_wait_for_event(li);
|
||||
while ((event = libinput_get_event(li)) != NULL) {
|
||||
ck_assert_int_eq(libinput_event_get_type(event),
|
||||
LIBINPUT_EVENT_POINTER_MOTION);
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_double_disable)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *device;
|
||||
enum libinput_config_status status;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_double_enable)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *device;
|
||||
enum libinput_config_status status;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_reenable_syspath_changed)
|
||||
{
|
||||
struct libinput *li;
|
||||
struct litest_device *litest_device;
|
||||
struct libinput_device *device1, *device2;
|
||||
enum libinput_config_status status;
|
||||
struct libinput_event *event;
|
||||
|
||||
li = litest_create_context();
|
||||
litest_device = litest_add_device(li, LITEST_MOUSE);
|
||||
device1 = litest_device->libinput_device;
|
||||
|
||||
libinput_device_ref(device1);
|
||||
status = libinput_device_config_send_events_set_mode(device1,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_delete_device(litest_device);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_device = litest_add_device(li, LITEST_MOUSE);
|
||||
device2 = litest_device->libinput_device;
|
||||
ck_assert_str_eq(libinput_device_get_sysname(device1),
|
||||
libinput_device_get_sysname(device2));
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device1,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
/* can't really check for much here, other than that if we pump
|
||||
events through libinput, none of them should be from the first
|
||||
device */
|
||||
litest_event(litest_device, EV_REL, REL_X, 1);
|
||||
litest_event(litest_device, EV_REL, REL_Y, 1);
|
||||
litest_event(litest_device, EV_SYN, SYN_REPORT, 0);
|
||||
|
||||
libinput_dispatch(li);
|
||||
while ((event = libinput_get_event(li))) {
|
||||
ck_assert(libinput_event_get_device(event) != device1);
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
litest_delete_device(litest_device);
|
||||
libinput_device_unref(device1);
|
||||
libinput_unref(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_reenable_device_removed)
|
||||
{
|
||||
struct libinput *li;
|
||||
struct litest_device *litest_device;
|
||||
struct libinput_device *device;
|
||||
enum libinput_config_status status;
|
||||
|
||||
li = litest_create_context();
|
||||
litest_device = litest_add_device(li, LITEST_MOUSE);
|
||||
device = litest_device->libinput_device;
|
||||
|
||||
libinput_device_ref(device);
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_delete_device(litest_device);
|
||||
litest_drain_events(li);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
/* can't really check for much here, this really just exercises the
|
||||
code path. */
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
libinput_device_unref(device);
|
||||
libinput_unref(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_disable_release_buttons)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *device;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_pointer *ptrevent;
|
||||
enum libinput_config_status status;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
litest_button_click(dev, BTN_LEFT, true);
|
||||
litest_drain_events(li);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
litest_wait_for_event(li);
|
||||
event = libinput_get_event(li);
|
||||
|
||||
ck_assert_int_eq(libinput_event_get_type(event),
|
||||
LIBINPUT_EVENT_POINTER_BUTTON);
|
||||
ptrevent = libinput_event_get_pointer_event(event);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button(ptrevent),
|
||||
BTN_LEFT);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrevent),
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_disable_release_keys)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *device;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_keyboard *kbdevent;
|
||||
enum libinput_config_status status;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
litest_button_click(dev, KEY_A, true);
|
||||
litest_drain_events(li);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
litest_wait_for_event(li);
|
||||
event = libinput_get_event(li);
|
||||
|
||||
ck_assert_int_eq(libinput_event_get_type(event),
|
||||
LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
kbdevent = libinput_event_get_keyboard_event(event);
|
||||
ck_assert_int_eq(libinput_event_keyboard_get_key(kbdevent),
|
||||
KEY_A);
|
||||
ck_assert_int_eq(libinput_event_keyboard_get_key_state(kbdevent),
|
||||
LIBINPUT_KEY_STATE_RELEASED);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_disable_release_tap)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *device;
|
||||
enum libinput_config_status status;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
libinput_device_config_tap_set_enabled(device,
|
||||
LIBINPUT_CONFIG_TAP_ENABLED);
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 50, 50);
|
||||
litest_touch_up(dev, 0);
|
||||
|
||||
libinput_dispatch(li);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
/* tap happened before suspending, so we still expect the event */
|
||||
|
||||
msleep(300); /* tap-n-drag timeout */
|
||||
|
||||
litest_assert_button_event(li,
|
||||
BTN_LEFT,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
litest_assert_button_event(li,
|
||||
BTN_LEFT,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
/* resume, make sure we don't get anything */
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
libinput_dispatch(li);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_disable_release_tap_n_drag)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *device;
|
||||
enum libinput_config_status status;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
libinput_device_config_tap_set_enabled(device,
|
||||
LIBINPUT_CONFIG_TAP_ENABLED);
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 50, 50);
|
||||
litest_touch_up(dev, 0);
|
||||
litest_touch_down(dev, 0, 50, 50);
|
||||
libinput_dispatch(li);
|
||||
msleep(400); /* tap-n-drag timeout */
|
||||
libinput_dispatch(li);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
libinput_dispatch(li);
|
||||
litest_touch_up(dev, 0);
|
||||
|
||||
litest_assert_button_event(li,
|
||||
BTN_LEFT,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
litest_assert_button_event(li,
|
||||
BTN_LEFT,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(device_disable_release_softbutton)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *device;
|
||||
enum libinput_config_status status;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 90, 90);
|
||||
litest_button_click(dev, BTN_LEFT, true);
|
||||
|
||||
/* make sure softbutton works */
|
||||
litest_assert_button_event(li,
|
||||
BTN_RIGHT,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
/* disable */
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
litest_assert_button_event(li,
|
||||
BTN_RIGHT,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_button_click(dev, BTN_LEFT, false);
|
||||
litest_touch_up(dev, 0);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
/* resume, make sure we don't get anything */
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
libinput_dispatch(li);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_disable_topsoftbutton)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct litest_device *trackpoint;
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *device;
|
||||
enum libinput_config_status status;
|
||||
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_pointer *ptrevent;
|
||||
|
||||
device = dev->libinput_device;
|
||||
|
||||
trackpoint = litest_add_device(li, LITEST_TRACKPOINT);
|
||||
|
||||
status = libinput_device_config_send_events_set_mode(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 90, 10);
|
||||
litest_button_click(dev, BTN_LEFT, true);
|
||||
litest_button_click(dev, BTN_LEFT, false);
|
||||
litest_touch_up(dev, 0);
|
||||
|
||||
litest_wait_for_event(li);
|
||||
event = libinput_get_event(li);
|
||||
ck_assert_int_eq(libinput_event_get_type(event),
|
||||
LIBINPUT_EVENT_POINTER_BUTTON);
|
||||
ck_assert_int_eq(libinput_event_get_device(event),
|
||||
trackpoint->libinput_device);
|
||||
ptrevent = libinput_event_get_pointer_event(event);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button(ptrevent),
|
||||
BTN_RIGHT);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrevent),
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
libinput_event_destroy(event);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
ck_assert_int_eq(libinput_event_get_type(event),
|
||||
LIBINPUT_EVENT_POINTER_BUTTON);
|
||||
ck_assert_int_eq(libinput_event_get_device(event),
|
||||
trackpoint->libinput_device);
|
||||
ptrevent = libinput_event_get_pointer_event(event);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button(ptrevent),
|
||||
BTN_RIGHT);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrevent),
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
libinput_event_destroy(event);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_delete_device(trackpoint);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
litest_add("device:sendevents", device_sendevents_config, LITEST_ANY, LITEST_TOUCHPAD|LITEST_TABLET);
|
||||
litest_add("device:sendevents", device_sendevents_config_touchpad, LITEST_TOUCHPAD, LITEST_TABLET);
|
||||
litest_add("device:sendevents", device_sendevents_config_default, LITEST_ANY, LITEST_TABLET);
|
||||
litest_add("device:sendevents", device_disable, LITEST_POINTER, LITEST_TABLET);
|
||||
litest_add("device:sendevents", device_disable_touchpad, LITEST_TOUCHPAD, LITEST_TABLET);
|
||||
litest_add("device:sendevents", device_disable_events_pending, LITEST_POINTER, LITEST_TOUCHPAD|LITEST_TABLET);
|
||||
litest_add("device:sendevents", device_double_disable, LITEST_ANY, LITEST_TABLET);
|
||||
litest_add("device:sendevents", device_double_enable, LITEST_ANY, LITEST_TABLET);
|
||||
litest_add_no_device("device:sendevents", device_reenable_syspath_changed);
|
||||
litest_add_no_device("device:sendevents", device_reenable_device_removed);
|
||||
litest_add_for_device("device:sendevents", device_disable_release_buttons, LITEST_MOUSE);
|
||||
litest_add_for_device("device:sendevents", device_disable_release_keys, LITEST_KEYBOARD);
|
||||
litest_add("device:sendevents", device_disable_release_tap, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("device:sendevents", device_disable_release_tap_n_drag, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("device:sendevents", device_disable_release_softbutton, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
|
||||
|
||||
litest_add("device:sendevents", device_disable_topsoftbutton, LITEST_TOPBUTTONPAD, LITEST_ANY);
|
||||
|
||||
return litest_run(argc, argv);
|
||||
}
|
||||
180
test/keyboard.c
180
test/keyboard.c
|
|
@ -25,6 +25,7 @@
|
|||
#include <check.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libinput-util.h"
|
||||
#include "litest.h"
|
||||
|
||||
START_TEST(keyboard_seat_key_count)
|
||||
|
|
@ -112,10 +113,189 @@ START_TEST(keyboard_seat_key_count)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(keyboard_ignore_no_pressed_release)
|
||||
{
|
||||
struct litest_device *dev;
|
||||
struct libinput *unused_libinput;
|
||||
struct libinput *libinput;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_keyboard *kevent;
|
||||
int events[] = {
|
||||
EV_KEY, KEY_A,
|
||||
-1, -1,
|
||||
};
|
||||
enum libinput_key_state *state;
|
||||
enum libinput_key_state expected_states[] = {
|
||||
LIBINPUT_KEY_STATE_PRESSED,
|
||||
LIBINPUT_KEY_STATE_RELEASED,
|
||||
};
|
||||
|
||||
/* We can't send pressed -> released -> pressed events using uinput
|
||||
* as such non-symmetric events are dropped. Work-around this by first
|
||||
* adding the test device to the tested context after having sent an
|
||||
* initial pressed event. */
|
||||
unused_libinput = litest_create_context();
|
||||
dev = litest_add_device_with_overrides(unused_libinput,
|
||||
LITEST_KEYBOARD,
|
||||
"Generic keyboard",
|
||||
NULL, NULL, events);
|
||||
|
||||
litest_keyboard_key(dev, KEY_A, true);
|
||||
litest_drain_events(unused_libinput);
|
||||
|
||||
libinput = litest_create_context();
|
||||
libinput_path_add_device(libinput,
|
||||
libevdev_uinput_get_devnode(dev->uinput));
|
||||
litest_drain_events(libinput);
|
||||
|
||||
litest_keyboard_key(dev, KEY_A, false);
|
||||
litest_keyboard_key(dev, KEY_A, true);
|
||||
litest_keyboard_key(dev, KEY_A, false);
|
||||
|
||||
libinput_dispatch(libinput);
|
||||
|
||||
ARRAY_FOR_EACH(expected_states, state) {
|
||||
event = libinput_get_event(libinput);
|
||||
ck_assert_notnull(event);
|
||||
ck_assert_int_eq(libinput_event_get_type(event),
|
||||
LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
kevent = libinput_event_get_keyboard_event(event);
|
||||
ck_assert_int_eq(libinput_event_keyboard_get_key(kevent),
|
||||
KEY_A);
|
||||
ck_assert_int_eq(libinput_event_keyboard_get_key_state(kevent),
|
||||
*state);
|
||||
libinput_event_destroy(event);
|
||||
libinput_dispatch(libinput);
|
||||
}
|
||||
|
||||
litest_assert_empty_queue(libinput);
|
||||
litest_delete_device(dev);
|
||||
libinput_unref(libinput);
|
||||
libinput_unref(unused_libinput);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static void
|
||||
test_key_event(struct litest_device *dev, unsigned int key, int state)
|
||||
{
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_keyboard *kevent;
|
||||
|
||||
litest_event(dev, EV_KEY, key, state);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
|
||||
libinput_dispatch(li);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
ck_assert(event != NULL);
|
||||
ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
kevent = libinput_event_get_keyboard_event(event);
|
||||
ck_assert(kevent != NULL);
|
||||
ck_assert_int_eq(libinput_event_keyboard_get_key(kevent), key);
|
||||
ck_assert_int_eq(libinput_event_keyboard_get_key_state(kevent),
|
||||
state ? LIBINPUT_KEY_STATE_PRESSED :
|
||||
LIBINPUT_KEY_STATE_RELEASED);
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
START_TEST(keyboard_key_auto_release)
|
||||
{
|
||||
struct libinput *libinput;
|
||||
struct litest_device *dev;
|
||||
struct libinput_event *event;
|
||||
enum libinput_event_type type;
|
||||
struct libinput_event_keyboard *kevent;
|
||||
struct {
|
||||
int code;
|
||||
int released;
|
||||
} keys[] = {
|
||||
{ .code = KEY_A, },
|
||||
{ .code = KEY_S, },
|
||||
{ .code = KEY_D, },
|
||||
{ .code = KEY_G, },
|
||||
{ .code = KEY_Z, },
|
||||
{ .code = KEY_DELETE, },
|
||||
{ .code = KEY_F24, },
|
||||
};
|
||||
int events[2 * (ARRAY_LENGTH(keys) + 1)];
|
||||
unsigned i;
|
||||
int key;
|
||||
int valid_code;
|
||||
|
||||
/* Enable all tested keys on the device */
|
||||
i = 0;
|
||||
while (i < 2 * ARRAY_LENGTH(keys)) {
|
||||
key = keys[i / 2].code;
|
||||
events[i++] = EV_KEY;
|
||||
events[i++] = key;
|
||||
}
|
||||
events[i++] = -1;
|
||||
events[i++] = -1;
|
||||
|
||||
libinput = litest_create_context();
|
||||
dev = litest_add_device_with_overrides(libinput,
|
||||
LITEST_KEYBOARD,
|
||||
"Generic keyboard",
|
||||
NULL, NULL, events);
|
||||
|
||||
litest_drain_events(libinput);
|
||||
|
||||
/* Send pressed events, without releasing */
|
||||
for (i = 0; i < ARRAY_LENGTH(keys); ++i) {
|
||||
test_key_event(dev, keys[i].code, 1);
|
||||
}
|
||||
|
||||
litest_drain_events(libinput);
|
||||
|
||||
/* "Disconnect" device */
|
||||
litest_delete_device(dev);
|
||||
|
||||
/* Mark all released keys until device is removed */
|
||||
while (1) {
|
||||
event = libinput_get_event(libinput);
|
||||
ck_assert_notnull(event);
|
||||
type = libinput_event_get_type(event);
|
||||
|
||||
if (type == LIBINPUT_EVENT_DEVICE_REMOVED) {
|
||||
libinput_event_destroy(event);
|
||||
break;
|
||||
}
|
||||
|
||||
ck_assert_int_eq(type, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
kevent = libinput_event_get_keyboard_event(event);
|
||||
ck_assert_int_eq(libinput_event_keyboard_get_key_state(kevent),
|
||||
LIBINPUT_KEY_STATE_RELEASED);
|
||||
key = libinput_event_keyboard_get_key(kevent);
|
||||
|
||||
valid_code = 0;
|
||||
for (i = 0; i < ARRAY_LENGTH(keys); ++i) {
|
||||
if (keys[i].code == key) {
|
||||
ck_assert_int_eq(keys[i].released, 0);
|
||||
keys[i].released = 1;
|
||||
valid_code = 1;
|
||||
}
|
||||
}
|
||||
ck_assert_int_eq(valid_code, 1);
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
/* Check that all pressed keys has been released. */
|
||||
for (i = 0; i < ARRAY_LENGTH(keys); ++i) {
|
||||
ck_assert_int_eq(keys[i].released, 1);
|
||||
}
|
||||
|
||||
libinput_unref(libinput);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
litest_add_no_device("keyboard:seat key count", keyboard_seat_key_count);
|
||||
litest_add_no_device("keyboard:key counting", keyboard_ignore_no_pressed_release);
|
||||
litest_add_no_device("keyboard:key counting", keyboard_key_auto_release);
|
||||
|
||||
return litest_run(argc, argv);
|
||||
}
|
||||
|
|
|
|||
260
test/litest-alps-semi-mt.c
Normal file
260
test/litest-alps-semi-mt.c
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* Copyright © 2014 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "libinput-util.h"
|
||||
|
||||
#include "litest.h"
|
||||
#include "litest-int.h"
|
||||
|
||||
static int tracking_id;
|
||||
|
||||
/* this is a semi-mt device, so we keep track of the touches that the tests
|
||||
* send and modify them so that the first touch is always slot 0 and sends
|
||||
* the top-left of the bounding box, the second is always slot 1 and sends
|
||||
* the bottom-right of the bounding box.
|
||||
* Lifting any of two fingers terminates slot 1
|
||||
*/
|
||||
struct alps {
|
||||
/* The actual touches requested by the test for the two slots
|
||||
* in the 0..100 range used by litest */
|
||||
struct {
|
||||
double x, y;
|
||||
} touches[2];
|
||||
};
|
||||
|
||||
static void alps_create(struct litest_device *d);
|
||||
|
||||
static void
|
||||
litest_alps_setup(void)
|
||||
{
|
||||
struct litest_device *d = litest_create_device(LITEST_ALPS_SEMI_MT);
|
||||
litest_set_current_device(d);
|
||||
}
|
||||
|
||||
static void
|
||||
send_abs_xy(struct litest_device *d, double x, double y)
|
||||
{
|
||||
struct input_event e;
|
||||
int val;
|
||||
|
||||
e.type = EV_ABS;
|
||||
e.code = ABS_X;
|
||||
e.value = LITEST_AUTO_ASSIGN;
|
||||
val = litest_auto_assign_value(d, &e, 0, x, y);
|
||||
litest_event(d, EV_ABS, ABS_X, val);
|
||||
|
||||
e.code = ABS_Y;
|
||||
val = litest_auto_assign_value(d, &e, 0, x, y);
|
||||
litest_event(d, EV_ABS, ABS_Y, val);
|
||||
}
|
||||
|
||||
static void
|
||||
send_abs_mt_xy(struct litest_device *d, double x, double y)
|
||||
{
|
||||
struct input_event e;
|
||||
int val;
|
||||
|
||||
e.type = EV_ABS;
|
||||
e.code = ABS_MT_POSITION_X;
|
||||
e.value = LITEST_AUTO_ASSIGN;
|
||||
val = litest_auto_assign_value(d, &e, 0, x, y);
|
||||
litest_event(d, EV_ABS, ABS_MT_POSITION_X, val);
|
||||
|
||||
e.code = ABS_MT_POSITION_Y;
|
||||
e.value = LITEST_AUTO_ASSIGN;
|
||||
val = litest_auto_assign_value(d, &e, 0, x, y);
|
||||
litest_event(d, EV_ABS, ABS_MT_POSITION_Y, val);
|
||||
}
|
||||
|
||||
static void
|
||||
alps_touch_down(struct litest_device *d, unsigned int slot, double x, double y)
|
||||
{
|
||||
struct alps *alps = d->private;
|
||||
double t, l, r = 0, b = 0; /* top, left, right, bottom */
|
||||
|
||||
if (d->ntouches_down > 2 || slot > 1)
|
||||
return;
|
||||
|
||||
if (d->ntouches_down == 1) {
|
||||
l = x;
|
||||
t = y;
|
||||
} else {
|
||||
int other = (slot + 1) % 2;
|
||||
l = min(x, alps->touches[other].x);
|
||||
t = min(y, alps->touches[other].y);
|
||||
r = max(x, alps->touches[other].x);
|
||||
b = max(y, alps->touches[other].y);
|
||||
}
|
||||
|
||||
send_abs_xy(d, l, t);
|
||||
|
||||
litest_event(d, EV_ABS, ABS_MT_SLOT, 0);
|
||||
|
||||
if (d->ntouches_down == 1)
|
||||
litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, ++tracking_id);
|
||||
|
||||
send_abs_mt_xy(d, l, t);
|
||||
|
||||
if (d->ntouches_down == 2) {
|
||||
litest_event(d, EV_ABS, ABS_MT_SLOT, 1);
|
||||
litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, ++tracking_id);
|
||||
|
||||
send_abs_mt_xy(d, r, b);
|
||||
}
|
||||
|
||||
litest_event(d, EV_SYN, SYN_REPORT, 0);
|
||||
|
||||
alps->touches[slot].x = x;
|
||||
alps->touches[slot].y = y;
|
||||
}
|
||||
|
||||
static void
|
||||
alps_touch_move(struct litest_device *d, unsigned int slot, double x, double y)
|
||||
{
|
||||
struct alps *alps = d->private;
|
||||
double t, l, r = 0, b = 0; /* top, left, right, bottom */
|
||||
|
||||
if (d->ntouches_down > 2 || slot > 1)
|
||||
return;
|
||||
|
||||
if (d->ntouches_down == 1) {
|
||||
l = x;
|
||||
t = y;
|
||||
} else {
|
||||
int other = (slot + 1) % 2;
|
||||
l = min(x, alps->touches[other].x);
|
||||
t = min(y, alps->touches[other].y);
|
||||
r = max(x, alps->touches[other].x);
|
||||
b = max(y, alps->touches[other].y);
|
||||
}
|
||||
|
||||
send_abs_xy(d, l, t);
|
||||
|
||||
litest_event(d, EV_ABS, ABS_MT_SLOT, 0);
|
||||
send_abs_mt_xy(d, l, t);
|
||||
|
||||
if (d->ntouches_down == 2) {
|
||||
litest_event(d, EV_ABS, ABS_MT_SLOT, 1);
|
||||
send_abs_mt_xy(d, r, b);
|
||||
}
|
||||
|
||||
litest_event(d, EV_SYN, SYN_REPORT, 0);
|
||||
|
||||
alps->touches[slot].x = x;
|
||||
alps->touches[slot].y = y;
|
||||
}
|
||||
|
||||
static void
|
||||
alps_touch_up(struct litest_device *d, unsigned int slot)
|
||||
{
|
||||
struct alps *alps = d->private;
|
||||
|
||||
/* note: ntouches_down is decreased before we get here */
|
||||
if (d->ntouches_down >= 2 || slot > 1)
|
||||
return;
|
||||
|
||||
litest_event(d, EV_ABS, ABS_MT_SLOT, d->ntouches_down);
|
||||
litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, -1);
|
||||
|
||||
/* if we have one finger left, send x/y coords for that finger left.
|
||||
this is likely to happen with a real touchpad */
|
||||
if (d->ntouches_down == 1) {
|
||||
int other = (slot + 1) % 2;
|
||||
send_abs_xy(d, alps->touches[other].x, alps->touches[other].y);
|
||||
litest_event(d, EV_ABS, ABS_MT_SLOT, 0);
|
||||
send_abs_mt_xy(d, alps->touches[other].x, alps->touches[other].y);
|
||||
}
|
||||
|
||||
litest_event(d, EV_SYN, SYN_REPORT, 0);
|
||||
}
|
||||
|
||||
static struct litest_device_interface interface = {
|
||||
.touch_down = alps_touch_down,
|
||||
.touch_move = alps_touch_move,
|
||||
.touch_up = alps_touch_up,
|
||||
};
|
||||
|
||||
static struct input_id input_id = {
|
||||
.bustype = 0x11,
|
||||
.vendor = 0x2,
|
||||
.product = 0x8,
|
||||
};
|
||||
|
||||
static int events[] = {
|
||||
EV_KEY, BTN_LEFT,
|
||||
EV_KEY, BTN_RIGHT,
|
||||
EV_KEY, BTN_MIDDLE,
|
||||
EV_KEY, BTN_TOOL_FINGER,
|
||||
EV_KEY, BTN_TOUCH,
|
||||
EV_KEY, BTN_TOOL_DOUBLETAP,
|
||||
EV_KEY, BTN_TOOL_TRIPLETAP,
|
||||
EV_KEY, BTN_TOOL_QUADTAP,
|
||||
INPUT_PROP_MAX, INPUT_PROP_POINTER,
|
||||
INPUT_PROP_MAX, INPUT_PROP_SEMI_MT,
|
||||
-1, -1,
|
||||
};
|
||||
|
||||
static struct input_absinfo absinfo[] = {
|
||||
{ ABS_X, 0, 2000, 0, 0, 0 },
|
||||
{ ABS_Y, 0, 1400, 0, 0, 0 },
|
||||
{ ABS_PRESSURE, 0, 127, 0, 0, 0 },
|
||||
{ ABS_MT_SLOT, 0, 1, 0, 0, 0 },
|
||||
{ ABS_MT_POSITION_X, 0, 2000, 0, 0, 0 },
|
||||
{ ABS_MT_POSITION_Y, 0, 1400, 0, 0, 0 },
|
||||
{ ABS_MT_TRACKING_ID, 0, 65535, 0, 0, 0 },
|
||||
{ .value = -1 }
|
||||
};
|
||||
|
||||
struct litest_test_device litest_alps_device = {
|
||||
.type = LITEST_ALPS_SEMI_MT,
|
||||
.features = LITEST_TOUCHPAD | LITEST_BUTTON | LITEST_SEMI_MT,
|
||||
.shortname = "alps semi-mt",
|
||||
.setup = litest_alps_setup,
|
||||
.interface = &interface,
|
||||
.create = alps_create,
|
||||
|
||||
.name = "AlpsPS/2 ALPS GlidePoint",
|
||||
.id = &input_id,
|
||||
.events = events,
|
||||
.absinfo = absinfo,
|
||||
};
|
||||
|
||||
static void
|
||||
alps_create(struct litest_device *d)
|
||||
{
|
||||
struct alps *alps = zalloc(sizeof(*alps));
|
||||
assert(alps);
|
||||
|
||||
d->private = alps;
|
||||
|
||||
d->uinput = litest_create_uinput_device_from_description(litest_alps_device.name,
|
||||
litest_alps_device.id,
|
||||
absinfo,
|
||||
events);
|
||||
d->interface = &interface;
|
||||
}
|
||||
|
|
@ -34,8 +34,6 @@ static void litest_bcm5974_setup(void)
|
|||
}
|
||||
|
||||
struct input_event down[] = {
|
||||
{ .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 },
|
||||
{ .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
|
||||
{ .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_PRESSURE, .value = 30 },
|
||||
|
|
@ -53,8 +51,6 @@ static struct input_event move[] = {
|
|||
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_MT_POSITION_X, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 },
|
||||
{ .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
|
||||
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
|
||||
{ .type = -1, .code = -1 },
|
||||
};
|
||||
|
|
@ -65,13 +61,18 @@ static struct litest_device_interface interface = {
|
|||
};
|
||||
|
||||
static struct input_absinfo absinfo[] = {
|
||||
{ ABS_X, 1472, 5472, 0, 0, 75 },
|
||||
{ ABS_Y, 1408, 4448, 0, 0, 129 },
|
||||
{ ABS_PRESSURE, 0, 255, 0, 0, 0 },
|
||||
{ ABS_TOOL_WIDTH, 0, 15, 0, 0, 0 },
|
||||
{ ABS_MT_SLOT, 0, 1, 0, 0, 0 },
|
||||
{ ABS_MT_POSITION_X, 1472, 5472, 0, 0, 75 },
|
||||
{ ABS_MT_POSITION_Y, 1408, 4448, 0, 0, 129 },
|
||||
{ ABS_X, -4824, 4824, 0, 0, 0 },
|
||||
{ ABS_Y, -172, 4290, 0, 0, 0 },
|
||||
{ ABS_PRESSURE, 0, 256, 5, 0, 0 },
|
||||
{ ABS_TOOL_WIDTH, 0, 16, 0, 0, 0 },
|
||||
{ ABS_MT_SLOT, 0, 15, 0, 0, 0 },
|
||||
{ ABS_MT_POSITION_X, -4824, 4824, 17, 0, 0 },
|
||||
{ ABS_MT_POSITION_Y, -172, 4290, 17, 0, 0 },
|
||||
{ ABS_MT_ORIENTATION, -16384, 16384, 3276, 0, 0 },
|
||||
{ ABS_MT_TOUCH_MAJOR, 0, 2048, 81, 0, 0 },
|
||||
{ ABS_MT_TOUCH_MINOR, 0, 2048, 81, 0, 0 },
|
||||
{ ABS_MT_WIDTH_MAJOR, 0, 2048, 81, 0, 0 },
|
||||
{ ABS_MT_WIDTH_MINOR, 0, 2048, 81, 0, 0 },
|
||||
{ ABS_MT_TRACKING_ID, 0, 65535, 0, 0, 0 },
|
||||
{ ABS_MT_PRESSURE, 0, 255, 0, 0, 0 },
|
||||
{ .value = -1 },
|
||||
|
|
|
|||
88
test/litest-generic-singletouch.c
Normal file
88
test/litest-generic-singletouch.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright © 2014 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "litest.h"
|
||||
#include "litest-int.h"
|
||||
|
||||
static void
|
||||
litest_generic_singletouch_touch_setup(void)
|
||||
{
|
||||
struct litest_device *d = litest_create_device(LITEST_GENERIC_SINGLETOUCH);
|
||||
litest_set_current_device(d);
|
||||
}
|
||||
|
||||
static struct input_event down[] = {
|
||||
{ .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
|
||||
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
|
||||
{ .type = -1, .code = -1 },
|
||||
};
|
||||
|
||||
static struct input_event move[] = {
|
||||
{ .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
|
||||
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
|
||||
{ .type = -1, .code = -1 },
|
||||
};
|
||||
|
||||
static struct litest_device_interface interface = {
|
||||
.touch_down_events = down,
|
||||
.touch_move_events = move,
|
||||
};
|
||||
|
||||
static struct input_absinfo absinfo[] = {
|
||||
{ ABS_X, 10000, 20000, 0, 0, 10 },
|
||||
{ ABS_Y, -2000, 2000, 0, 0, 9 },
|
||||
{ .value = -1 },
|
||||
};
|
||||
|
||||
static struct input_id input_id = {
|
||||
.bustype = 0x01,
|
||||
.vendor = 0x02,
|
||||
.product = 0x03,
|
||||
};
|
||||
|
||||
static int events[] = {
|
||||
EV_KEY, BTN_TOUCH,
|
||||
INPUT_PROP_MAX, INPUT_PROP_DIRECT,
|
||||
-1, -1,
|
||||
};
|
||||
|
||||
struct litest_test_device litest_generic_singletouch_device = {
|
||||
.type = LITEST_GENERIC_SINGLETOUCH,
|
||||
.features = LITEST_SINGLE_TOUCH,
|
||||
.shortname = "generic-singletouch",
|
||||
.setup = litest_generic_singletouch_touch_setup,
|
||||
.interface = &interface,
|
||||
|
||||
.name = "generic_singletouch",
|
||||
.id = &input_id,
|
||||
.events = events,
|
||||
.absinfo = absinfo,
|
||||
};
|
||||
|
|
@ -72,8 +72,8 @@ struct litest_test_device {
|
|||
};
|
||||
|
||||
struct litest_device_interface {
|
||||
void (*touch_down)(struct litest_device *d, unsigned int slot, int x, int y);
|
||||
void (*touch_move)(struct litest_device *d, unsigned int slot, int x, int y);
|
||||
void (*touch_down)(struct litest_device *d, unsigned int slot, double x, double y);
|
||||
void (*touch_move)(struct litest_device *d, unsigned int slot, double x, double y);
|
||||
void (*touch_up)(struct litest_device *d, unsigned int slot);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -195,7 +195,6 @@ static int events[] = {
|
|||
-1, -1,
|
||||
};
|
||||
|
||||
|
||||
struct litest_test_device litest_keyboard_device = {
|
||||
.type = LITEST_KEYBOARD,
|
||||
.features = LITEST_KEYS,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ litest_synaptics_touchpad_setup(void)
|
|||
}
|
||||
|
||||
static struct input_event down[] = {
|
||||
{ .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
|
||||
{ .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_PRESSURE, .value = 30 },
|
||||
|
|
@ -47,13 +46,11 @@ static struct input_event down[] = {
|
|||
static struct input_event move[] = {
|
||||
{ .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
|
||||
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
|
||||
{ .type = -1, .code = -1 },
|
||||
};
|
||||
|
||||
struct input_event up[] = {
|
||||
{ .type = EV_KEY, .code = BTN_TOUCH, .value = 0 },
|
||||
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
|
||||
{ .type = -1, .code = -1 },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,8 +35,6 @@ litest_synaptics_t440_setup(void)
|
|||
}
|
||||
|
||||
static struct input_event down[] = {
|
||||
{ .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 },
|
||||
{ .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
|
||||
{ .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_PRESSURE, .value = 30 },
|
||||
|
|
@ -54,8 +52,6 @@ static struct input_event move[] = {
|
|||
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_MT_POSITION_X, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 },
|
||||
{ .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
|
||||
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
|
||||
{ .type = -1, .code = -1 },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,8 +35,6 @@ litest_synaptics_clickpad_setup(void)
|
|||
}
|
||||
|
||||
static struct input_event down[] = {
|
||||
{ .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 },
|
||||
{ .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
|
||||
{ .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_PRESSURE, .value = 30 },
|
||||
|
|
@ -54,8 +52,6 @@ static struct input_event move[] = {
|
|||
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_MT_POSITION_X, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = LITEST_AUTO_ASSIGN },
|
||||
{ .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 },
|
||||
{ .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
|
||||
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
|
||||
{ .type = -1, .code = -1 },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -49,12 +49,14 @@ static int events[] = {
|
|||
EV_KEY, BTN_MIDDLE,
|
||||
EV_REL, REL_X,
|
||||
EV_REL, REL_Y,
|
||||
INPUT_PROP_MAX, INPUT_PROP_POINTER,
|
||||
INPUT_PROP_MAX, INPUT_PROP_POINTING_STICK,
|
||||
-1, -1,
|
||||
};
|
||||
|
||||
struct litest_test_device litest_trackpoint_device = {
|
||||
.type = LITEST_TRACKPOINT,
|
||||
.features = LITEST_POINTER | LITEST_BUTTON,
|
||||
.features = LITEST_POINTER | LITEST_BUTTON | LITEST_POINTINGSTICK,
|
||||
.shortname = "trackpoint",
|
||||
.setup = litest_trackpoint_setup,
|
||||
.interface = &interface,
|
||||
|
|
|
|||
221
test/litest.c
221
test/litest.c
|
|
@ -24,6 +24,7 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <check.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
|
@ -88,6 +89,8 @@ extern struct litest_test_device litest_wacom_bamboo_tablet_device;
|
|||
extern struct litest_test_device litest_wacom_cintiq_tablet_device;
|
||||
extern struct litest_test_device litest_wacom_intuos_tablet_device;
|
||||
extern struct litest_test_device litest_wacom_isdv4_tablet_device;
|
||||
extern struct litest_test_device litest_alps_device;
|
||||
extern struct litest_test_device litest_generic_singletouch_device;
|
||||
|
||||
struct litest_test_device* devices[] = {
|
||||
&litest_synaptics_clickpad_device,
|
||||
|
|
@ -102,10 +105,11 @@ struct litest_test_device* devices[] = {
|
|||
&litest_wacom_cintiq_tablet_device,
|
||||
&litest_wacom_intuos_tablet_device,
|
||||
&litest_wacom_isdv4_tablet_device,
|
||||
&litest_alps_device,
|
||||
&litest_generic_singletouch_device,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
static struct list all_tests;
|
||||
|
||||
static void
|
||||
|
|
@ -163,6 +167,9 @@ litest_add_tcase(struct suite *suite, void *func,
|
|||
{
|
||||
struct litest_test_device **dev = devices;
|
||||
|
||||
assert(required >= LITEST_DISABLE_DEVICE);
|
||||
assert(excluded >= LITEST_DISABLE_DEVICE);
|
||||
|
||||
if (required == LITEST_DISABLE_DEVICE &&
|
||||
excluded == LITEST_DISABLE_DEVICE) {
|
||||
litest_add_tcase_no_device(suite, func);
|
||||
|
|
@ -187,11 +194,8 @@ litest_add_no_device(const char *name, void *func)
|
|||
litest_add(name, func, LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
|
||||
}
|
||||
|
||||
void
|
||||
litest_add(const char *name,
|
||||
void *func,
|
||||
enum litest_device_feature required,
|
||||
enum litest_device_feature excluded)
|
||||
static struct suite *
|
||||
get_suite(const char *name)
|
||||
{
|
||||
struct suite *s;
|
||||
|
||||
|
|
@ -199,10 +203,8 @@ litest_add(const char *name,
|
|||
list_init(&all_tests);
|
||||
|
||||
list_for_each(s, &all_tests, node) {
|
||||
if (strcmp(s->name, name) == 0) {
|
||||
litest_add_tcase(s, func, required, excluded);
|
||||
return;
|
||||
}
|
||||
if (strcmp(s->name, name) == 0)
|
||||
return s;
|
||||
}
|
||||
|
||||
s = zalloc(sizeof(*s));
|
||||
|
|
@ -211,7 +213,39 @@ litest_add(const char *name,
|
|||
|
||||
list_init(&s->tests);
|
||||
list_insert(&all_tests, &s->node);
|
||||
litest_add_tcase(s, func, required, excluded);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
litest_add(const char *name,
|
||||
void *func,
|
||||
enum litest_device_feature required,
|
||||
enum litest_device_feature excluded)
|
||||
{
|
||||
litest_add_tcase(get_suite(name), func, required, excluded);
|
||||
}
|
||||
|
||||
void
|
||||
litest_add_for_device(const char *name,
|
||||
void *func,
|
||||
enum litest_device_type type)
|
||||
{
|
||||
struct suite *s;
|
||||
struct litest_test_device **dev = devices;
|
||||
|
||||
assert(type < LITEST_NO_DEVICE);
|
||||
|
||||
s = get_suite(name);
|
||||
while (*dev) {
|
||||
if ((*dev)->type == type) {
|
||||
litest_add_tcase_for_device(s, func, *dev);
|
||||
return;
|
||||
}
|
||||
dev++;
|
||||
}
|
||||
|
||||
ck_abort_msg("Invalid test device type");
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -243,7 +277,6 @@ is_debugger_attached(void)
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
litest_list_tests(struct list *tests)
|
||||
{
|
||||
|
|
@ -339,7 +372,7 @@ litest_run(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
srunner_run_all(sr, CK_ENV);
|
||||
failed = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
|
||||
|
|
@ -429,7 +462,6 @@ merge_events(const int *orig, const int *override)
|
|||
return events;
|
||||
}
|
||||
|
||||
|
||||
static struct litest_device *
|
||||
litest_create(enum litest_device_type which,
|
||||
const char *name_override,
|
||||
|
|
@ -539,6 +571,18 @@ litest_add_device_with_overrides(struct libinput *libinput,
|
|||
return d;
|
||||
}
|
||||
|
||||
struct litest_device *
|
||||
litest_add_device(struct libinput *libinput,
|
||||
enum litest_device_type which)
|
||||
{
|
||||
return litest_add_device_with_overrides(libinput,
|
||||
which,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
struct litest_device *
|
||||
litest_create_device_with_overrides(enum litest_device_type which,
|
||||
const char *name_override,
|
||||
|
|
@ -584,10 +628,12 @@ litest_delete_device(struct litest_device *d)
|
|||
return;
|
||||
|
||||
libinput_device_unref(d->libinput_device);
|
||||
libinput_path_remove_device(d->libinput_device);
|
||||
if (d->owns_context)
|
||||
libinput_unref(d->libinput);
|
||||
libevdev_free(d->evdev);
|
||||
libevdev_uinput_destroy(d->uinput);
|
||||
free(d->private);
|
||||
memset(d,0, sizeof(*d));
|
||||
free(d);
|
||||
}
|
||||
|
|
@ -600,10 +646,10 @@ litest_event(struct litest_device *d, unsigned int type,
|
|||
ck_assert_int_eq(ret, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
auto_assign_value(struct litest_device *d,
|
||||
const struct input_event *ev,
|
||||
int slot, double x, double y)
|
||||
int
|
||||
litest_auto_assign_value(struct litest_device *d,
|
||||
const struct input_event *ev,
|
||||
int slot, double x, double y)
|
||||
{
|
||||
static int tracking_id;
|
||||
int value = ev->value;
|
||||
|
|
@ -631,6 +677,16 @@ auto_assign_value(struct litest_device *d,
|
|||
return value;
|
||||
}
|
||||
|
||||
static void
|
||||
send_btntool(struct litest_device *d)
|
||||
{
|
||||
litest_event(d, EV_KEY, BTN_TOUCH, d->ntouches_down != 0);
|
||||
litest_event(d, EV_KEY, BTN_TOOL_FINGER, d->ntouches_down == 1);
|
||||
litest_event(d, EV_KEY, BTN_TOOL_DOUBLETAP, d->ntouches_down == 2);
|
||||
litest_event(d, EV_KEY, BTN_TOOL_TRIPLETAP, d->ntouches_down == 3);
|
||||
litest_event(d, EV_KEY, BTN_TOOL_QUADTAP, d->ntouches_down == 4);
|
||||
litest_event(d, EV_KEY, BTN_TOOL_QUINTTAP, d->ntouches_down == 5);
|
||||
}
|
||||
|
||||
void
|
||||
litest_touch_down(struct litest_device *d, unsigned int slot,
|
||||
|
|
@ -638,6 +694,10 @@ litest_touch_down(struct litest_device *d, unsigned int slot,
|
|||
{
|
||||
struct input_event *ev;
|
||||
|
||||
assert(++d->ntouches_down > 0);
|
||||
|
||||
send_btntool(d);
|
||||
|
||||
if (d->interface->touch_down) {
|
||||
d->interface->touch_down(d, slot, x, y);
|
||||
return;
|
||||
|
|
@ -645,7 +705,7 @@ litest_touch_down(struct litest_device *d, unsigned int slot,
|
|||
|
||||
ev = d->interface->touch_down_events;
|
||||
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
|
||||
int value = auto_assign_value(d, ev, slot, x, y);
|
||||
int value = litest_auto_assign_value(d, ev, slot, x, y);
|
||||
litest_event(d, ev->type, ev->code, value);
|
||||
ev++;
|
||||
}
|
||||
|
|
@ -662,6 +722,10 @@ litest_touch_up(struct litest_device *d, unsigned int slot)
|
|||
{ .type = -1, .code = -1 }
|
||||
};
|
||||
|
||||
assert(--d->ntouches_down >= 0);
|
||||
|
||||
send_btntool(d);
|
||||
|
||||
if (d->interface->touch_up) {
|
||||
d->interface->touch_up(d, slot);
|
||||
return;
|
||||
|
|
@ -671,7 +735,7 @@ litest_touch_up(struct litest_device *d, unsigned int slot)
|
|||
ev = up;
|
||||
|
||||
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
|
||||
int value = auto_assign_value(d, ev, slot, 0, 0);
|
||||
int value = litest_auto_assign_value(d, ev, slot, 0, 0);
|
||||
litest_event(d, ev->type, ev->code, value);
|
||||
ev++;
|
||||
}
|
||||
|
|
@ -690,7 +754,7 @@ litest_touch_move(struct litest_device *d, unsigned int slot,
|
|||
|
||||
ev = d->interface->touch_move_events;
|
||||
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
|
||||
int value = auto_assign_value(d, ev, slot, x, y);
|
||||
int value = litest_auto_assign_value(d, ev, slot, x, y);
|
||||
litest_event(d, ev->type, ev->code, value);
|
||||
ev++;
|
||||
}
|
||||
|
|
@ -832,6 +896,53 @@ litest_scale(const struct litest_device *d, unsigned int axis, double val)
|
|||
return (max - min) * val/100.0 + min;
|
||||
}
|
||||
|
||||
void
|
||||
litest_wait_for_event(struct libinput *li)
|
||||
{
|
||||
return litest_wait_for_event_of_type(li, -1);
|
||||
}
|
||||
|
||||
void
|
||||
litest_wait_for_event_of_type(struct libinput *li, ...)
|
||||
{
|
||||
va_list args;
|
||||
enum libinput_event_type types[32] = {LIBINPUT_EVENT_NONE};
|
||||
size_t ntypes = 0;
|
||||
enum libinput_event_type type;
|
||||
|
||||
va_start(args, li);
|
||||
type = va_arg(args, int);
|
||||
while ((int)type != -1) {
|
||||
assert(type > 0);
|
||||
assert(ntypes < ARRAY_LENGTH(types));
|
||||
types[ntypes++] = type;
|
||||
type = va_arg(args, int);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
while (1) {
|
||||
size_t i;
|
||||
struct libinput_event *event;
|
||||
|
||||
while ((type = libinput_next_event_type(li)) == LIBINPUT_EVENT_NONE) {
|
||||
msleep(10);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
/* no event mask means wait for any event */
|
||||
if (ntypes == 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ntypes; i++) {
|
||||
if (type == types[i])
|
||||
return;
|
||||
}
|
||||
|
||||
event = libinput_get_event(li);
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
litest_drain_events(struct libinput *li)
|
||||
{
|
||||
|
|
@ -952,8 +1063,6 @@ litest_create_uinput_device_from_description(const char *name,
|
|||
if (type == INPUT_PROP_MAX) {
|
||||
rc = libevdev_enable_property(dev, code);
|
||||
} else {
|
||||
if (type != EV_SYN)
|
||||
ck_assert(!libevdev_has_event_code(dev, type, code));
|
||||
rc = libevdev_enable_event_code(dev, type, code,
|
||||
type == EV_ABS ? &default_abs : NULL);
|
||||
}
|
||||
|
|
@ -963,7 +1072,11 @@ litest_create_uinput_device_from_description(const char *name,
|
|||
rc = libevdev_uinput_create_from_device(dev,
|
||||
LIBEVDEV_UINPUT_OPEN_MANAGED,
|
||||
&uinput);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
/* workaround for a bug in libevdev pre-1.3
|
||||
http://cgit.freedesktop.org/libevdev/commit/?id=debe9b030c8069cdf78307888ef3b65830b25122 */
|
||||
if (rc == -EBADF)
|
||||
rc = -EACCES;
|
||||
ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
|
||||
|
||||
libevdev_free(dev);
|
||||
|
||||
|
|
@ -1047,3 +1160,63 @@ litest_create_uinput_device(const char *name, struct input_id *id, ...)
|
|||
|
||||
return uinput;
|
||||
}
|
||||
|
||||
void
|
||||
litest_assert_button_event(struct libinput *li, unsigned int button,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_pointer *ptrev;
|
||||
|
||||
litest_wait_for_event(li);
|
||||
event = libinput_get_event(li);
|
||||
|
||||
ck_assert(event != NULL);
|
||||
ck_assert_int_eq(libinput_event_get_type(event),
|
||||
LIBINPUT_EVENT_POINTER_BUTTON);
|
||||
ptrev = libinput_event_get_pointer_event(event);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button(ptrev),
|
||||
button);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrev),
|
||||
state);
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
void litest_assert_scroll(struct libinput *li, unsigned int axis, int dir)
|
||||
{
|
||||
struct libinput_event *event, *next_event;
|
||||
struct libinput_event_pointer *ptrev;
|
||||
|
||||
event = libinput_get_event(li);
|
||||
next_event = libinput_get_event(li);
|
||||
ck_assert(next_event != NULL); /* At least 1 scroll + stop scroll */
|
||||
|
||||
while (event) {
|
||||
ck_assert_int_eq(libinput_event_get_type(event),
|
||||
LIBINPUT_EVENT_POINTER_AXIS);
|
||||
ptrev = libinput_event_get_pointer_event(event);
|
||||
ck_assert(ptrev != NULL);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev), axis);
|
||||
|
||||
if (next_event) {
|
||||
/* Normal scroll event, check dir */
|
||||
if (dir > 0) {
|
||||
ck_assert_int_ge(
|
||||
libinput_event_pointer_get_axis_value(ptrev),
|
||||
dir);
|
||||
} else {
|
||||
ck_assert_int_le(
|
||||
libinput_event_pointer_get_axis_value(ptrev),
|
||||
dir);
|
||||
}
|
||||
} else {
|
||||
/* Last scroll event, must be 0 */
|
||||
ck_assert_int_eq(
|
||||
libinput_event_pointer_get_axis_value(ptrev),
|
||||
0);
|
||||
}
|
||||
libinput_event_destroy(event);
|
||||
event = next_event;
|
||||
next_event = libinput_get_event(li);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,18 +35,20 @@
|
|||
|
||||
enum litest_device_type {
|
||||
LITEST_NO_DEVICE = -1,
|
||||
LITEST_SYNAPTICS_CLICKPAD,
|
||||
LITEST_SYNAPTICS_TOUCHPAD,
|
||||
LITEST_SYNAPTICS_TOPBUTTONPAD,
|
||||
LITEST_BCM5974,
|
||||
LITEST_KEYBOARD,
|
||||
LITEST_TRACKPOINT,
|
||||
LITEST_MOUSE,
|
||||
LITEST_WACOM_TOUCH,
|
||||
LITEST_WACOM_BAMBOO,
|
||||
LITEST_WACOM_CINTIQ,
|
||||
LITEST_WACOM_INTUOS,
|
||||
LITEST_WACOM_ISDV4,
|
||||
LITEST_SYNAPTICS_CLICKPAD = -2,
|
||||
LITEST_SYNAPTICS_TOUCHPAD = -3,
|
||||
LITEST_SYNAPTICS_TOPBUTTONPAD = -4,
|
||||
LITEST_BCM5974 = -5,
|
||||
LITEST_KEYBOARD = -6,
|
||||
LITEST_TRACKPOINT = -7,
|
||||
LITEST_MOUSE = -8,
|
||||
LITEST_WACOM_TOUCH = -9,
|
||||
LITEST_ALPS_SEMI_MT = -10,
|
||||
LITEST_GENERIC_SINGLETOUCH = -11,
|
||||
LITEST_WACOM_BAMBOO = -12,
|
||||
LITEST_WACOM_CINTIQ = -13,
|
||||
LITEST_WACOM_INTUOS = -14,
|
||||
LITEST_WACOM_ISDV4 = -15,
|
||||
};
|
||||
|
||||
enum litest_device_feature {
|
||||
|
|
@ -62,9 +64,11 @@ enum litest_device_feature {
|
|||
LITEST_SINGLE_TOUCH = 1 << 7,
|
||||
LITEST_APPLE_CLICKPAD = 1 << 8,
|
||||
LITEST_TOPBUTTONPAD = 1 << 9,
|
||||
LITEST_TABLET = 1 << 10,
|
||||
LITEST_DISTANCE = 1 << 11,
|
||||
LITEST_TOOL_SERIAL = 1 << 12,
|
||||
LITEST_SEMI_MT = 1 << 10,
|
||||
LITEST_POINTINGSTICK = 1 << 11,
|
||||
LITEST_TABLET = 1 << 12,
|
||||
LITEST_DISTANCE = 1 << 13,
|
||||
LITEST_TOOL_SERIAL = 1 << 14,
|
||||
};
|
||||
|
||||
struct litest_device {
|
||||
|
|
@ -74,6 +78,9 @@ struct litest_device {
|
|||
bool owns_context;
|
||||
struct libinput_device *libinput_device;
|
||||
struct litest_device_interface *interface;
|
||||
|
||||
int ntouches_down;
|
||||
void *private; /* device-specific data */
|
||||
};
|
||||
|
||||
struct libinput *litest_create_context(void);
|
||||
|
|
@ -85,10 +92,16 @@ struct axis_replacement {
|
|||
void litest_add(const char *name, void *func,
|
||||
enum litest_device_feature required_feature,
|
||||
enum litest_device_feature excluded_feature);
|
||||
void
|
||||
litest_add_for_device(const char *name,
|
||||
void *func,
|
||||
enum litest_device_type type);
|
||||
void litest_add_no_device(const char *name, void *func);
|
||||
|
||||
int litest_run(int argc, char **argv);
|
||||
struct litest_device * litest_create_device(enum litest_device_type which);
|
||||
struct litest_device * litest_add_device(struct libinput *libinput,
|
||||
enum litest_device_type which);
|
||||
struct libevdev_uinput *
|
||||
litest_create_uinput_device_from_description(const char *name,
|
||||
const struct input_id *id,
|
||||
|
|
@ -116,6 +129,9 @@ void litest_event(struct litest_device *t,
|
|||
unsigned int type,
|
||||
unsigned int code,
|
||||
int value);
|
||||
int litest_auto_assign_value(struct litest_device *d,
|
||||
const struct input_event *ev,
|
||||
int slot, double x, double y);
|
||||
void litest_touch_up(struct litest_device *d, unsigned int slot);
|
||||
void litest_touch_move(struct litest_device *d,
|
||||
unsigned int slot,
|
||||
|
|
@ -143,8 +159,14 @@ void litest_button_click(struct litest_device *d,
|
|||
void litest_keyboard_key(struct litest_device *d,
|
||||
unsigned int key,
|
||||
bool is_press);
|
||||
void litest_wait_for_event(struct libinput *li);
|
||||
void litest_wait_for_event_of_type(struct libinput *li, ...);
|
||||
void litest_drain_events(struct libinput *li);
|
||||
void litest_assert_empty_queue(struct libinput *li);
|
||||
void litest_assert_button_event(struct libinput *li,
|
||||
unsigned int button,
|
||||
enum libinput_button_state state);
|
||||
void litest_assert_scroll(struct libinput *li, unsigned int axis, int dir);
|
||||
|
||||
struct libevdev_uinput * litest_create_uinput_device(const char *name,
|
||||
struct input_id *id,
|
||||
|
|
|
|||
78
test/misc.c
78
test/misc.c
|
|
@ -469,6 +469,83 @@ START_TEST(config_status_string)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(matrix_helpers)
|
||||
{
|
||||
struct matrix m1, m2, m3;
|
||||
float f[6] = { 1, 2, 3, 4, 5, 6 };
|
||||
int x, y;
|
||||
int row, col;
|
||||
|
||||
matrix_init_identity(&m1);
|
||||
|
||||
for (row = 0; row < 3; row++) {
|
||||
for (col = 0; col < 3; col++) {
|
||||
ck_assert_int_eq(m1.val[row][col],
|
||||
(row == col) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
ck_assert(matrix_is_identity(&m1));
|
||||
|
||||
matrix_from_farray6(&m2, f);
|
||||
ck_assert_int_eq(m2.val[0][0], 1);
|
||||
ck_assert_int_eq(m2.val[0][1], 2);
|
||||
ck_assert_int_eq(m2.val[0][2], 3);
|
||||
ck_assert_int_eq(m2.val[1][0], 4);
|
||||
ck_assert_int_eq(m2.val[1][1], 5);
|
||||
ck_assert_int_eq(m2.val[1][2], 6);
|
||||
ck_assert_int_eq(m2.val[2][0], 0);
|
||||
ck_assert_int_eq(m2.val[2][1], 0);
|
||||
ck_assert_int_eq(m2.val[2][2], 1);
|
||||
|
||||
x = 100;
|
||||
y = 5;
|
||||
matrix_mult_vec(&m1, &x, &y);
|
||||
ck_assert_int_eq(x, 100);
|
||||
ck_assert_int_eq(y, 5);
|
||||
|
||||
matrix_mult(&m3, &m1, &m1);
|
||||
ck_assert(matrix_is_identity(&m3));
|
||||
|
||||
matrix_init_scale(&m2, 2, 4);
|
||||
ck_assert_int_eq(m2.val[0][0], 2);
|
||||
ck_assert_int_eq(m2.val[0][1], 0);
|
||||
ck_assert_int_eq(m2.val[0][2], 0);
|
||||
ck_assert_int_eq(m2.val[1][0], 0);
|
||||
ck_assert_int_eq(m2.val[1][1], 4);
|
||||
ck_assert_int_eq(m2.val[1][2], 0);
|
||||
ck_assert_int_eq(m2.val[2][0], 0);
|
||||
ck_assert_int_eq(m2.val[2][1], 0);
|
||||
ck_assert_int_eq(m2.val[2][2], 1);
|
||||
|
||||
matrix_mult_vec(&m2, &x, &y);
|
||||
ck_assert_int_eq(x, 200);
|
||||
ck_assert_int_eq(y, 20);
|
||||
|
||||
matrix_init_translate(&m2, 10, 100);
|
||||
ck_assert_int_eq(m2.val[0][0], 1);
|
||||
ck_assert_int_eq(m2.val[0][1], 0);
|
||||
ck_assert_int_eq(m2.val[0][2], 10);
|
||||
ck_assert_int_eq(m2.val[1][0], 0);
|
||||
ck_assert_int_eq(m2.val[1][1], 1);
|
||||
ck_assert_int_eq(m2.val[1][2], 100);
|
||||
ck_assert_int_eq(m2.val[2][0], 0);
|
||||
ck_assert_int_eq(m2.val[2][1], 0);
|
||||
ck_assert_int_eq(m2.val[2][2], 1);
|
||||
|
||||
matrix_mult_vec(&m2, &x, &y);
|
||||
ck_assert_int_eq(x, 210);
|
||||
ck_assert_int_eq(y, 120);
|
||||
|
||||
matrix_to_farray6(&m2, f);
|
||||
ck_assert_int_eq(f[0], 1);
|
||||
ck_assert_int_eq(f[1], 0);
|
||||
ck_assert_int_eq(f[2], 10);
|
||||
ck_assert_int_eq(f[3], 0);
|
||||
ck_assert_int_eq(f[4], 1);
|
||||
ck_assert_int_eq(f[5], 100);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
litest_add_no_device("events:conversion", event_conversion_device_notify);
|
||||
litest_add_no_device("events:conversion", event_conversion_pointer);
|
||||
|
|
@ -480,5 +557,6 @@ int main (int argc, char **argv) {
|
|||
litest_add("device:id", device_ids, LITEST_ANY, LITEST_ANY);
|
||||
litest_add_no_device("config:status string", config_status_string);
|
||||
|
||||
litest_add_no_device("misc:matrix", matrix_helpers);
|
||||
return litest_run(argc, argv);
|
||||
}
|
||||
|
|
|
|||
47
test/path.c
47
test/path.c
|
|
@ -53,7 +53,6 @@ const struct libinput_interface simple_interface = {
|
|||
.close_restricted = close_restricted,
|
||||
};
|
||||
|
||||
|
||||
START_TEST(path_create_NULL)
|
||||
{
|
||||
struct libinput *li;
|
||||
|
|
@ -244,12 +243,11 @@ END_TEST
|
|||
|
||||
START_TEST(path_add_invalid_path)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput *li;
|
||||
struct libinput_event *event;
|
||||
struct libinput_device *device;
|
||||
|
||||
litest_drain_events(li);
|
||||
li = litest_create_context();
|
||||
|
||||
device = libinput_path_add_device(li, "/tmp/");
|
||||
ck_assert(device == NULL);
|
||||
|
|
@ -258,6 +256,8 @@ START_TEST(path_add_invalid_path)
|
|||
|
||||
while ((event = libinput_get_event(li)))
|
||||
ck_abort();
|
||||
|
||||
libinput_unref(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
|
@ -492,7 +492,6 @@ START_TEST(path_add_device_suspend_resume)
|
|||
|
||||
ck_assert_int_eq(nevents, 2);
|
||||
|
||||
|
||||
libinput_suspend(li);
|
||||
libinput_dispatch(li);
|
||||
|
||||
|
|
@ -576,7 +575,6 @@ START_TEST(path_add_device_suspend_resume_fail)
|
|||
|
||||
ck_assert_int_eq(nevents, 2);
|
||||
|
||||
|
||||
libinput_suspend(li);
|
||||
libinput_dispatch(li);
|
||||
|
||||
|
|
@ -667,7 +665,6 @@ START_TEST(path_add_device_suspend_resume_remove_device)
|
|||
|
||||
ck_assert_int_eq(nevents, 2);
|
||||
|
||||
|
||||
libinput_suspend(li);
|
||||
libinput_dispatch(li);
|
||||
|
||||
|
|
@ -796,26 +793,26 @@ START_TEST(path_seat_recycle)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
litest_add("path:create", path_create_NULL, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:create", path_create_invalid, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:create", path_create_destroy, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:suspend", path_suspend, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:suspend", path_double_suspend, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:suspend", path_double_resume, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:suspend", path_add_device_suspend_resume, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:suspend", path_add_device_suspend_resume_fail, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:suspend", path_add_device_suspend_resume_remove_device, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:seat events", path_added_seat, LITEST_ANY, LITEST_ANY);
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
litest_add_no_device("path:create", path_create_NULL);
|
||||
litest_add_no_device("path:create", path_create_invalid);
|
||||
litest_add_no_device("path:create", path_create_destroy);
|
||||
litest_add_no_device("path:suspend", path_suspend);
|
||||
litest_add_no_device("path:suspend", path_double_suspend);
|
||||
litest_add_no_device("path:suspend", path_double_resume);
|
||||
litest_add_no_device("path:suspend", path_add_device_suspend_resume);
|
||||
litest_add_no_device("path:suspend", path_add_device_suspend_resume_fail);
|
||||
litest_add_no_device("path:suspend", path_add_device_suspend_resume_remove_device);
|
||||
litest_add_for_device("path:seat events", path_added_seat, LITEST_SYNAPTICS_CLICKPAD);
|
||||
litest_add("path:device events", path_added_device, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:device events", path_device_sysname, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:device events", path_add_device, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:device events", path_add_invalid_path, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:device events", path_remove_device, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:device events", path_double_remove_device, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("path:seat", path_seat_recycle,
|
||||
LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
|
||||
litest_add_for_device("path:device events", path_add_device, LITEST_SYNAPTICS_CLICKPAD);
|
||||
litest_add_no_device("path:device events", path_add_invalid_path);
|
||||
litest_add_for_device("path:device events", path_remove_device, LITEST_SYNAPTICS_CLICKPAD);
|
||||
litest_add_for_device("path:device events", path_double_remove_device, LITEST_SYNAPTICS_CLICKPAD);
|
||||
litest_add_no_device("path:seat", path_seat_recycle);
|
||||
|
||||
return litest_run(argc, argv);
|
||||
}
|
||||
|
|
|
|||
137
test/pointer.c
137
test/pointer.c
|
|
@ -105,26 +105,13 @@ static void
|
|||
test_button_event(struct litest_device *dev, unsigned int button, int state)
|
||||
{
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_pointer *ptrev;
|
||||
|
||||
litest_event(dev, EV_KEY, button, state);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
|
||||
libinput_dispatch(li);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
ck_assert(event != NULL);
|
||||
ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_BUTTON);
|
||||
|
||||
ptrev = libinput_event_get_pointer_event(event);
|
||||
ck_assert(ptrev != NULL);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button(ptrev), button);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrev),
|
||||
state ?
|
||||
LIBINPUT_BUTTON_STATE_PRESSED :
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
libinput_event_destroy(event);
|
||||
litest_assert_button_event(li, button,
|
||||
state ? LIBINPUT_BUTTON_STATE_PRESSED :
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
}
|
||||
|
||||
START_TEST(pointer_button)
|
||||
|
|
@ -145,13 +132,104 @@ START_TEST(pointer_button)
|
|||
test_button_event(dev, BTN_RIGHT, 0);
|
||||
}
|
||||
|
||||
if (libevdev_has_event_code(dev->evdev, EV_KEY, BTN_MIDDLE)) {
|
||||
/* Skip middle button test on trackpoints (used for scrolling) */
|
||||
if (!libevdev_has_property(dev->evdev, INPUT_PROP_POINTING_STICK) &&
|
||||
libevdev_has_event_code(dev->evdev, EV_KEY, BTN_MIDDLE)) {
|
||||
test_button_event(dev, BTN_MIDDLE, 1);
|
||||
test_button_event(dev, BTN_MIDDLE, 0);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(pointer_button_auto_release)
|
||||
{
|
||||
struct libinput *libinput;
|
||||
struct litest_device *dev;
|
||||
struct libinput_event *event;
|
||||
enum libinput_event_type type;
|
||||
struct libinput_event_pointer *pevent;
|
||||
struct {
|
||||
int code;
|
||||
int released;
|
||||
} buttons[] = {
|
||||
{ .code = BTN_LEFT, },
|
||||
{ .code = BTN_MIDDLE, },
|
||||
{ .code = BTN_EXTRA, },
|
||||
{ .code = BTN_SIDE, },
|
||||
{ .code = BTN_BACK, },
|
||||
{ .code = BTN_FORWARD, },
|
||||
{ .code = BTN_4, },
|
||||
};
|
||||
int events[2 * (ARRAY_LENGTH(buttons) + 1)];
|
||||
unsigned i;
|
||||
int button;
|
||||
int valid_code;
|
||||
|
||||
/* Enable all tested buttons on the device */
|
||||
for (i = 0; i < 2 * ARRAY_LENGTH(buttons);) {
|
||||
button = buttons[i / 2].code;
|
||||
events[i++] = EV_KEY;
|
||||
events[i++] = button;
|
||||
}
|
||||
events[i++] = -1;
|
||||
events[i++] = -1;
|
||||
|
||||
libinput = litest_create_context();
|
||||
dev = litest_add_device_with_overrides(libinput,
|
||||
LITEST_MOUSE,
|
||||
"Generic mouse",
|
||||
NULL, NULL, events);
|
||||
|
||||
litest_drain_events(libinput);
|
||||
|
||||
/* Send pressed events, without releasing */
|
||||
for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
|
||||
test_button_event(dev, buttons[i].code, 1);
|
||||
}
|
||||
|
||||
litest_drain_events(libinput);
|
||||
|
||||
/* "Disconnect" device */
|
||||
litest_delete_device(dev);
|
||||
|
||||
/* Mark all released buttons until device is removed */
|
||||
while (1) {
|
||||
event = libinput_get_event(libinput);
|
||||
ck_assert_notnull(event);
|
||||
type = libinput_event_get_type(event);
|
||||
|
||||
if (type == LIBINPUT_EVENT_DEVICE_REMOVED) {
|
||||
libinput_event_destroy(event);
|
||||
break;
|
||||
}
|
||||
|
||||
ck_assert_int_eq(type, LIBINPUT_EVENT_POINTER_BUTTON);
|
||||
pevent = libinput_event_get_pointer_event(event);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button_state(pevent),
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
button = libinput_event_pointer_get_button(pevent);
|
||||
|
||||
valid_code = 0;
|
||||
for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
|
||||
if (buttons[i].code == button) {
|
||||
ck_assert_int_eq(buttons[i].released, 0);
|
||||
buttons[i].released = 1;
|
||||
valid_code = 1;
|
||||
}
|
||||
}
|
||||
ck_assert_int_eq(valid_code, 1);
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
/* Check that all pressed buttons has been released. */
|
||||
for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
|
||||
ck_assert_int_eq(buttons[i].released, 1);
|
||||
}
|
||||
|
||||
libinput_unref(libinput);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static void
|
||||
test_wheel_event(struct litest_device *dev, int which, int amount)
|
||||
{
|
||||
|
|
@ -296,12 +374,37 @@ START_TEST(pointer_seat_button_count)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(pointer_no_calibration)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput_device *d = dev->libinput_device;
|
||||
enum libinput_config_status status;
|
||||
int rc;
|
||||
float calibration[6] = {0};
|
||||
|
||||
rc = libinput_device_config_calibration_has_matrix(d);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
rc = libinput_device_config_calibration_get_matrix(d, calibration);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
rc = libinput_device_config_calibration_get_default_matrix(d,
|
||||
calibration);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
|
||||
status = libinput_device_config_calibration_set_matrix(d,
|
||||
calibration);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
litest_add("pointer:motion", pointer_motion_relative, LITEST_POINTER, LITEST_ANY);
|
||||
litest_add("pointer:button", pointer_button, LITEST_BUTTON, LITEST_CLICKPAD);
|
||||
litest_add_no_device("pointer:button_auto_release", pointer_button_auto_release);
|
||||
litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_ANY);
|
||||
litest_add_no_device("pointer:seat button count", pointer_seat_button_count);
|
||||
|
||||
litest_add("pointer:calibration", pointer_no_calibration, LITEST_ANY, LITEST_TOUCH|LITEST_SINGLE_TOUCH);
|
||||
|
||||
return litest_run(argc, argv);
|
||||
}
|
||||
|
|
|
|||
196
test/touch.c
196
test/touch.c
|
|
@ -26,6 +26,7 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <libinput.h>
|
||||
#include <libevdev/libevdev.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libinput-util.h"
|
||||
|
|
@ -112,7 +113,6 @@ START_TEST(touch_abs_transform)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(touch_many_slots)
|
||||
{
|
||||
struct libinput *libinput;
|
||||
|
|
@ -213,6 +213,194 @@ START_TEST(touch_double_touch_down_up)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touch_calibration_scale)
|
||||
{
|
||||
struct libinput *li;
|
||||
struct litest_device *dev;
|
||||
struct libinput_event *ev;
|
||||
struct libinput_event_touch *tev;
|
||||
float matrix[6] = {
|
||||
1, 0, 0,
|
||||
0, 1, 0
|
||||
};
|
||||
|
||||
float calibration;
|
||||
double x, y;
|
||||
const int width = 640, height = 480;
|
||||
|
||||
dev = litest_current_device();
|
||||
li = dev->libinput;
|
||||
|
||||
for (calibration = 0.1; calibration < 1; calibration += 0.1) {
|
||||
libinput_device_config_calibration_set_matrix(dev->libinput_device,
|
||||
matrix);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 100, 100);
|
||||
litest_touch_up(dev, 0);
|
||||
|
||||
litest_wait_for_event(li);
|
||||
ev = libinput_get_event(li);
|
||||
ck_assert_int_eq(libinput_event_get_type(ev),
|
||||
LIBINPUT_EVENT_TOUCH_DOWN);
|
||||
tev = libinput_event_get_touch_event(ev);
|
||||
|
||||
x = libinput_event_touch_get_x_transformed(tev, width);
|
||||
y = libinput_event_touch_get_y_transformed(tev, height);
|
||||
|
||||
ck_assert_int_eq(round(x), round(width * matrix[0]));
|
||||
ck_assert_int_eq(round(y), round(height * matrix[4]));
|
||||
|
||||
libinput_event_destroy(ev);
|
||||
litest_drain_events(li);
|
||||
|
||||
matrix[0] = calibration;
|
||||
matrix[4] = 1 - calibration;
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touch_calibration_rotation)
|
||||
{
|
||||
struct libinput *li;
|
||||
struct litest_device *dev;
|
||||
struct libinput_event *ev;
|
||||
struct libinput_event_touch *tev;
|
||||
float matrix[6];
|
||||
int i;
|
||||
double x, y;
|
||||
int width = 1024, height = 480;
|
||||
|
||||
dev = litest_current_device();
|
||||
li = dev->libinput;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
float angle = i * M_PI/2;
|
||||
|
||||
/* [ cos -sin tx ]
|
||||
[ sin cos ty ]
|
||||
[ 0 0 1 ] */
|
||||
matrix[0] = cos(angle);
|
||||
matrix[1] = -sin(angle);
|
||||
matrix[3] = sin(angle);
|
||||
matrix[4] = cos(angle);
|
||||
|
||||
switch(i) {
|
||||
case 0: /* 0 deg */
|
||||
matrix[2] = 0;
|
||||
matrix[5] = 0;
|
||||
break;
|
||||
case 1: /* 90 deg cw */
|
||||
matrix[2] = 1;
|
||||
matrix[5] = 0;
|
||||
break;
|
||||
case 2: /* 180 deg cw */
|
||||
matrix[2] = 1;
|
||||
matrix[5] = 1;
|
||||
break;
|
||||
case 3: /* 270 deg cw */
|
||||
matrix[2] = 0;
|
||||
matrix[5] = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
libinput_device_config_calibration_set_matrix(dev->libinput_device,
|
||||
matrix);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 80, 20);
|
||||
litest_touch_up(dev, 0);
|
||||
litest_wait_for_event(li);
|
||||
ev = libinput_get_event(li);
|
||||
ck_assert_int_eq(libinput_event_get_type(ev),
|
||||
LIBINPUT_EVENT_TOUCH_DOWN);
|
||||
tev = libinput_event_get_touch_event(ev);
|
||||
|
||||
x = libinput_event_touch_get_x_transformed(tev, width);
|
||||
y = libinput_event_touch_get_y_transformed(tev, height);
|
||||
|
||||
/* rounding errors... */
|
||||
#define almost_equal(a_, b_) \
|
||||
{ ck_assert_int_ge((a_) + 0.5, (b_) - 1); \
|
||||
ck_assert_int_le((a_) + 0.5, (b_) + 1); }
|
||||
switch(i) {
|
||||
case 0: /* 0 deg */
|
||||
almost_equal(x, width * 0.8);
|
||||
almost_equal(y, height * 0.2);
|
||||
break;
|
||||
case 1: /* 90 deg cw */
|
||||
almost_equal(x, width * 0.8);
|
||||
almost_equal(y, height * 0.8);
|
||||
break;
|
||||
case 2: /* 180 deg cw */
|
||||
almost_equal(x, width * 0.2);
|
||||
almost_equal(y, height * 0.8);
|
||||
break;
|
||||
case 3: /* 270 deg cw */
|
||||
almost_equal(x, width * 0.2);
|
||||
almost_equal(y, height * 0.2);
|
||||
break;
|
||||
}
|
||||
#undef almost_equal
|
||||
|
||||
|
||||
libinput_event_destroy(ev);
|
||||
litest_drain_events(li);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touch_calibration_translation)
|
||||
{
|
||||
struct libinput *li;
|
||||
struct litest_device *dev;
|
||||
struct libinput_event *ev;
|
||||
struct libinput_event_touch *tev;
|
||||
float matrix[6] = {
|
||||
1, 0, 0,
|
||||
0, 1, 0
|
||||
};
|
||||
|
||||
float translate;
|
||||
double x, y;
|
||||
const int width = 640, height = 480;
|
||||
|
||||
dev = litest_current_device();
|
||||
li = dev->libinput;
|
||||
|
||||
/* translating from 0 up to 1 device width/height */
|
||||
for (translate = 0.1; translate <= 1; translate += 0.1) {
|
||||
libinput_device_config_calibration_set_matrix(dev->libinput_device,
|
||||
matrix);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 100, 100);
|
||||
litest_touch_up(dev, 0);
|
||||
|
||||
litest_wait_for_event(li);
|
||||
ev = libinput_get_event(li);
|
||||
ck_assert_int_eq(libinput_event_get_type(ev),
|
||||
LIBINPUT_EVENT_TOUCH_DOWN);
|
||||
tev = libinput_event_get_touch_event(ev);
|
||||
|
||||
x = libinput_event_touch_get_x_transformed(tev, width);
|
||||
y = libinput_event_touch_get_y_transformed(tev, height);
|
||||
|
||||
/* sigh. rounding errors */
|
||||
ck_assert_int_ge(round(x), width + round(width * matrix[2]) - 1);
|
||||
ck_assert_int_ge(round(y), height + round(height * matrix[5]) - 1);
|
||||
ck_assert_int_le(round(x), width + round(width * matrix[2]) + 1);
|
||||
ck_assert_int_le(round(y), height + round(height * matrix[5]) + 1);
|
||||
|
||||
libinput_event_destroy(ev);
|
||||
litest_drain_events(li);
|
||||
|
||||
matrix[2] = translate;
|
||||
matrix[5] = 1 - translate;
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
|
@ -220,6 +408,12 @@ main(int argc, char **argv)
|
|||
litest_add_no_device("touch:abs-transform", touch_abs_transform);
|
||||
litest_add_no_device("touch:many-slots", touch_many_slots);
|
||||
litest_add("touch:double-touch-down-up", touch_double_touch_down_up, LITEST_TOUCH, LITEST_ANY);
|
||||
litest_add("touch:calibration", touch_calibration_scale, LITEST_TOUCH, LITEST_TOUCHPAD);
|
||||
litest_add("touch:calibration", touch_calibration_scale, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
|
||||
litest_add("touch:calibration", touch_calibration_rotation, LITEST_TOUCH, LITEST_TOUCHPAD);
|
||||
litest_add("touch:calibration", touch_calibration_rotation, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
|
||||
litest_add("touch:calibration", touch_calibration_translation, LITEST_TOUCH, LITEST_TOUCHPAD);
|
||||
litest_add("touch:calibration", touch_calibration_translation, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
|
||||
|
||||
return litest_run(argc, argv);
|
||||
}
|
||||
|
|
|
|||
622
test/touchpad.c
622
test/touchpad.c
File diff suppressed because it is too large
Load diff
103
test/trackpoint.c
Normal file
103
test/trackpoint.c
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright © 2014 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the copyright holders not be used in
|
||||
* advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The copyright holders make
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <check.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <libinput.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libinput-util.h"
|
||||
#include "litest.h"
|
||||
|
||||
START_TEST(trackpoint_middlebutton)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
/* A quick middle button click should get reported normally */
|
||||
litest_button_click(dev, BTN_MIDDLE, 1);
|
||||
litest_button_click(dev, BTN_MIDDLE, 0);
|
||||
|
||||
litest_assert_button_event(li, BTN_MIDDLE, 1);
|
||||
litest_assert_button_event(li, BTN_MIDDLE, 0);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static void
|
||||
test_2fg_scroll(struct litest_device *dev, double dx, double dy)
|
||||
{
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
litest_button_click(dev, BTN_MIDDLE, 1);
|
||||
|
||||
libinput_dispatch(li);
|
||||
msleep(300);
|
||||
libinput_dispatch(li);
|
||||
|
||||
litest_event(dev, EV_REL, REL_X, dx);
|
||||
litest_event(dev, EV_REL, REL_Y, dy);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
|
||||
litest_button_click(dev, BTN_MIDDLE, 0);
|
||||
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
START_TEST(trackpoint_scroll)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
test_2fg_scroll(dev, 1, 6);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 6);
|
||||
test_2fg_scroll(dev, 1, -7);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -7);
|
||||
test_2fg_scroll(dev, 8, 1);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 8);
|
||||
test_2fg_scroll(dev, -9, 1);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -9);
|
||||
|
||||
/* scroll smaller than the threshold should not generate events */
|
||||
test_2fg_scroll(dev, 1, 1);
|
||||
/* long middle press without movement should not generate events */
|
||||
test_2fg_scroll(dev, 0, 0);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
litest_add("trackpoint:middlebutton", trackpoint_middlebutton, LITEST_POINTINGSTICK, LITEST_ANY);
|
||||
litest_add("trackpoint:scroll", trackpoint_scroll, LITEST_POINTINGSTICK, LITEST_ANY);
|
||||
|
||||
return litest_run(argc, argv);
|
||||
}
|
||||
16
test/udev.c
16
test/udev.c
|
|
@ -47,7 +47,6 @@ const struct libinput_interface simple_interface = {
|
|||
.close_restricted = close_restricted,
|
||||
};
|
||||
|
||||
|
||||
START_TEST(udev_create_NULL)
|
||||
{
|
||||
struct libinput *li;
|
||||
|
|
@ -408,19 +407,20 @@ START_TEST(udev_seat_recycle)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
litest_add_no_device("udev:create", udev_create_NULL);
|
||||
litest_add_no_device("udev:create", udev_create_seat0);
|
||||
litest_add_no_device("udev:create", udev_create_empty_seat);
|
||||
|
||||
litest_add_no_device("udev:seat events", udev_added_seat_default);
|
||||
|
||||
litest_add("udev:suspend", udev_double_suspend, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("udev:suspend", udev_double_resume, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("udev:suspend", udev_suspend_resume, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("udev:device events", udev_device_sysname, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("udev:seat", udev_seat_recycle, LITEST_ANY, LITEST_ANY);
|
||||
litest_add_for_device("udev:suspend", udev_double_suspend, LITEST_SYNAPTICS_CLICKPAD);
|
||||
litest_add_for_device("udev:suspend", udev_double_resume, LITEST_SYNAPTICS_CLICKPAD);
|
||||
litest_add_for_device("udev:suspend", udev_suspend_resume, LITEST_SYNAPTICS_CLICKPAD);
|
||||
litest_add_for_device("udev:device events", udev_device_sysname, LITEST_SYNAPTICS_CLICKPAD);
|
||||
litest_add_for_device("udev:seat", udev_seat_recycle, LITEST_SYNAPTICS_CLICKPAD);
|
||||
|
||||
return litest_run(argc, argv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include \
|
|||
|
||||
event_debug_SOURCES = event-debug.c
|
||||
event_debug_LDADD = ../src/libinput.la $(LIBUDEV_LIBS)
|
||||
event_debug_LDFLAGS = -static
|
||||
event_debug_LDFLAGS = -no-install
|
||||
event_debug_CFLAGS = $(LIBUDEV_CFLAGS)
|
||||
|
||||
if BUILD_EVENTGUI
|
||||
|
|
@ -14,5 +14,5 @@ noinst_PROGRAMS += event-gui
|
|||
event_gui_SOURCES = event-gui.c
|
||||
event_gui_LDADD = ../src/libinput.la $(CAIRO_LIBS) $(GTK_LIBS) $(LIBUDEV_LIBS)
|
||||
event_gui_CFLAGS = $(CAIRO_CFLAGS) $(GTK_CFLAGS) $(LIBUDEV_CFLAGS)
|
||||
event_gui_LDFLAGS = -static
|
||||
event_gui_LDFLAGS = -no-install
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -223,6 +223,15 @@ handle_event_device_notify(struct libinput_event *ev)
|
|||
type = "removed";
|
||||
|
||||
msg("%s %s\n", libinput_device_get_sysname(dev), type);
|
||||
|
||||
if (libinput_device_config_tap_get_finger_count(dev) > 0) {
|
||||
enum libinput_config_status status;
|
||||
status = libinput_device_config_tap_set_enabled(dev,
|
||||
LIBINPUT_CONFIG_TAP_ENABLED);
|
||||
if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
|
||||
error("%s: Failed to enable tapping\n",
|
||||
libinput_device_get_sysname(dev));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -427,7 +436,6 @@ parse_opts(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
open_restricted(const char *path, int flags, void *user_data)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue