From 8ae137789c8d1821e663892aa051db6f039da1d9 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 11:55:17 +1000 Subject: [PATCH 01/55] test: fix busted indentation Signed-off-by: Peter Hutterer --- test/touchpad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/touchpad.c b/test/touchpad.c index 934674c1..84b30804 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -924,7 +924,7 @@ START_TEST(clickpad_softbutton_left) litest_assert_button_event(li, BTN_LEFT, - LIBINPUT_BUTTON_STATE_PRESSED); + LIBINPUT_BUTTON_STATE_PRESSED); litest_event(dev, EV_KEY, BTN_LEFT, 0); litest_event(dev, EV_SYN, SYN_REPORT, 0); @@ -932,7 +932,7 @@ START_TEST(clickpad_softbutton_left) litest_assert_button_event(li, BTN_LEFT, - LIBINPUT_BUTTON_STATE_RELEASED); + LIBINPUT_BUTTON_STATE_RELEASED); libinput_dispatch(li); From 0343a62a9fc5c22a801017bcb884961324a39f4a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 12:57:59 +1000 Subject: [PATCH 02/55] tools: add --help to event-debug's usage Signed-off-by: Peter Hutterer --- tools/event-debug.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/event-debug.c b/tools/event-debug.c index 2a48e2db..3e4981b1 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -54,6 +54,7 @@ usage(void) { printf("Usage: %s [--verbose] [--udev []|--device /dev/input/event0]\n" "--verbose ....... Print debugging output.\n" + "--help .......... Print this help.\n" "--udev .... Use udev device discovery (default).\n" " Specifying a seat ID is optional.\n" "--device /path/to/device .... open the given device only\n", From 0b7efd62118e3cd25b67776b48570f3b4e8d1f76 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Thu, 18 Dec 2014 10:49:58 -0800 Subject: [PATCH 03/55] Initial move of some wiki contents into main documentation. This moves some information from the wiki into the main generated doxygen documenation. It is fairly rought but includes examples for inline and stand-alone diagrams, linking to external HTML pages, etc. Among other things, it allows for better cross-referencing into the main doxygen contents and thus for overall shorter documentation. Signed-off-by: Jon A. Cruz Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- configure.ac | 9 +++++ doc/Makefile.am | 16 +++++++-- doc/absolute-axes.dox | 64 ++++++++++++++++++++++++++++++++++ doc/clickpad-softbuttons.dox | 67 ++++++++++++++++++++++++++++++++++++ doc/dot/seats-sketch.gv | 41 ++++++++++++++++++++++ doc/seats.dox | 10 ++++++ doc/t440-support.dox | 66 +++++++++++++++++++++++++++++++++++ 7 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 doc/absolute-axes.dox create mode 100644 doc/clickpad-softbuttons.dox create mode 100644 doc/dot/seats-sketch.gv create mode 100644 doc/seats.dox create mode 100644 doc/t440-support.dox diff --git a/configure.ac b/configure.ac index 33e380ce..329f2245 100644 --- a/configure.ac +++ b/configure.ac @@ -76,6 +76,15 @@ else fi AM_CONDITIONAL([HAVE_DOXYGEN], [test "x$have_doxygen" = "xyes"]) +AC_PATH_PROG(DOT, dot) +if test "x$DOT" = "x"; then + AC_MSG_WARN([Graphviz's dot not found - required for documentation]) + have_dot="no" +else + have_dot="yes" +fi +AM_CONDITIONAL([HAVE_DOT], [test "x$have_dot" = "xyes"]) + AC_ARG_ENABLE(event-gui, AS_HELP_STRING([--enable-event-gui], [Build the GUI event viewer (default=auto)]), [build_eventgui="$enableval"], diff --git a/doc/Makefile.am b/doc/Makefile.am index 8f05bd2c..624326ba 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -6,10 +6,20 @@ noinst_DATA = html/index.html header_files = \ $(top_srcdir)/src/libinput.h \ - $(top_srcdir)/README.txt + $(top_srcdir)/README.txt \ + $(srcdir)/absolute-axes.dox \ + $(srcdir)/clickpad-softbuttons.dox \ + $(srcdir)/seats.dox \ + $(srcdir)/t440-support.dox -html/index.html: libinput.doxygen $(header_files) - $(AM_V_GEN)$(DOXYGEN) $< +diagram_files = \ + $(srcdir)/dot/seats-sketch.gv + +html/index.html: libinput.doxygen $(header_files) $(diagram_files) + $(AM_V_GEN)(cat $<; \ + echo "INPUT = $(header_files)"; \ + echo "DOTFILE_DIRS = $(srcdir)/dot"; \ + ) | $(DOXYGEN) - clean-local: $(AM_V_at)rm -rf html diff --git a/doc/absolute-axes.dox b/doc/absolute-axes.dox new file mode 100644 index 00000000..ee041130 --- /dev/null +++ b/doc/absolute-axes.dox @@ -0,0 +1,64 @@ +/** +@page absolute_axes Absolute Axes in libinput + +Devices with absolute axes are those that send positioning data for an axis in +a device-specific coordinate range, defined by a minimum and a maximum value. +Compare this to relative devices (e.g. a mouse) that can only detect +directional data, not positional data. + +libinput supports three types of devices with absolute axes: + + - multi-touch screens + - single-touch screens + - graphics tablets (currently WIP) + +Touchpads are technically absolute devices, but the axis values are converted +to directional motion and posted as relative events. Touchpads do not count +as absolute devices in libinput. + +For all absolute devices in libinput, the default unit for x/y coordinates is +in mm off the top left corner on the device, or more specifically off the +device's sensor, see @ref index "the API doc" + +@section absolute_axes_nonorm Why x/y coordinates are not normalized + +x/y are not given in @ref motion_normalization "normalized coordinates" +([0..1]) for one simple reason: the aspect ratio of virtually all current +devices is something other than 1:1. A normalized axes thus is only useful to +determine that the stylus is e.g. at 78% from the left, 34% from the top of +the device. Without knowing the per-axis resolution, these numbers are +meaningless. Worse, calculation based on previous coordinates is simply wrong: +a movement from 0/0 to 50%/50% is not a 45% degree line. + +This could be alleviated by providing resolution and information about the +aspect ratio to the caller. Which shifts processing and likely errors into the +caller for little benefit. Providing the x/y axes in mm from the outset +removes these errors. + +@section absolute_axes_handling Handling of absolute coordinates + +In most use-cases, absolute input devices are mapped to a single screen. For +direct input devices such as touchscreens the aspect ratio of the screen and +the device match. Mapping the input device position to the output position is +thus a simple mapping between two coordinates. libinput provides the API for +this with + +- libinput_event_pointer_get_absolute_x_transformed() for pointer events +- libinput_event_touch_get_x_transformed() for touch events + +See @ref index "the API doc" for more details. + +libinput's API only provides the call to map into a single coordinate range. +If the coordinate range has an offset, the compositor is responsible for +applying that offset after the mapping. For example, if the device is mapped +to the right of two outputs, add the output offset to the transformed +coordinate. + +@section absolute_axes_nores Devices without x/y resolution + +An absolute device that does not provide a valid resolution is considered +buggy and must be fixed in the kernel. Some touchpad devices that do not +provide resolution, those devices are correctly handled within libinput +(touchpads are not absolute devices, as mentioned above). + +*/ \ No newline at end of file diff --git a/doc/clickpad-softbuttons.dox b/doc/clickpad-softbuttons.dox new file mode 100644 index 00000000..3ac0323f --- /dev/null +++ b/doc/clickpad-softbuttons.dox @@ -0,0 +1,67 @@ +/** +@page clickpad_softbuttons Clickpad Software Button behavior + +Clickpad is the name given to touchpads without physical buttons below the +touchpad. Instead, the whole touchpad acts as a button and left or right +button clicks are distinguished by the location and/or number of fingers on +the touchpad. "ClickPad" is +a term coined by Synaptics Inc. but for simplicity we refer to any +touchpad with the above feature as Clickpad, regardless of the manufacturer. + +A clickpad is always marked with the INPUT_PROP_BUTTONPAD property. Note that +there is a type of clickpads that have the top section marked as software +buttons as well. See @ref t440_support "Lenovo *40 series touchpad support" +for details on the top software button. + +To perform a right-click on a Clickpad, two methods are available in libinput: + +- on Apple touchpads, a right click is performed by two fingers on the + touchpad while clicking, a behavior termed "clickfinger" +- on non-Apple touchpads, a right click is performed by a finger in a + software-defined right button area + +The button behavior depends on the hardware. Some Clickpads, notably some +Cypress ones, perform right button detection in firmware and appear to +userspace as if the touchpad had physical buttons. While physically clickpads, +these are not handled by the software and treated like traditional touchpads. + +The clickfinger behavior is subject to some restrictions: + +- two fingers execute a right click, three fingers a middle click +- The Xorg synaptics driver uses 30% of the touchpad dimensions as threshold, + libinput does not have this restrictions. If two fingers are on the pad + while clicking, that is a two-finger click. +- clickfinger behavior is only enabled on Apple touchpads + +The button behavior is subject to some restrictions: + +The button area is usually defined like this: + +@dot +digraph G { + clickpad [ + shape = "record"; + label = "{\nMain\nArea\n\n|{LEFT|RIGHT}}"; + ] +} +@enddot + +The size of the buttons is hardware dependent. + +- if fingers are only down in the main area, a left click is generated +- if a finger is in the right area when the physical click happens, a right + click is generated +- if fingers are in both the left and right area, a middle click is generated +- fingers in the main area are not considered for right or middle click + generation +- if a finger starts in the main area, the software buttons do not apply to + that finger +- a finger in the software button area does not move the pointer, but once it + moves out of the button area it will control the pointer (if it's the first + finger to do so) +- once a finger has moved out of the button area, it cannot move back in and + trigger a right/middle button click +- a release event releases the buttons logically down, regardless of the + current finger position + +*/ \ No newline at end of file diff --git a/doc/dot/seats-sketch.gv b/doc/dot/seats-sketch.gv new file mode 100644 index 00000000..f537df1a --- /dev/null +++ b/doc/dot/seats-sketch.gv @@ -0,0 +1,41 @@ +digraph seats +{ + rankdir="BT"; + node [ + shape="box"; + ] + + kernel [label="Kernel"]; + + event0 [URL="\ref libinput_event"]; + event1 [URL="\ref libinput_event"]; + event2 [URL="\ref libinput_event"]; + event3 [URL="\ref libinput_event"]; + + pseat0 [label="phys seat0"; URL="\ref libinput_seat_get_physical_name"]; + pseat1 [label="phys seat1"; URL="\ref libinput_seat_get_physical_name"]; + + lseatA [label="log seat A"; URL="\ref libinput_seat_get_logical_name"]; + lseatB [label="log seat B"; URL="\ref libinput_seat_get_logical_name"]; + lseatC [label="log seat C"; URL="\ref libinput_seat_get_logical_name"]; + + ctx1 [label="libinput context 1"; URL="\ref libinput"]; + ctx2 [label="libinput context 2"; URL="\ref libinput"]; + + kernel -> event0 + kernel -> event1 + kernel -> event2 + kernel -> event3 + + event0 -> pseat0 + event1 -> pseat0 + event2 -> pseat0 + event3 -> pseat1 + + pseat0 -> ctx1 + pseat1 -> ctx2 + + ctx1 -> lseatA + ctx1 -> lseatB + ctx2 -> lseatC +} \ No newline at end of file diff --git a/doc/seats.dox b/doc/seats.dox new file mode 100644 index 00000000..fe777606 --- /dev/null +++ b/doc/seats.dox @@ -0,0 +1,10 @@ +/** +@page seats Seats + +@section seats_overview Overview + +@dotfile seats-sketch.gv + +Details pending. + +*/ diff --git a/doc/t440-support.dox b/doc/t440-support.dox new file mode 100644 index 00000000..6261ce02 --- /dev/null +++ b/doc/t440-support.dox @@ -0,0 +1,66 @@ +/** +@page t440_support Lenovo *40 series touchpad support + +@section t440_support_overview Overview + +The Lenovo *40 series introduced a new type of touchpad. Previously, all +laptops had a separate set of physical buttons for the +trackstick. This +series removed these buttons, relying on a software emulation of the top +section of the touchpad. This is visually marked on the trackpad itself, +approximately like this: + +@dot +digraph G { + subgraph cluster_0 { + margin="0"; + + clickpad [ + shape = "record"; + color = "none"; + label = "{{LLLLLLLLLL|MMMMM|RRRRRRRRR}|\n\n\n\n\n\n\n\n|{LLLLLLLL| |RRRRRRRR}}"; + ] + } +} +@enddot + +The below is a list of what is needed for support of these devices. This page +only covers the top software buttons, the bottom button behavior is covered in +@ref clickpad_softbuttons "Clickpad software buttons". + +@section t440_support_btn_size Size of the buttons + +The approximate size of the top software buttons is 8% of the touchpad's +announced range, starting from the top. Note that a +kernel patch is required to +get the right ranges. + +The size of the left and right buttons is approximately 42%, the middle button +is centered and should be assigned approximately 16% of the touchpad width. + +@section t440_support_btn_behavior Button behavior + +Movement in the top button area must not generate pointer movement, these +buttons are not replacement buttons for the bottom area but have their own +behaviour. They do not work for click-and-drag. + +If the finger starts inside the top area and moves outside the button area +without the physical button being down, movement may start. + +Movement into the top button area should not trigger button events, a click +has to start inside this area to take effect. + +The top button areas must work, even if the touchpad is otherwise disabled +(e.g. by a disable-while-typing feature). + +@section t440_support_identification Identification + +The touchpads can be identified by the PNPID, or by a DMI match + +- Helix: PnPID: LEN0033, DMI substring match "Helix" +- T540: PnPID: LEN0034, DMI substring match "T540?" +- x240: PnPID: LEN0035, DMI substring match "X240" +- T440: PnPID: LEN0036, DMI substring match "T440?" +- Yoga: PnPID: LEN0042, DMI subString match "S1Yoga" + +*/ From b853ec90d56d4f052980d6dd7ef37fa83e6062d3 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Thu, 18 Dec 2014 10:49:59 -0800 Subject: [PATCH 04/55] Added configure option for documentation build. Added option with fallback of 'auto' to control building of documentation. Signed-off-by: Jon A. Cruz Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- configure.ac | 66 +++++++++++++++++++++++++++++++++++++------------ doc/Makefile.am | 2 +- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/configure.ac b/configure.ac index 329f2245..374a63aa 100644 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,7 @@ AM_SILENT_RULES([yes]) # Check for programs AC_PROG_CC_C99 AC_PROG_CXX # Only used by build C++ test +AC_PROG_GREP # Initialize libtool LT_PREREQ([2.2]) @@ -67,23 +68,55 @@ fi AC_SUBST(GCC_CFLAGS) AC_SUBST(GCC_CXXFLAGS) -AC_PATH_PROG(DOXYGEN, [doxygen]) -if test "x$DOXYGEN" = "x"; then - AC_MSG_WARN([doxygen not found - required for documentation]) - have_doxygen="no" -else - have_doxygen="yes" -fi -AM_CONDITIONAL([HAVE_DOXYGEN], [test "x$have_doxygen" = "xyes"]) +AC_ARG_ENABLE([documentation], + [AC_HELP_STRING([--enable-documentation], + [Enable building the documentation (default=auto)])], + [build_documentation="$enableval"], + [build_documentation="auto"]) -AC_PATH_PROG(DOT, dot) -if test "x$DOT" = "x"; then - AC_MSG_WARN([Graphviz's dot not found - required for documentation]) - have_dot="no" -else - have_dot="yes" +if test "x$build_documentation" = "xyes" -o "x$build_documentation" = "xauto"; then + AC_PATH_PROG(DOXYGEN, doxygen) + if test "x$DOXYGEN" = "x"; then + if test "x$build_documentation" = "xyes"; then + AC_MSG_ERROR([Documentation build requested but doxygen not found. Install doxygen or disable the documentation using --disable-documentation]) + fi + else + AC_MSG_CHECKING([for compatible doxygen version]) + doxygen_version=`$DOXYGEN --version` + AS_VERSION_COMPARE([$doxygen_version], [1.6.0], + [AC_MSG_RESULT([no]) + DOXYGEN=""], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([yes])]) + if test "x$DOXYGEN" = "x" -a "x$build_documentation" = "xyes"; then + AC_MSG_ERROR([Doxygen $doxygen_version too old. Doxygen 1.6+ required for documentation build. Install required doxygen version or disable the documentation using --disable-documentation]) + fi + fi + + AC_PATH_PROG(DOT, dot) + if test "x$DOT" = "x"; then + if test "x$build_documentation" = "xyes"; then + AC_MSG_ERROR([Documentation build requested but graphviz's dot not found. Install graphviz or disable the documentation using --disable-documentation]) + fi + else + AC_MSG_CHECKING([for compatible dot version]) + dot_version=`$DOT -V 2>&1|$GREP -oP '(?<=version\W)@<:@0-9.@:>@*(?=\W(.*))'` + AS_VERSION_COMPARE([$dot_version], [2.26.0], + [AC_MSG_RESULT([no]) + DOT=""], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([yes])]) + if test "x$DOT" = "x" -a "x$build_documentation" = "xyes"; then + AC_MSG_ERROR([Graphviz dot $dot_version too old. Graphviz 2.26+ required for documentation build. Install required graphviz version or disable the documentation using --disable-documentation]) + fi + fi + + if test "x$DOXYGEN" != "x" -a "x$DOT" != "x"; then + build_documentation="yes" + else + build_documentation="no" + fi fi -AM_CONDITIONAL([HAVE_DOT], [test "x$have_dot" = "xyes"]) AC_ARG_ENABLE(event-gui, AS_HELP_STRING([--enable-event-gui], [Build the GUI event viewer (default=auto)]), @@ -120,6 +153,7 @@ fi AM_CONDITIONAL(HAVE_VALGRIND, [test "x$VALGRIND" != "x"]) AM_CONDITIONAL(BUILD_TESTS, [test "x$build_tests" = "xyes"]) +AM_CONDITIONAL(BUILD_DOCS, [test "x$build_documentation" = "xyes"]) AC_CONFIG_FILES([Makefile doc/Makefile @@ -134,7 +168,7 @@ AC_OUTPUT AC_MSG_RESULT([ Prefix ${prefix} - Build documentation ${have_doxygen} + Build documentation ${build_documentation} Build tests ${build_tests} Tests use valgrind ${VALGRIND} Build GUI event tool ${build_eventgui} diff --git a/doc/Makefile.am b/doc/Makefile.am index 624326ba..30f60895 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,6 +1,6 @@ EXTRA_DIST = touchpad-tap-state-machine.svg touchpad-softbutton-state-machine.svg -if HAVE_DOXYGEN +if BUILD_DOCS noinst_DATA = html/index.html From f82aa16624998855dbfe96c6641906d67e47e352 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 22 Dec 2014 10:04:58 +1000 Subject: [PATCH 05/55] Improve the documentation Signed-off-by: Peter Hutterer --- doc/absolute-axes.dox | 60 +++++++++++----------- doc/clickpad-softbuttons.dox | 99 ++++++++++++++++++++---------------- doc/seats.dox | 2 + doc/t440-support.dox | 58 ++++++++++++--------- 4 files changed, 120 insertions(+), 99 deletions(-) diff --git a/doc/absolute-axes.dox b/doc/absolute-axes.dox index ee041130..f1ff973b 100644 --- a/doc/absolute-axes.dox +++ b/doc/absolute-axes.dox @@ -1,5 +1,5 @@ /** -@page absolute_axes Absolute Axes in libinput +@page absolute_axes Absolute axes Devices with absolute axes are those that send positioning data for an axis in a device-specific coordinate range, defined by a minimum and a maximum value. @@ -12,13 +12,37 @@ libinput supports three types of devices with absolute axes: - single-touch screens - graphics tablets (currently WIP) -Touchpads are technically absolute devices, but the axis values are converted -to directional motion and posted as relative events. Touchpads do not count +Touchpads are technically absolute devices but libinput converts the axis values +to directional motion and posts events as relative events. Touchpads do not count as absolute devices in libinput. For all absolute devices in libinput, the default unit for x/y coordinates is in mm off the top left corner on the device, or more specifically off the -device's sensor, see @ref index "the API doc" +device's sensor. + +@section absolute_axes_handling Handling of absolute coordinates + +In most use-cases, absolute input devices are mapped to a single screen. For +direct input devices such as touchscreens the aspect ratio of the screen and +the device match. Mapping the input device position to the output position is +thus a simple mapping between two coordinates. libinput provides the API for +this with + +- libinput_event_pointer_get_absolute_x_transformed() for pointer events +- libinput_event_touch_get_x_transformed() for touch events + +libinput's API only provides the call to map into a single coordinate range. +If the coordinate range has an offset, the compositor is responsible for +applying that offset after the mapping. For example, if the device is mapped +to the right of two outputs, add the output offset to the transformed +coordinate. + +@section absolute_axes_nores Devices without x/y resolution + +An absolute device that does not provide a valid resolution is considered +buggy and must be fixed in the kernel. Some touchpad devices that do not +provide resolution, those devices are correctly handled within libinput +(touchpads are not absolute devices, as mentioned above). @section absolute_axes_nonorm Why x/y coordinates are not normalized @@ -35,30 +59,4 @@ aspect ratio to the caller. Which shifts processing and likely errors into the caller for little benefit. Providing the x/y axes in mm from the outset removes these errors. -@section absolute_axes_handling Handling of absolute coordinates - -In most use-cases, absolute input devices are mapped to a single screen. For -direct input devices such as touchscreens the aspect ratio of the screen and -the device match. Mapping the input device position to the output position is -thus a simple mapping between two coordinates. libinput provides the API for -this with - -- libinput_event_pointer_get_absolute_x_transformed() for pointer events -- libinput_event_touch_get_x_transformed() for touch events - -See @ref index "the API doc" for more details. - -libinput's API only provides the call to map into a single coordinate range. -If the coordinate range has an offset, the compositor is responsible for -applying that offset after the mapping. For example, if the device is mapped -to the right of two outputs, add the output offset to the transformed -coordinate. - -@section absolute_axes_nores Devices without x/y resolution - -An absolute device that does not provide a valid resolution is considered -buggy and must be fixed in the kernel. Some touchpad devices that do not -provide resolution, those devices are correctly handled within libinput -(touchpads are not absolute devices, as mentioned above). - -*/ \ No newline at end of file +*/ diff --git a/doc/clickpad-softbuttons.dox b/doc/clickpad-softbuttons.dox index 3ac0323f..2653c3b7 100644 --- a/doc/clickpad-softbuttons.dox +++ b/doc/clickpad-softbuttons.dox @@ -1,41 +1,28 @@ /** -@page clickpad_softbuttons Clickpad Software Button behavior +@page clickpad_softbuttons Clickpad software button behavior Clickpad is the name given to touchpads without physical buttons below the touchpad. Instead, the whole touchpad acts as a button and left or right button clicks are distinguished by the location and/or number of fingers on the touchpad. "ClickPad" is -a term coined by Synaptics Inc. but for simplicity we refer to any +a trademark by Synaptics Inc. but for simplicity we refer to any touchpad with the above feature as Clickpad, regardless of the manufacturer. -A clickpad is always marked with the INPUT_PROP_BUTTONPAD property. Note that -there is a type of clickpads that have the top section marked as software -buttons as well. See @ref t440_support "Lenovo *40 series touchpad support" -for details on the top software button. +A clickpad is always marked with the INPUT_PROP_BUTTONPAD property. +To perform a right-click on a Clickpad, libinput provides @ref +software_buttons and @ref clickfinger. -To perform a right-click on a Clickpad, two methods are available in libinput: +In the page below, the term "click" shall refer to a physical button press +and/or release of the touchpad, the term "button event" refers to the events +generated by libinput and passed to the caller in response to a click. -- on Apple touchpads, a right click is performed by two fingers on the - touchpad while clicking, a behavior termed "clickfinger" -- on non-Apple touchpads, a right click is performed by a finger in a - software-defined right button area +@section software_buttons Software button areas -The button behavior depends on the hardware. Some Clickpads, notably some -Cypress ones, perform right button detection in firmware and appear to -userspace as if the touchpad had physical buttons. While physically clickpads, -these are not handled by the software and treated like traditional touchpads. - -The clickfinger behavior is subject to some restrictions: - -- two fingers execute a right click, three fingers a middle click -- The Xorg synaptics driver uses 30% of the touchpad dimensions as threshold, - libinput does not have this restrictions. If two fingers are on the pad - while clicking, that is a two-finger click. -- clickfinger behavior is only enabled on Apple touchpads - -The button behavior is subject to some restrictions: - -The button area is usually defined like this: +On most clickpads, this is the default behavior. The bottom of the touchpad +is split in the middle to generate left or right button events on click. The +height of the button area depends on the hardware but is usually around +10mm. @dot digraph G { @@ -46,22 +33,48 @@ digraph G { } @enddot -The size of the buttons is hardware dependent. +Left, right and middle button events can be triggered as follows: +- if a finger is in the main area or the left button area, a click generates + left button events. +- if a finger is in the right area, a click generates right button events. +- if there is a finger in both the left and right button area, a click + generates middle button events. -- if fingers are only down in the main area, a left click is generated -- if a finger is in the right area when the physical click happens, a right - click is generated -- if fingers are in both the left and right area, a middle click is generated -- fingers in the main area are not considered for right or middle click - generation -- if a finger starts in the main area, the software buttons do not apply to - that finger -- a finger in the software button area does not move the pointer, but once it - moves out of the button area it will control the pointer (if it's the first - finger to do so) +If fingers are down in the main area in addition to fingers in the +left or right button area, those fingers are are ignored. +A release event always releases the buttons logically down, regardless of +the current finger position + +The movement of a finger can alter the button area behavior: +- if a finger starts in the main area and moves into the software button + area, the software buttons do not apply to that finger +- a finger in the software button area does not move the pointer +- if a finger moves out out of the button area it will control the pointer + if it's the first finger in the main area - once a finger has moved out of the button area, it cannot move back in and - trigger a right/middle button click -- a release event releases the buttons logically down, regardless of the - current finger position + trigger a right or middle button event -*/ \ No newline at end of file +@section clickfinger Clickfinger behavior + +This is the default behavior on Apple touchpads. +Here, a left, right, middle button event is generated when one, two, or +three fingers are held down on the touchpad when a physical click is +generated. The location of the fingers does not matter and there are no +software-defined button areas. + +The Xorg synaptics driver uses 30% of the touchpad dimensions as threshold, +libinput does not have this restriction. If two fingers are on the pad +while clicking, that is a two-finger click. + +@section special_clickpads Special Clickpads + +The Lenovo *40 series laptops have a clickpad that provides two software button sections, one at +the top and one at the bottom. See @ref t440_support "Lenovo *40 series touchpad support" +for details on the top software button. + +Some Clickpads, notably some Cypress ones, perform right button detection in +firmware and appear to userspace as if the touchpad had physical buttons. +While physically clickpads, these are not handled by the software and +treated like traditional touchpads. + +*/ diff --git a/doc/seats.dox b/doc/seats.dox index fe777606..09094508 100644 --- a/doc/seats.dox +++ b/doc/seats.dox @@ -1,6 +1,8 @@ /** @page seats Seats +Each device in libinput is associated with one physical seat and one logical seat. + @section seats_overview Overview @dotfile seats-sketch.gv diff --git a/doc/t440-support.dox b/doc/t440-support.dox index 6261ce02..277dbe8e 100644 --- a/doc/t440-support.dox +++ b/doc/t440-support.dox @@ -1,6 +1,9 @@ /** @page t440_support Lenovo *40 series touchpad support +The Lenovo *40 series emulates trackstick buttons on the top part of the +touchpads. + @section t440_support_overview Overview The Lenovo *40 series introduced a new type of touchpad. Previously, all @@ -24,43 +27,48 @@ digraph G { } @enddot -The below is a list of what is needed for support of these devices. This page -only covers the top software buttons, the bottom button behavior is covered in -@ref clickpad_softbuttons "Clickpad software buttons". +This page only covers the top software buttons, the bottom button behavior +is covered in @ref clickpad_softbuttons "Clickpad software buttons". + +Clickpads with a top button area are marked with the INPUT_PROP_TOPBUTTONPAD +property. @section t440_support_btn_size Size of the buttons -The approximate size of the top software buttons is 8% of the touchpad's -announced range, starting from the top. Note that a -kernel patch is required to -get the right ranges. +The line of the buttons is 5mm from the top edge of the touchpad, +measurements of button presses showed that the size of the buttons needs to +be approximately 10mm high to work reliable (especially when using the +thumb to press the button). -The size of the left and right buttons is approximately 42%, the middle button -is centered and should be assigned approximately 16% of the touchpad width. +The width of the left and right buttons is approximately 42% of the +touchpad's width, the middle button is centered and should be assigned +approximately 16% of the touchpad width. @section t440_support_btn_behavior Button behavior -Movement in the top button area must not generate pointer movement, these -buttons are not replacement buttons for the bottom area but have their own -behaviour. They do not work for click-and-drag. +Movement in the top button area does not generate pointer movement. These +buttons are not replacement buttons for the bottom button area but have +their own behavior. +Semantically attached to the trackstick device, libinput re-routes events +from these buttons to appear through the trackstick device. The top button +areas work even if the touchpad is disabled but will be disabled when the +trackstick device is disabled. If the finger starts inside the top area and moves outside the button area -without the physical button being down, movement may start. - -Movement into the top button area should not trigger button events, a click +the finger is treated as dead and must be lifted to generate future buttons. +Likewise, movement into the top button area does not trigger button events, a click has to start inside this area to take effect. -The top button areas must work, even if the touchpad is otherwise disabled -(e.g. by a disable-while-typing feature). +@section t440_support_identification Kernel support -@section t440_support_identification Identification +The firmware on touchpads providing top software buttons is buggy and +announces wrong ranges. Kernel +patches are required; these fixes are available in kernels +3.14.1, 3.15 and later but each touchpad needs a separate fix. -The touchpads can be identified by the PNPID, or by a DMI match - -- Helix: PnPID: LEN0033, DMI substring match "Helix" -- T540: PnPID: LEN0034, DMI substring match "T540?" -- x240: PnPID: LEN0035, DMI substring match "X240" -- T440: PnPID: LEN0036, DMI substring match "T440?" -- Yoga: PnPID: LEN0042, DMI subString match "S1Yoga" +For a complete list of supported touchpads check the +kernel source (search for "topbuttonpad_pnp_ids"). */ From 5c63a739708e48890aa931eaa55591ab08f96a82 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 22 Dec 2014 10:08:13 +1000 Subject: [PATCH 06/55] doc: move relative motion normalization page over to doc/ Signed-off-by: Peter Hutterer --- doc/Makefile.am | 1 + doc/normalization-of-relative-motion.dox | 52 ++++++++++++++++++++++++ src/libinput.h | 51 ----------------------- 3 files changed, 53 insertions(+), 51 deletions(-) create mode 100644 doc/normalization-of-relative-motion.dox diff --git a/doc/Makefile.am b/doc/Makefile.am index 30f60895..3feeb07d 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -9,6 +9,7 @@ header_files = \ $(top_srcdir)/README.txt \ $(srcdir)/absolute-axes.dox \ $(srcdir)/clickpad-softbuttons.dox \ + $(srcdir)/normalization-of-relative-motion.dox \ $(srcdir)/seats.dox \ $(srcdir)/t440-support.dox diff --git a/doc/normalization-of-relative-motion.dox b/doc/normalization-of-relative-motion.dox new file mode 100644 index 00000000..ce266e3e --- /dev/null +++ b/doc/normalization-of-relative-motion.dox @@ -0,0 +1,52 @@ +/** +@page motion_normalization Normalization of relative motion + +Most relative input devices generate input in so-called "mickeys". A +mickey is in device-specific units that depend on the resolution +of the sensor. Most optical mice use sensors with 1000dpi resolution, but +some devices range from 100dpi to well above 8000dpi. + +Without a physical reference point, a relative coordinate cannot be +interpreted correctly. A delta of 10 mickeys may be a millimeter of +physical movement or 10 millimeters, depending on the sensor. This +affects pointer acceleration in libinput and interpretation of relative +coordinates in callers. + +libinput normalizes all relative input to a physical resolution of +1000dpi, the same delta from two different devices thus represents the +same physical movement of those two devices (within sensor error +margins). + +Devices usually do not advertise their resolution and libinput relies on +the udev property MOUSE_DPI for this information. + +The format of the property for single-resolution mice is: +@code + MOUSE_DPI=resolution@frequency +@endcode + +The resolution is in dots per inch, the frequency in Hz. +The format of the property for multi-resolution mice may list multiple +resolutions and frequencies: +@code + MOUSE_DPI=r1@f1 *r2@f2 r3@f3 +@endcode + +The default frequency must be pre-fixed with an asterisk. + +For example, these two properties are valid: +@code + MOUSE_DPI=800@125 + MOUSE_DPI=400@125 800@125 *1000@500 5500@500 +@endcode + +The behavior for a malformed property is undefined. + +If the property is unset, libinput assumes the resolution is 1000dpi. + +Note that HW does not usually provide information about run-time +resolution changes, libinput will thus not detect when a resolution +changes to the non-default value. + +*/ + diff --git a/src/libinput.h b/src/libinput.h index d62516d1..4adf2177 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -132,57 +132,6 @@ extern "C" { * */ -/** - * @page motion_normalization Normalization of relative motion - * - * Most relative input devices generate input in so-called "mickeys". A - * mickey is in device-specific units that depend on the resolution - * of the sensor. Most optical mice use sensors with 1000dpi resolution, but - * some devices range from 100dpi to well above 8000dpi. - * - * Without a physical reference point, a relative coordinate cannot be - * interpreted correctly. A delta of 10 mickeys may be a millimeter of - * physical movement or 10 millimeters, depending on the sensor. This - * affects pointer acceleration in libinput and interpretation of relative - * coordinates in callers. - * - * libinput normalizes all relative input to a physical resolution of - * 1000dpi, the same delta from two different devices thus represents the - * same physical movement of those two devices (within sensor error - * margins). - * - * Devices usually do not advertise their resolution and libinput relies on - * the udev property MOUSE_DPI for this information. - * - * The format of the property for single-resolution mice is: - * @code - * MOUSE_DPI=resolution@frequency - * @endcode - * - * The resolution is in dots per inch, the frequency in Hz. - * The format of the property for multi-resolution mice may list multiple - * resolutions and frequencies: - * @code - * MOUSE_DPI=r1@f1 *r2@f2 r3@f3 - * @endcode - * - * The default frequency must be pre-fixed with an asterisk. - * - * For example, these two properties are valid: - * @code - * MOUSE_DPI=800@125 - * MOUSE_DPI=400@125 800@125 *1000@500 5500@500 - * @endcode - * - * The behavior for a malformed property is undefined. - * - * If the property is unset, libinput assumes the resolution is 1000dpi. - * - * Note that HW does not usually provide information about run-time - * resolution changes, libinput will thus not detect when a resolution - * changes to the non-default value. - */ - /** * Log priority for internal logging messages. */ From ac76a398765510198a2eabb1affcad06aad3c345 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 22 Dec 2014 10:09:27 +1000 Subject: [PATCH 07/55] doc: drop touchpad button behavior page - provided in doc/ now Signed-off-by: Peter Hutterer --- src/libinput.h | 61 -------------------------------------------------- 1 file changed, 61 deletions(-) diff --git a/src/libinput.h b/src/libinput.h index 4adf2177..f3776f3b 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -35,67 +35,6 @@ extern "C" { __attribute__ ((format (printf, _format, _args))) #define LIBINPUT_ATTRIBUTE_DEPRECATED __attribute__ ((deprecated)) -/** - * @page tpbuttons Touchpad button behavior - * - * For touchpad devices without physical buttons, libinput enables an - * emulated right button area through either of two methods. - * - * Software button areas - * ===================== - * On most touchpads, the bottom area of the touchpad is split into a left - * and a right-button area. Pressing the touchpad down with a finger in - * those areas will generate clicks as shown in the diagram below: - * - * @code - +------------------------+ - | | - | | - | LEFT | - | | - | | - +------------------------+ - | LEFT | RIGHT | - +------------------------+ - * @endcode - * - * Generally, the touchpad will emulate a right-button click if the finger - * was set down in the right button area and did not leave the - * right button area before clicking, even if another finger was already - * down on the touchpad in another area. - * A middle click is generated by clicking the touchpad when one finger is - * in the bottom left button area, and one finger is in the botton right - * button area. - * The exact behavior of the touchpad is implementation-dependent. - * - * Top software button area - * ======================== - * On selected touchpads, the top area of the touchpad is a separate set of - * software buttons split into a left, middle and right button area. - * Pressing the touchpad down with a finger in those areas will generate - * clicks as shown in the diagram below: - * - * @code - +------------------------+ - | LEFT | MIDDLE | RIGHT | - +------------------------+ - | | - | LEFT | - | | - +------------------------+ - | LEFT | RIGHT | - +------------------------+ - * @endcode - * This behavior is enabled on the Lenovo *40 series (T440, T540, T240...) - * and the Lenovo Helix, Yoga S1 and Carbon X1 2nd. - * - * Clickfinger - * =========== - * On Apple touchpads, no button areas are provided. Instead, use a - * two-finger click for a right button click, and a three-finger click for a - * middle button click. - */ - /** * @page udev_config Static device configuration via udev * From e537d84305e0c5ce7fec8a3435b43e6cf3a6d03a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 22 Dec 2014 10:11:09 +1000 Subject: [PATCH 08/55] doc: move "device configuration via udev" page to here Signed-off-by: Peter Hutterer --- doc/Makefile.am | 1 + doc/device-configuration-via-udev.dox | 35 ++++++++++++++++++++++++++ src/libinput.h | 36 --------------------------- 3 files changed, 36 insertions(+), 36 deletions(-) create mode 100644 doc/device-configuration-via-udev.dox diff --git a/doc/Makefile.am b/doc/Makefile.am index 3feeb07d..ccb790da 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -9,6 +9,7 @@ header_files = \ $(top_srcdir)/README.txt \ $(srcdir)/absolute-axes.dox \ $(srcdir)/clickpad-softbuttons.dox \ + $(srcdir)/device-configuration-via-udev.dox \ $(srcdir)/normalization-of-relative-motion.dox \ $(srcdir)/seats.dox \ $(srcdir)/t440-support.dox diff --git a/doc/device-configuration-via-udev.dox b/doc/device-configuration-via-udev.dox new file mode 100644 index 00000000..b8540351 --- /dev/null +++ b/doc/device-configuration-via-udev.dox @@ -0,0 +1,35 @@ +/** +@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: +
+
LIBINPUT_CALIBRATION_MATRIX
+
Sets the calibration matrix, see +libinput_device_config_calibration_get_default_matrix(). If unset, +defaults to the identity matrix.
+
ID_SEAT
+
Assigns the physical seat for this device. See +libinput_seat_get_physical_name(). Defaults to "seat0".
+
WL_SEAT
+
Assigns the logical seat for this device. See +libinput_seat_get_logical_name() +context. Defaults to "default".
+
MOUSE_DPI
+
HW resolution and sampling frequency of a relative pointer device. +See @ref motion_normalization for details. +
+
+ +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 + +*/ diff --git a/src/libinput.h b/src/libinput.h index f3776f3b..a6eddae9 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -35,42 +35,6 @@ extern "C" { __attribute__ ((format (printf, _format, _args))) #define LIBINPUT_ATTRIBUTE_DEPRECATED __attribute__ ((deprecated)) -/** - * @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: - *
- *
LIBINPUT_CALIBRATION_MATRIX
- *
Sets the calibration matrix, see - * libinput_device_config_calibration_get_default_matrix(). If unset, - * defaults to the identity matrix.
- *
ID_SEAT
- *
Assigns the physical seat for this device. See - * libinput_seat_get_physical_name(). Defaults to "seat0".
- *
WL_SEAT
- *
Assigns the logical seat for this device. See - * libinput_seat_get_logical_name() - * context. Defaults to "default".
- *
MOUSE_DPI
- *
HW resolution and sampling frequency of a relative pointer device. - * See @ref motion_normalization for details. - *
- *
- * - * 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. */ From d04d0c19dd9425f3394e9b4205f983a7939b6039 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 22 Dec 2014 10:33:55 +1000 Subject: [PATCH 09/55] doc: improve seat documentation Signed-off-by: Peter Hutterer --- doc/Makefile.am | 3 +- doc/dot/seats-sketch-libinput.gv | 29 ++++++++++++++ doc/dot/seats-sketch.gv | 18 +++++++-- doc/seats.dox | 67 ++++++++++++++++++++++++++++++-- src/libinput.h | 25 ++---------- 5 files changed, 113 insertions(+), 29 deletions(-) create mode 100644 doc/dot/seats-sketch-libinput.gv diff --git a/doc/Makefile.am b/doc/Makefile.am index ccb790da..28933384 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -15,7 +15,8 @@ header_files = \ $(srcdir)/t440-support.dox diagram_files = \ - $(srcdir)/dot/seats-sketch.gv + $(srcdir)/dot/seats-sketch.gv \ + $(srcdir)/dot/seats-sketch-libinput.gv html/index.html: libinput.doxygen $(header_files) $(diagram_files) $(AM_V_GEN)(cat $<; \ diff --git a/doc/dot/seats-sketch-libinput.gv b/doc/dot/seats-sketch-libinput.gv new file mode 100644 index 00000000..b0216563 --- /dev/null +++ b/doc/dot/seats-sketch-libinput.gv @@ -0,0 +1,29 @@ +digraph seats_libinput +{ + rankdir="BT"; + node [ + shape="box"; + ] + + ctx1 [label="libinput context 1"; URL="\ref libinput"]; + ctx2 [label="libinput context 2"; URL="\ref libinput"]; + + seat0 [ label="seat phys 0 logical A"]; + seat1 [ label="seat phys 0 logical B"]; + seat2 [ label="seat phys 1 logical C"]; + + dev1 [label="device 'Foo'"]; + dev2 [label="device 'Bar'"]; + dev3 [label="device 'Spam'"]; + dev4 [label="device 'Egg'"]; + + ctx1 -> dev1 + ctx1 -> dev2 + ctx1 -> dev3 + ctx2 -> dev4 + + dev1 -> seat0 + dev2 -> seat0 + dev3 -> seat1 + dev4 -> seat2 +} diff --git a/doc/dot/seats-sketch.gv b/doc/dot/seats-sketch.gv index f537df1a..3647cef8 100644 --- a/doc/dot/seats-sketch.gv +++ b/doc/dot/seats-sketch.gv @@ -15,13 +15,18 @@ digraph seats pseat0 [label="phys seat0"; URL="\ref libinput_seat_get_physical_name"]; pseat1 [label="phys seat1"; URL="\ref libinput_seat_get_physical_name"]; - lseatA [label="log seat A"; URL="\ref libinput_seat_get_logical_name"]; - lseatB [label="log seat B"; URL="\ref libinput_seat_get_logical_name"]; - lseatC [label="log seat C"; URL="\ref libinput_seat_get_logical_name"]; + lseatA [label="logical seat A"; URL="\ref libinput_seat_get_logical_name"]; + lseatB [label="logical seat B"; URL="\ref libinput_seat_get_logical_name"]; + lseatC [label="logical seat C"; URL="\ref libinput_seat_get_logical_name"]; ctx1 [label="libinput context 1"; URL="\ref libinput"]; ctx2 [label="libinput context 2"; URL="\ref libinput"]; + dev1 [label="device 'Foo'"]; + dev2 [label="device 'Bar'"]; + dev3 [label="device 'Spam'"]; + dev4 [label="device 'Egg'"]; + kernel -> event0 kernel -> event1 kernel -> event2 @@ -38,4 +43,9 @@ digraph seats ctx1 -> lseatA ctx1 -> lseatB ctx2 -> lseatC -} \ No newline at end of file + + lseatA -> dev1 + lseatA -> dev2 + lseatB -> dev3 + lseatC -> dev4 +} diff --git a/doc/seats.dox b/doc/seats.dox index 09094508..5eec5ded 100644 --- a/doc/seats.dox +++ b/doc/seats.dox @@ -1,12 +1,73 @@ /** @page seats Seats -Each device in libinput is associated with one physical seat and one logical seat. +Each device in libinput is assigned to one seat. +A seat has two identifiers, the physical name and the logical name. The +physical name is summarized as the list of devices a process on the same +physical seat has access to. The logical seat name is the seat name for a +logical group of devices. A compositor may use that to create additonal +seats as independent device sets. Alternatively, a compositor may limit +itself to a single logical seat, leaving a second compositor to manage +devices on the other logical seats. -@section seats_overview Overview +@section Overview + +Below is an illustration of how physical seats and logical seats interact: @dotfile seats-sketch.gv -Details pending. +The devices "Foo", "Bar" and "Spam" share the same physical seat and are +thus available in the same libinput context. Only "Foo" and "Bar" share the +same logical seat. The device "Egg" is not available in the libinput context +associated with the physical seat 0. + +The above graph is for illustration purposes only. In libinput, a struct +@ref libinput_seat comprises both physical seat and logical seat. From a +caller's point-of-view the above device layout is presented as: + +@dotfile seats-sketch-libinput.gv + +Thus, devices "Foo" and "Bar" both reference the same struct @ref +libinput_seat, all other devices reference their own respective seats. + +@section seats_and_features The effect of seat assignment + +A logical set is interprested as a group of devices that usually belong to a +single user that interacts with a computer. Thus, the devices are +semantically related. This means for devices within the same logical seat: + +- if the same button is pressed on different devices, the button should only + be considered logically pressed once. +- if the same button is released on one device, the button should be + considered logically down if still down on another device. +- if two different buttons or keys are pressed on different devices, the + logical state is that of both buttons/keys down. +- if a button is pressed on one device and another device moves, this should + count as dragging. +- if two touches are down on different devices, the logical state is that of + two touches down. + +libinput provides functions to aid with the above: +libinput_event_pointer_get_seat_button_count(), +libinput_event_keyboard_get_seat_key_count(), and +libinput_event_touch_get_seat_slot(). + +Internally, libinput counts devices within the same logical seat as related. +Cross-device features only activate if all required devices are in the same +logical seat. For example, libinput will only activate the top software +buttons (see @ref t440_support) if both trackstick and touchpad are assigned +to the same logical seat. + + +@section changing_seats Changing seats + +A device may change the logical seat it is assigned to at runtime with +libinput_device_set_seat_logical_name(). The physical seat is immutable and +may not be changed. + +Changing the logical seat for a device is equivalent to unplugging the +device and plugging it back in with the new logical seat. No device state +carries over across a logical seat change. + */ diff --git a/src/libinput.h b/src/libinput.h index a6eddae9..e156a3a0 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -1139,27 +1139,10 @@ libinput_log_set_handler(struct libinput *libinput, /** * @defgroup seat Initialization and manipulation of seats * - * A seat has two identifiers, the physical name and the logical name. The - * physical name is summarized as the list of devices a process on the same - * physical seat has access to. - * - * The logical seat name is the seat name for a logical group of devices. A - * compositor may use that to create additonal seats as independent device - * sets. Alternatively, a compositor may limit itself to a single logical - * seat, leaving a second compositor to manage devices on the other logical - * seats. - * - * @code - * +---+--------+------------+------------------------+------------+ - * | | event0 | | | log seat A | - * | K +--------+ | +------------+ - * | e | event1 | phys seat0 | libinput context 1 | | - * | r +--------+ | | log seat B | - * | n | event2 | | | | - * | e +--------+------------+------------------------+------------+ - * | l | event3 | phys seat1 | libinput context 2 | log seat C | - * +---+--------+------------+------------------------+------------+ - * @endcode + * A seat has two identifiers, the physical name and the logical name. A + * device is always assigned to exactly one seat. It may change to a + * different logical seat but it cannot change physical seats. See @ref + * seats for details. */ /** From ba3166c1137bffd6891a84b6610c107000898208 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 22 Dec 2014 12:11:46 +1000 Subject: [PATCH 10/55] doc: document the calibration as well Requires MathJax for client-side, but that's an easy dependency to accept and better than requiring Latex to build the documentation. Signed-off-by: Peter Hutterer --- doc/absolute-axes.dox | 68 +++++++++++++++++++++++++++++++++++++++++ doc/libinput.doxygen.in | 2 +- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/doc/absolute-axes.dox b/doc/absolute-axes.dox index f1ff973b..7d205f62 100644 --- a/doc/absolute-axes.dox +++ b/doc/absolute-axes.dox @@ -44,6 +44,74 @@ buggy and must be fixed in the kernel. Some touchpad devices that do not provide resolution, those devices are correctly handled within libinput (touchpads are not absolute devices, as mentioned above). +@section calibration Calibration of absolute devices + +Absolute devices may require calibration to map precisely into the output +range required. This is done by setting a transformation matrix, see +libinput_device_config_calibration_set_matrix() which is applied to +each input coordinate. + +@f[ +\begin{pmatrix} + cos\theta & -sin\theta & xoff \\ + sin\theta & cos\theta & yoff \\ + 0 & 0 & 1 +\end{pmatrix} \begin{pmatrix} +x \\ y \\ 1 +\end{pmatrix} +@f] + +@f$\theta@f$ is the rotation angle. The offsets @f$xoff@f$ and @f$yoff@f$ are +specified in device dimensions, i.e. a value of 1 equals one device width +or height. Note that rotation applies to the device's origin, rotation +usually requires an offset to move the coordinates back into the original +range. + +The most comon matrices are: + +- 90 degree clockwise: +@f$ +\begin{pmatrix} + 0 & -1 & 1 \\ + 1 & 0 & 0 \\ + 0 & 0 & 1 +\end{pmatrix} +@f$ + +- 180 degree clockwise: +@f$ +\begin{pmatrix} + -1 & 0 & 1 \\ + 0 & -1 & 1 \\ + 0 & 0 & 1 +\end{pmatrix} +@f$ + +- 270 degree clockwise: +@f$ +\begin{pmatrix} + 0 & 1 & 0 \\ + -1 & 0 & 1 \\ + 0 & 0 & 1 +\end{pmatrix} +@f$ + +- reflection along y axis: +@f$ +\begin{pmatrix} + -1 & 0 & 1 \\ + 1 & 0 & 0 \\ + 0 & 0 & 1 +\end{pmatrix} +@f$ + +See Wikipedia's +Transformation +Matrix article for more information on the matrix maths. + +See libinput_device_config_calibration_get_default_matrix() for how these +matrices must be supplied to libinput. + @section absolute_axes_nonorm Why x/y coordinates are not normalized x/y are not given in @ref motion_normalization "normalized coordinates" diff --git a/doc/libinput.doxygen.in b/doc/libinput.doxygen.in index 9800f808..4d2a0abf 100644 --- a/doc/libinput.doxygen.in +++ b/doc/libinput.doxygen.in @@ -1421,7 +1421,7 @@ FORMULA_TRANSPARENT = YES # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -USE_MATHJAX = NO +USE_MATHJAX = YES # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: From 700ec897eb6f0fee479905898dd440417c851549 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 23 Dec 2014 08:15:00 +1000 Subject: [PATCH 11/55] doc: add link to udev hwdb in rel motion normalization doc Signed-off-by: Peter Hutterer --- doc/normalization-of-relative-motion.dox | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/normalization-of-relative-motion.dox b/doc/normalization-of-relative-motion.dox index ce266e3e..aaa1735f 100644 --- a/doc/normalization-of-relative-motion.dox +++ b/doc/normalization-of-relative-motion.dox @@ -18,7 +18,9 @@ same physical movement of those two devices (within sensor error margins). Devices usually do not advertise their resolution and libinput relies on -the udev property MOUSE_DPI for this information. +the udev property MOUSE_DPI for this information. This property is usually +set via the udev hwdb. The format of the property for single-resolution mice is: @code From 169fdadd82b59f35f803718427fbca0b48eac454 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 23 Dec 2014 09:24:33 +1000 Subject: [PATCH 12/55] doc: move the wiki's scrolling documentation to here Signed-off-by: Peter Hutterer --- doc/Makefile.am | 6 +- doc/libinput.doxygen.in | 2 +- doc/scrolling.dox | 50 ++++++ doc/svg/button-scrolling.svg | 292 ++++++++++++++++++++++++++++++++ doc/svg/edge-scrolling.svg | 126 ++++++++++++++ doc/svg/twofinger-scrolling.svg | 165 ++++++++++++++++++ 6 files changed, 639 insertions(+), 2 deletions(-) create mode 100644 doc/scrolling.dox create mode 100644 doc/svg/button-scrolling.svg create mode 100644 doc/svg/edge-scrolling.svg create mode 100644 doc/svg/twofinger-scrolling.svg diff --git a/doc/Makefile.am b/doc/Makefile.am index 28933384..5c22d776 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -11,12 +11,16 @@ header_files = \ $(srcdir)/clickpad-softbuttons.dox \ $(srcdir)/device-configuration-via-udev.dox \ $(srcdir)/normalization-of-relative-motion.dox \ + $(srcdir)/scrolling.dox \ $(srcdir)/seats.dox \ $(srcdir)/t440-support.dox diagram_files = \ $(srcdir)/dot/seats-sketch.gv \ - $(srcdir)/dot/seats-sketch-libinput.gv + $(srcdir)/dot/seats-sketch-libinput.gv \ + $(srcdir)/svg/button-scrolling.svg \ + $(srcdir)/svg/edge-scrolling.svg \ + $(srcdir)/svg/twofinger-scrolling.svg html/index.html: libinput.doxygen $(header_files) $(diagram_files) $(AM_V_GEN)(cat $<; \ diff --git a/doc/libinput.doxygen.in b/doc/libinput.doxygen.in index 4d2a0abf..8fb045e8 100644 --- a/doc/libinput.doxygen.in +++ b/doc/libinput.doxygen.in @@ -842,7 +842,7 @@ EXAMPLE_RECURSIVE = NO # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = +IMAGE_PATH = svg # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program diff --git a/doc/scrolling.dox b/doc/scrolling.dox new file mode 100644 index 00000000..3ded909d --- /dev/null +++ b/doc/scrolling.dox @@ -0,0 +1,50 @@ +/** +@page scrolling Scrolling + +libinput supports three different types of scrolling behavior. + +@section twofinger_scrolling Two-finger scrolling + +The default on two-finger capable touchpads (almost all modern touchpads are +capable of detecting two fingers). Scrolling is triggered by two fingers +being placed on the surface of the touchpad, then moving those fingers +vertically or horizontally. + +@image html twofinger-scrolling.svg "Vertical and horizontal two-finger scrolling" + +For scrolling to trigger, a built-in distance threshold has to be met but once +engaged any movement will scroll. In other words, to start scrolling a +sufficiently large movement is required, once scrolling tiny amounts of +movements will translate into tiny scroll movements. + +Scrolling in both directions at once is possible by meeting the required +distance thresholds to enable each direction separately. + +@section edge_scrolling Edge scrolling + +On some touchpads, edge scrolling is available, triggered by moving a single +finger along the right edge (vertical scroll) or bottom edge (horizontal +scroll). + +@image html edge-scrolling.svg "Vertical and horizontal edge scrolling" + +Due to the layout of the edges, diagonal scrolling is not possible. + +Edge scrolling conflicts with @ref clickpad_softbuttons and is +not usually available on clickpads. + +@section button_scrolling On-Button scrolling + +Scrolling when a button is held down is available on selected devices. The +motion of a device is converted into scrolling motion. + +For example, Lenovo devices provide a +pointing stick that emulates +scroll events when the trackstick's middle mouse button is held down. + +@image html button-scrolling.svg "Button scrolling" + +Note that libinput's @ref t440_support enables the use of the middle +button for button scrolling (even when the touchpad is disabled). + +*/ diff --git a/doc/svg/button-scrolling.svg b/doc/svg/button-scrolling.svg new file mode 100644 index 00000000..476c9c7d --- /dev/null +++ b/doc/svg/button-scrolling.svg @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C + V + B + N + M + J + H + G + F + + + + + + + + + + + + + + + + + + + + diff --git a/doc/svg/edge-scrolling.svg b/doc/svg/edge-scrolling.svg new file mode 100644 index 00000000..cba72c50 --- /dev/null +++ b/doc/svg/edge-scrolling.svg @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/svg/twofinger-scrolling.svg b/doc/svg/twofinger-scrolling.svg new file mode 100644 index 00000000..e182a7fe --- /dev/null +++ b/doc/svg/twofinger-scrolling.svg @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 174364580d1f8006dba4c8412573f4a8f9d1a447 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 23 Dec 2014 09:32:37 +1000 Subject: [PATCH 13/55] doc: move the wiki's tapping documentation to here Signed-off-by: Peter Hutterer --- doc/Makefile.am | 3 ++- doc/tapping.dox | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 doc/tapping.dox diff --git a/doc/Makefile.am b/doc/Makefile.am index 5c22d776..746418a6 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -13,7 +13,8 @@ header_files = \ $(srcdir)/normalization-of-relative-motion.dox \ $(srcdir)/scrolling.dox \ $(srcdir)/seats.dox \ - $(srcdir)/t440-support.dox + $(srcdir)/t440-support.dox \ + $(srcdir)/tapping.dox diagram_files = \ $(srcdir)/dot/seats-sketch.gv \ diff --git a/doc/tapping.dox b/doc/tapping.dox new file mode 100644 index 00000000..f603b7d5 --- /dev/null +++ b/doc/tapping.dox @@ -0,0 +1,48 @@ +/** +@page tapping Tap-to-click behaviour + +"Tapping" or "tap-to-click" is the name given to the behavior where a short +finger touch down/up sequence maps into a button click. This is most +commonly used on touchpads, but may be available on other devices. + +libinput implements tapping for one, two, and three fingers, where supported +by the hardware, and maps those taps into a left, right, and middle button +click, respectively. Not all devices support three fingers, libinput will +support tapping up to whatever is supported by the hardware. libinput does +not support four-finger taps or any tapping with more than four fingers, +even though some hardware can distinguish between that many fingers. + +Tapping is **disabled** by default, see [this +commit](http://cgit.freedesktop.org/wayland/libinput/commit/?id=2219c12c3aa45b80f235e761e87c17fb9ec70eae) +because: +- if you don't know that tapping is a thing (or enabled by default), you get + spurious button events that make the desktop feel buggy. +- if you do know what tapping is and you want it, you usually know where to + enable it, or at least you can search for it. + +Tapping can be enabled on a per-device basis. See +libinput_device_config_tap_set_enabled() for details. + +@section tapndrag Tap-and-drag + +libinput also supports "tap-and-drag" where a tap immediately followed by a +finger down and that finger being held down emulates a button press. Moving +the finger around can thus drag the selected item on the screen. Lifting the +finger and putting it back down immediately (i.e. within the timeout) will +continue the dragging process, so that multiple touchpad-widths of distance +can be covered easily. If two-fingers are supported by the hardware, a +second finger can be used to drag while the first is held in-place. + +@section tap_constraints Constraints while tapping + +A couple of constraints apply to the contact to be converted into a press, the most common ones are: +- the touch down and touch up must happen within an implementation-defined timeout +- if a finger moves more than an implementation-defined distance while in contact, it's not a tap +- tapping within @ref clickpad_softbuttons "clickpad software buttons" may not trigger an event +- a tap not meeting required pressure thresholds can be ignored as accidental touch +- a tap exceeding certain pressure thresholds can be ignored (see @ref + palm_detection) +- a tap on the edges of the touchpad can usually be ignored (see @ref + palm_detection) + +*/ From 380137ca29b992be857f67c99f60bbeb11146fd7 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 23 Dec 2014 09:47:39 +1000 Subject: [PATCH 14/55] doc: move the wiki's palm detection docs to here Signed-off-by: Peter Hutterer --- doc/Makefile.am | 2 + doc/palm-detection.dox | 52 ++++++++++++++++ doc/svg/palm-detection.svg | 122 +++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 doc/palm-detection.dox create mode 100644 doc/svg/palm-detection.svg diff --git a/doc/Makefile.am b/doc/Makefile.am index 746418a6..b4b5d542 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -11,6 +11,7 @@ header_files = \ $(srcdir)/clickpad-softbuttons.dox \ $(srcdir)/device-configuration-via-udev.dox \ $(srcdir)/normalization-of-relative-motion.dox \ + $(srcdir)/palm-detection.dox \ $(srcdir)/scrolling.dox \ $(srcdir)/seats.dox \ $(srcdir)/t440-support.dox \ @@ -21,6 +22,7 @@ diagram_files = \ $(srcdir)/dot/seats-sketch-libinput.gv \ $(srcdir)/svg/button-scrolling.svg \ $(srcdir)/svg/edge-scrolling.svg \ + $(srcdir)/svg/palm-detection.svg \ $(srcdir)/svg/twofinger-scrolling.svg html/index.html: libinput.doxygen $(header_files) $(diagram_files) diff --git a/doc/palm-detection.dox b/doc/palm-detection.dox new file mode 100644 index 00000000..4e839e62 --- /dev/null +++ b/doc/palm-detection.dox @@ -0,0 +1,52 @@ +/** +@page palm_detection Palm detection + +Palm detection tries to identify accidental touches while typing. + +On most laptops typing on the keyboard generates accidental touches on the +touchpad with the palm (usually the area below the thumb). This can lead to +cursor jumps or accidental clicks. + +Interference from a palm depends on the size of the touchpad and the position +of the user's hand. Data from touchpads showed that almost all palm events on a +Lenovo T440 happened in the left-most and right-most 5% of the touchpad. The +T440 series has one of the largest touchpads, other touchpads are less +affected by palm touches. + +@section palm_exclusion_zones Palm exclusion zones + +libinput enables palm detection on the edge of the touchpad. Two exclusion +zones are defined on the left and right edge of the touchpad. +If a touch starts in the exclusion zone, it is considered a palm and the +touch point is ignored. However, for fast cursor movements across the +screen, it is common for a finger to start inside an exclusion zone and move +rapidly across the touchpad. libinput detects such movements and avoids palm +detection on such touch sequences. + +In the diagram below, the exclusion zones are painted red. +Touch 'A' starts inside the exclusion zone and moves +almost vertically. It is considered a palm and ignored for cursor movement, +despite moving out of the exclusion zone. + +Touch 'B' starts inside the exclusion zone but moves horizontally out of the +zone. It is considered a valid touch and controls the cursor. + +@image html palm-detection.svg + +@section trackpoint-disabling Palm detection during trackpoint use + +If a device provides a trackpoint, it is +usually located above the touchpad. This increases the likelyhood of +accidental touches whenever the trackpoint is used. + +libinput disables the touchpad whenver it detects trackpoint activity for a +certain timeout until after trackpoint activity stops. Touches generated +during this timeout will not move the pointer, and touches started during +this timeout will likewise not move the pointer (allowing for a user to rest +the palm on the touchpad while using the trackstick). +If the touchpad is disabled, the @ref t440_support "top software buttons" +remain enabled. + + +*/ diff --git a/doc/svg/palm-detection.svg b/doc/svg/palm-detection.svg new file mode 100644 index 00000000..9fb6077d --- /dev/null +++ b/doc/svg/palm-detection.svg @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + A + B + + + + From 93a2cb21e0fef6ac8fe86c0250722a1dabc37fae Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 12:56:14 +1000 Subject: [PATCH 15/55] tools: make event-debug's option parsing more flexible We need to be able to turn config options on/off for testing, so switch to something that's a bit more flexible than characters that represent the options. Signed-off-by: Peter Hutterer --- tools/event-debug.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/tools/event-debug.c b/tools/event-debug.c index 3e4981b1..1be3e146 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -61,6 +61,13 @@ usage(void) program_invocation_short_name); } +enum options { + OPT_DEVICE, + OPT_UDEV, + OPT_HELP, + OPT_VERBOSE, +}; + static int parse_args(int argc, char **argv) { @@ -68,10 +75,10 @@ parse_args(int argc, char **argv) int c; int option_index = 0; static struct option opts[] = { - { "device", 1, 0, 'd' }, - { "udev", 0, 0, 'u' }, - { "help", 0, 0, 'h' }, - { "verbose", 0, 0, 'v'}, + { "device", 1, 0, OPT_DEVICE }, + { "udev", 0, 0, OPT_UDEV }, + { "help", 0, 0, OPT_HELP }, + { "verbose", 0, 0, OPT_VERBOSE }, { 0, 0, 0, 0} }; @@ -81,9 +88,10 @@ parse_args(int argc, char **argv) switch(c) { case 'h': /* --help */ + case OPT_HELP: usage(); exit(0); - case 'd': /* --device */ + case OPT_DEVICE: /* --device */ mode = MODE_DEVICE; if (!optarg) { usage(); @@ -91,12 +99,12 @@ parse_args(int argc, char **argv) } device = optarg; break; - case 'u': /* --udev */ + case OPT_UDEV: /* --udev */ mode = MODE_UDEV; if (optarg) seat = optarg; break; - case 'v': /* --verbose */ + case OPT_VERBOSE: /* --verbose */ verbose = 1; break; default: From bc6925d6c212f5ae528f983dc7609e39da57b63e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 13:04:50 +1000 Subject: [PATCH 16/55] tools: add --enable-tap to event-debug Signed-off-by: Peter Hutterer --- tools/event-debug.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/tools/event-debug.c b/tools/event-debug.c index 1be3e146..b6b71401 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -48,16 +48,26 @@ uint32_t start_time; static const uint32_t screen_width = 100; static const uint32_t screen_height = 100; static int verbose = 0; +static int tapping = -1; static void usage(void) { - printf("Usage: %s [--verbose] [--udev []|--device /dev/input/event0]\n" - "--verbose ....... Print debugging output.\n" - "--help .......... Print this help.\n" + printf("Usage: %s [options] [--udev []|--device /dev/input/event0]\n" "--udev .... Use udev device discovery (default).\n" " Specifying a seat ID is optional.\n" - "--device /path/to/device .... open the given device only\n", + "--device /path/to/device .... open the given device only\n" + "\n" + "Features:\n" + "--enable-tap\n" + "--disable-tap.... enable/disable tapping\n" + "\n" + "These options apply to all applicable devices, if a feature\n" + "is not explicitly specified it is left at each device's default.\n" + "\n" + "Other options:\n" + "--verbose ....... Print debugging output.\n" + "--help .......... Print this help.\n", program_invocation_short_name); } @@ -66,6 +76,8 @@ enum options { OPT_UDEV, OPT_HELP, OPT_VERBOSE, + OPT_TAP_ENABLE, + OPT_TAP_DISABLE, }; static int @@ -79,6 +91,8 @@ parse_args(int argc, char **argv) { "udev", 0, 0, OPT_UDEV }, { "help", 0, 0, OPT_HELP }, { "verbose", 0, 0, OPT_VERBOSE }, + { "enable-tap", 0, 0, OPT_TAP_ENABLE }, + { "disable-tap", 0, 0, OPT_TAP_DISABLE }, { 0, 0, 0, 0} }; @@ -107,6 +121,12 @@ parse_args(int argc, char **argv) case OPT_VERBOSE: /* --verbose */ verbose = 1; break; + case OPT_TAP_ENABLE: + tapping = 1; + break; + case OPT_TAP_DISABLE: + tapping = 0; + break; default: usage(); return 1; @@ -404,6 +424,13 @@ print_touch_event_with_coords(struct libinput_event *ev) xmm, ymm); } +static void +setup_device(struct libinput_device *device) +{ + if (tapping != -1) + libinput_device_config_tap_set_enabled(device, tapping); +} + static int handle_and_print_events(struct libinput *li) { @@ -420,6 +447,7 @@ handle_and_print_events(struct libinput *li) case LIBINPUT_EVENT_DEVICE_ADDED: case LIBINPUT_EVENT_DEVICE_REMOVED: print_device_notify(ev); + setup_device(libinput_event_get_device(ev)); break; case LIBINPUT_EVENT_KEYBOARD_KEY: print_key_event(ev); From e205615c9817caf3e9bb0f97c1da80ca6569d7f2 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 14:42:42 +1000 Subject: [PATCH 17/55] tools: move option parsing to a helper library event-debug and event-gui can and should share this Signed-off-by: Peter Hutterer --- tools/Makefile.am | 8 ++- tools/event-debug.c | 121 +++++----------------------------------- tools/shared.c | 133 ++++++++++++++++++++++++++++++++++++++++++++ tools/shared.h | 45 +++++++++++++++ 4 files changed, 198 insertions(+), 109 deletions(-) create mode 100644 tools/shared.c create mode 100644 tools/shared.h diff --git a/tools/Makefile.am b/tools/Makefile.am index aadd874a..6dd64c94 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,10 +1,16 @@ noinst_PROGRAMS = event-debug +noinst_LTLIBRARIES = libshared.la AM_CPPFLAGS = -I$(top_srcdir)/include \ -I$(top_srcdir)/src + +libshared_la_SOURCES = \ + shared.c \ + shared.h + event_debug_SOURCES = event-debug.c -event_debug_LDADD = ../src/libinput.la $(LIBUDEV_LIBS) +event_debug_LDADD = ../src/libinput.la libshared.la $(LIBUDEV_LIBS) event_debug_LDFLAGS = -no-install event_debug_CFLAGS = $(LIBUDEV_CFLAGS) diff --git a/tools/event-debug.c b/tools/event-debug.c index b6b71401..184c68fc 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -23,7 +23,6 @@ #define _GNU_SOURCE #include #include -#include #include #include #include @@ -37,110 +36,14 @@ #include -static enum { - MODE_UDEV, - MODE_DEVICE, -} mode = MODE_UDEV; +#include "shared.h" + static const char *device; -static const char *seat = "seat0"; static struct udev *udev; uint32_t start_time; static const uint32_t screen_width = 100; static const uint32_t screen_height = 100; -static int verbose = 0; -static int tapping = -1; - -static void -usage(void) -{ - printf("Usage: %s [options] [--udev []|--device /dev/input/event0]\n" - "--udev .... Use udev device discovery (default).\n" - " Specifying a seat ID is optional.\n" - "--device /path/to/device .... open the given device only\n" - "\n" - "Features:\n" - "--enable-tap\n" - "--disable-tap.... enable/disable tapping\n" - "\n" - "These options apply to all applicable devices, if a feature\n" - "is not explicitly specified it is left at each device's default.\n" - "\n" - "Other options:\n" - "--verbose ....... Print debugging output.\n" - "--help .......... Print this help.\n", - program_invocation_short_name); -} - -enum options { - OPT_DEVICE, - OPT_UDEV, - OPT_HELP, - OPT_VERBOSE, - OPT_TAP_ENABLE, - OPT_TAP_DISABLE, -}; - -static int -parse_args(int argc, char **argv) -{ - while (1) { - int c; - int option_index = 0; - static struct option opts[] = { - { "device", 1, 0, OPT_DEVICE }, - { "udev", 0, 0, OPT_UDEV }, - { "help", 0, 0, OPT_HELP }, - { "verbose", 0, 0, OPT_VERBOSE }, - { "enable-tap", 0, 0, OPT_TAP_ENABLE }, - { "disable-tap", 0, 0, OPT_TAP_DISABLE }, - { 0, 0, 0, 0} - }; - - c = getopt_long(argc, argv, "h", opts, &option_index); - if (c == -1) - break; - - switch(c) { - case 'h': /* --help */ - case OPT_HELP: - usage(); - exit(0); - case OPT_DEVICE: /* --device */ - mode = MODE_DEVICE; - if (!optarg) { - usage(); - return 1; - } - device = optarg; - break; - case OPT_UDEV: /* --udev */ - mode = MODE_UDEV; - if (optarg) - seat = optarg; - break; - case OPT_VERBOSE: /* --verbose */ - verbose = 1; - break; - case OPT_TAP_ENABLE: - tapping = 1; - break; - case OPT_TAP_DISABLE: - tapping = 0; - break; - default: - usage(); - return 1; - } - - } - - if (optind < argc) { - usage(); - return 1; - } - - return 0; -} +struct tools_options options; static int open_restricted(const char *path, int flags, void *user_data) @@ -184,12 +87,12 @@ open_udev(struct libinput **li) return 1; } - if (verbose) { + if (options.verbose) { libinput_log_set_handler(*li, log_handler); libinput_log_set_priority(*li, LIBINPUT_LOG_PRIORITY_DEBUG); } - if (libinput_udev_assign_seat(*li, seat)) { + if (libinput_udev_assign_seat(*li, options.seat)) { fprintf(stderr, "Failed to set seat\n"); libinput_unref(*li); return 1; @@ -209,7 +112,7 @@ open_device(struct libinput **li, const char *path) return 1; } - if (verbose) { + if (options.verbose) { libinput_log_set_handler(*li, log_handler); libinput_log_set_priority(*li, LIBINPUT_LOG_PRIORITY_DEBUG); } @@ -427,8 +330,8 @@ print_touch_event_with_coords(struct libinput_event *ev) static void setup_device(struct libinput_device *device) { - if (tapping != -1) - libinput_device_config_tap_set_enabled(device, tapping); + if (options.tapping != -1) + libinput_device_config_tap_set_enabled(device, options.tapping); } static int @@ -532,13 +435,15 @@ main(int argc, char **argv) struct libinput *li; struct timespec tp; - if (parse_args(argc, argv)) + tools_init_options(&options); + + if (tools_parse_args(argc, argv, &options)) return 1; - if (mode == MODE_UDEV) { + if (options.backend == BACKEND_UDEV) { if (open_udev(&li)) return 1; - } else if (mode == MODE_DEVICE) { + } else if (options.backend == BACKEND_DEVICE) { if (open_device(&li, device)) return 1; } else diff --git a/tools/shared.c b/tools/shared.c new file mode 100644 index 00000000..17a96732 --- /dev/null +++ b/tools/shared.c @@ -0,0 +1,133 @@ +/* + * 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. + */ + +#define _GNU_SOURCE +#include + +#include +#include +#include +#include +#include + +#include "shared.h" + +enum options { + OPT_DEVICE, + OPT_UDEV, + OPT_HELP, + OPT_VERBOSE, + OPT_TAP_ENABLE, + OPT_TAP_DISABLE, +}; + +void +tools_usage() +{ + printf("Usage: %s [options] [--udev []|--device /dev/input/event0]\n" + "--udev .... Use udev device discovery (default).\n" + " Specifying a seat ID is optional.\n" + "--device /path/to/device .... open the given device only\n" + "\n" + "Features:\n" + "--enable-tap\n" + "--disable-tap.... enable/disable tapping\n" + "\n" + "These options apply to all applicable devices, if a feature\n" + "is not explicitly specified it is left at each device's default.\n" + "\n" + "Other options:\n" + "--verbose ....... Print debugging output.\n" + "--help .......... Print this help.\n", + program_invocation_short_name); +} + +void +tools_init_options(struct tools_options *options) +{ + memset(options, 0, sizeof(*options)); + options->tapping = -1; + options->backend = BACKEND_UDEV; + options->seat = "seat0"; +} + +int +tools_parse_args(int argc, char **argv, struct tools_options *options) +{ + while (1) { + int c; + int option_index = 0; + static struct option opts[] = { + { "device", 1, 0, OPT_DEVICE }, + { "udev", 0, 0, OPT_UDEV }, + { "help", 0, 0, OPT_HELP }, + { "verbose", 0, 0, OPT_VERBOSE }, + { "enable-tap", 0, 0, OPT_TAP_ENABLE }, + { "disable-tap", 0, 0, OPT_TAP_DISABLE }, + { 0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "h", opts, &option_index); + if (c == -1) + break; + + switch(c) { + case 'h': /* --help */ + case OPT_HELP: + tools_usage(); + exit(0); + case OPT_DEVICE: /* --device */ + options->backend = BACKEND_DEVICE; + if (!optarg) { + tools_usage(); + return 1; + } + options->device = optarg; + break; + case OPT_UDEV: /* --udev */ + options->backend = BACKEND_UDEV; + if (optarg) + options->seat = optarg; + break; + case OPT_VERBOSE: /* --verbose */ + options->verbose = 1; + break; + case OPT_TAP_ENABLE: + options->tapping = 1; + break; + case OPT_TAP_DISABLE: + options->tapping = 0; + break; + default: + tools_usage(); + return 1; + } + + } + + if (optind < argc) { + tools_usage(); + return 1; + } + + return 0; +} diff --git a/tools/shared.h b/tools/shared.h new file mode 100644 index 00000000..fa7c5efe --- /dev/null +++ b/tools/shared.h @@ -0,0 +1,45 @@ +/* + * 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. + */ + +#ifndef _SHARED_H_ +#define _SHARED_H_ + +enum tools_backend { + BACKEND_DEVICE, + BACKEND_UDEV +}; + +struct tools_options { + enum tools_backend backend; + const char *device; /* if backend is BACKEND_DEVICE */ + const char *seat; /* if backend is BACKEND_UDEV */ + + int verbose; + int tapping; +}; + +void tools_init_options(struct tools_options *options); +int tools_parse_args(int argc, char **argv, struct tools_options *options); + +void tools_usage(); + +#endif From 3628f7016e3c457b0384549c3f4fe9299002f6a0 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 15:02:45 +1000 Subject: [PATCH 18/55] tools: move opening the backend to the shared lib too Signed-off-by: Peter Hutterer --- tools/event-debug.c | 79 ++------------------------------------- tools/shared.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ tools/shared.h | 4 ++ 3 files changed, 98 insertions(+), 76 deletions(-) diff --git a/tools/event-debug.c b/tools/event-debug.c index 184c68fc..b8be215d 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -38,8 +38,6 @@ #include "shared.h" -static const char *device; -static struct udev *udev; uint32_t start_time; static const uint32_t screen_width = 100; static const uint32_t screen_height = 100; @@ -63,70 +61,6 @@ static const struct libinput_interface interface = { .close_restricted = close_restricted, }; -static void -log_handler(struct libinput *li, - enum libinput_log_priority priority, - const char *format, - va_list args) -{ - vprintf(format, args); -} - -static int -open_udev(struct libinput **li) -{ - udev = udev_new(); - if (!udev) { - fprintf(stderr, "Failed to initialize udev\n"); - return 1; - } - - *li = libinput_udev_create_context(&interface, NULL, udev); - if (!*li) { - fprintf(stderr, "Failed to initialize context from udev\n"); - return 1; - } - - if (options.verbose) { - libinput_log_set_handler(*li, log_handler); - libinput_log_set_priority(*li, LIBINPUT_LOG_PRIORITY_DEBUG); - } - - if (libinput_udev_assign_seat(*li, options.seat)) { - fprintf(stderr, "Failed to set seat\n"); - libinput_unref(*li); - return 1; - } - - return 0; -} - -static int -open_device(struct libinput **li, const char *path) -{ - struct libinput_device *device; - - *li = libinput_path_create_context(&interface, NULL); - if (!*li) { - fprintf(stderr, "Failed to initialize context from %s\n", path); - return 1; - } - - if (options.verbose) { - libinput_log_set_handler(*li, log_handler); - libinput_log_set_priority(*li, LIBINPUT_LOG_PRIORITY_DEBUG); - } - - device = libinput_path_add_device(*li, path); - if (!device) { - fprintf(stderr, "Failed to initialized device %s\n", path); - libinput_unref(*li); - return 1; - } - - return 0; -} - static void print_event_header(struct libinput_event *ev) { @@ -440,14 +374,9 @@ main(int argc, char **argv) if (tools_parse_args(argc, argv, &options)) return 1; - if (options.backend == BACKEND_UDEV) { - if (open_udev(&li)) - return 1; - } else if (options.backend == BACKEND_DEVICE) { - if (open_device(&li, device)) - return 1; - } else - abort(); + li = tools_open_backend(&options, &interface); + if (!li) + return 1; clock_gettime(CLOCK_MONOTONIC, &tp); start_time = tp.tv_sec * 1000 + tp.tv_nsec / 1000000; @@ -455,8 +384,6 @@ main(int argc, char **argv) mainloop(li); libinput_unref(li); - if (udev) - udev_unref(udev); return 0; } diff --git a/tools/shared.c b/tools/shared.c index 17a96732..f8ceb341 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "shared.h" @@ -40,6 +41,15 @@ enum options { OPT_TAP_DISABLE, }; +static void +log_handler(struct libinput *li, + enum libinput_log_priority priority, + const char *format, + va_list args) +{ + vprintf(format, args); +} + void tools_usage() { @@ -131,3 +141,84 @@ tools_parse_args(int argc, char **argv, struct tools_options *options) return 0; } + +static struct libinput * +open_udev(const struct libinput_interface *interface, + const char *seat, + int verbose) +{ + struct libinput *li; + struct udev *udev = udev_new(); + + if (!udev) { + fprintf(stderr, "Failed to initialize udev\n"); + return NULL; + } + + li = libinput_udev_create_context(interface, NULL, udev); + if (!li) { + fprintf(stderr, "Failed to initialize context from udev\n"); + goto out; + } + + if (verbose) { + libinput_log_set_handler(li, log_handler); + libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG); + } + + if (libinput_udev_assign_seat(li, seat)) { + fprintf(stderr, "Failed to set seat\n"); + libinput_unref(li); + li = NULL; + goto out; + } + +out: + udev_unref(udev); + return li; +} + +static struct libinput * +open_device(const struct libinput_interface *interface, + const char *path, + int verbose) +{ + struct libinput_device *device; + struct libinput *li; + + li = libinput_path_create_context(interface, NULL); + if (!li) { + fprintf(stderr, "Failed to initialize context from %s\n", path); + return NULL; + } + + if (verbose) { + libinput_log_set_handler(li, log_handler); + libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG); + } + + device = libinput_path_add_device(li, path); + if (!device) { + fprintf(stderr, "Failed to initialized device %s\n", path); + libinput_unref(li); + li = NULL; + } + + return li; +} + +struct libinput * +tools_open_backend(struct tools_options *options, + const struct libinput_interface *interface) +{ + struct libinput *li = NULL; + + if (options->backend == BACKEND_UDEV) { + li = open_udev(interface, options->seat, options->verbose); + } else if (options->backend == BACKEND_DEVICE) { + li = open_device(interface, options->device, options->verbose); + } else + abort(); + + return li; +} diff --git a/tools/shared.h b/tools/shared.h index fa7c5efe..04d13697 100644 --- a/tools/shared.h +++ b/tools/shared.h @@ -23,6 +23,8 @@ #ifndef _SHARED_H_ #define _SHARED_H_ +#include + enum tools_backend { BACKEND_DEVICE, BACKEND_UDEV @@ -39,6 +41,8 @@ struct tools_options { void tools_init_options(struct tools_options *options); int tools_parse_args(int argc, char **argv, struct tools_options *options); +struct libinput* tools_open_backend(struct tools_options *options, + const struct libinput_interface *interface); void tools_usage(); From b8e63b54d3be8b838ad9791c8aa4005d73f269eb Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 15:10:09 +1000 Subject: [PATCH 19/55] tools: move applying device configuration to shared lib Signed-off-by: Peter Hutterer --- tools/event-debug.c | 10 ++-------- tools/shared.c | 8 ++++++++ tools/shared.h | 3 ++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tools/event-debug.c b/tools/event-debug.c index b8be215d..ffc9a132 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -261,13 +261,6 @@ print_touch_event_with_coords(struct libinput_event *ev) xmm, ymm); } -static void -setup_device(struct libinput_device *device) -{ - if (options.tapping != -1) - libinput_device_config_tap_set_enabled(device, options.tapping); -} - static int handle_and_print_events(struct libinput *li) { @@ -284,7 +277,8 @@ handle_and_print_events(struct libinput *li) case LIBINPUT_EVENT_DEVICE_ADDED: case LIBINPUT_EVENT_DEVICE_REMOVED: print_device_notify(ev); - setup_device(libinput_event_get_device(ev)); + tools_device_apply_config(libinput_event_get_device(ev), + &options); break; case LIBINPUT_EVENT_KEYBOARD_KEY: print_key_event(ev); diff --git a/tools/shared.c b/tools/shared.c index f8ceb341..bd8fd11b 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -222,3 +222,11 @@ tools_open_backend(struct tools_options *options, return li; } + +void +tools_device_apply_config(struct libinput_device *device, + struct tools_options *options) +{ + if (options->tapping != -1) + libinput_device_config_tap_set_enabled(device, options->tapping); +} diff --git a/tools/shared.h b/tools/shared.h index 04d13697..71a3b360 100644 --- a/tools/shared.h +++ b/tools/shared.h @@ -43,7 +43,8 @@ void tools_init_options(struct tools_options *options); int tools_parse_args(int argc, char **argv, struct tools_options *options); struct libinput* tools_open_backend(struct tools_options *options, const struct libinput_interface *interface); - +void tools_device_apply_config(struct libinput_device *device, + struct tools_options *options); void tools_usage(); #endif From 333f4e0347e32e8e67fca30527bac490beee76e6 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 15:10:59 +1000 Subject: [PATCH 20/55] tools: add support to enable/disable natural scrolling Signed-off-by: Peter Hutterer --- tools/shared.c | 16 ++++++++++++++++ tools/shared.h | 1 + 2 files changed, 17 insertions(+) diff --git a/tools/shared.c b/tools/shared.c index bd8fd11b..623005e5 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -39,6 +39,8 @@ enum options { OPT_VERBOSE, OPT_TAP_ENABLE, OPT_TAP_DISABLE, + OPT_NATURAL_SCROLL_ENABLE, + OPT_NATURAL_SCROLL_DISABLE, }; static void @@ -61,6 +63,8 @@ tools_usage() "Features:\n" "--enable-tap\n" "--disable-tap.... enable/disable tapping\n" + "--enable-natural-scrolling\n" + "--disable-natural-scrolling.... enable/disable natural scrolling\n" "\n" "These options apply to all applicable devices, if a feature\n" "is not explicitly specified it is left at each device's default.\n" @@ -76,6 +80,7 @@ tools_init_options(struct tools_options *options) { memset(options, 0, sizeof(*options)); options->tapping = -1; + options->natural_scroll = -1; options->backend = BACKEND_UDEV; options->seat = "seat0"; } @@ -93,6 +98,8 @@ tools_parse_args(int argc, char **argv, struct tools_options *options) { "verbose", 0, 0, OPT_VERBOSE }, { "enable-tap", 0, 0, OPT_TAP_ENABLE }, { "disable-tap", 0, 0, OPT_TAP_DISABLE }, + { "enable-natural-scrolling", 0, 0, OPT_NATURAL_SCROLL_ENABLE }, + { "disable-natural-scrolling", 0, 0, OPT_NATURAL_SCROLL_DISABLE }, { 0, 0, 0, 0} }; @@ -127,6 +134,12 @@ tools_parse_args(int argc, char **argv, struct tools_options *options) case OPT_TAP_DISABLE: options->tapping = 0; break; + case OPT_NATURAL_SCROLL_ENABLE: + options->natural_scroll = 1; + break; + case OPT_NATURAL_SCROLL_DISABLE: + options->natural_scroll = 0; + break; default: tools_usage(); return 1; @@ -229,4 +242,7 @@ tools_device_apply_config(struct libinput_device *device, { if (options->tapping != -1) libinput_device_config_tap_set_enabled(device, options->tapping); + if (options->natural_scroll != -1) + libinput_device_config_scroll_set_natural_scroll_enabled(device, + options->natural_scroll); } diff --git a/tools/shared.h b/tools/shared.h index 71a3b360..e33fe04f 100644 --- a/tools/shared.h +++ b/tools/shared.h @@ -37,6 +37,7 @@ struct tools_options { int verbose; int tapping; + int natural_scroll; }; void tools_init_options(struct tools_options *options); From 363a7f783f9f18fa4142ba2911a18a61625f2ce7 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 15:14:09 +1000 Subject: [PATCH 21/55] tools: add support for enabling/disabling left-handed button mappings Signed-off-by: Peter Hutterer --- tools/shared.c | 15 +++++++++++++++ tools/shared.h | 1 + 2 files changed, 16 insertions(+) diff --git a/tools/shared.c b/tools/shared.c index 623005e5..8439cb27 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -41,6 +41,8 @@ enum options { OPT_TAP_DISABLE, OPT_NATURAL_SCROLL_ENABLE, OPT_NATURAL_SCROLL_DISABLE, + OPT_LEFT_HANDED_ENABLE, + OPT_LEFT_HANDED_DISABLE, }; static void @@ -65,6 +67,8 @@ tools_usage() "--disable-tap.... enable/disable tapping\n" "--enable-natural-scrolling\n" "--disable-natural-scrolling.... enable/disable natural scrolling\n" + "--enable-left-handed\n" + "--disable-left-handed.... enable/disable left-handed button configuration\n" "\n" "These options apply to all applicable devices, if a feature\n" "is not explicitly specified it is left at each device's default.\n" @@ -81,6 +85,7 @@ tools_init_options(struct tools_options *options) memset(options, 0, sizeof(*options)); options->tapping = -1; options->natural_scroll = -1; + options->left_handed = -1; options->backend = BACKEND_UDEV; options->seat = "seat0"; } @@ -100,6 +105,8 @@ tools_parse_args(int argc, char **argv, struct tools_options *options) { "disable-tap", 0, 0, OPT_TAP_DISABLE }, { "enable-natural-scrolling", 0, 0, OPT_NATURAL_SCROLL_ENABLE }, { "disable-natural-scrolling", 0, 0, OPT_NATURAL_SCROLL_DISABLE }, + { "enable-left-handed", 0, 0, OPT_LEFT_HANDED_ENABLE }, + { "disable-left-handed", 0, 0, OPT_LEFT_HANDED_DISABLE }, { 0, 0, 0, 0} }; @@ -140,6 +147,12 @@ tools_parse_args(int argc, char **argv, struct tools_options *options) case OPT_NATURAL_SCROLL_DISABLE: options->natural_scroll = 0; break; + case OPT_LEFT_HANDED_ENABLE: + options->left_handed = 1; + break; + case OPT_LEFT_HANDED_DISABLE: + options->left_handed = 0; + break; default: tools_usage(); return 1; @@ -245,4 +258,6 @@ tools_device_apply_config(struct libinput_device *device, if (options->natural_scroll != -1) libinput_device_config_scroll_set_natural_scroll_enabled(device, options->natural_scroll); + if (options->left_handed != -1) + libinput_device_config_buttons_set_left_handed(device, options->left_handed); } diff --git a/tools/shared.h b/tools/shared.h index e33fe04f..9ecd3adb 100644 --- a/tools/shared.h +++ b/tools/shared.h @@ -38,6 +38,7 @@ struct tools_options { int verbose; int tapping; int natural_scroll; + int left_handed; }; void tools_init_options(struct tools_options *options); From 6ee8c5854ca574e76d5f4a59f9cd4041a8279e64 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 14:47:54 +1000 Subject: [PATCH 22/55] tools: use the new shared lib from event-gui This gives the event gui the ability to use the path backend, and any configuration toggles given on the commandline. Signed-off-by: Peter Hutterer --- tools/Makefile.am | 2 +- tools/event-gui.c | 50 ++++++++++------------------------------------- 2 files changed, 11 insertions(+), 41 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index 6dd64c94..cebcd729 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -18,7 +18,7 @@ if BUILD_EVENTGUI noinst_PROGRAMS += event-gui event_gui_SOURCES = event-gui.c -event_gui_LDADD = ../src/libinput.la $(CAIRO_LIBS) $(GTK_LIBS) $(LIBUDEV_LIBS) +event_gui_LDADD = ../src/libinput.la libshared.la $(CAIRO_LIBS) $(GTK_LIBS) $(LIBUDEV_LIBS) event_gui_CFLAGS = $(CAIRO_CFLAGS) $(GTK_CFLAGS) $(LIBUDEV_CFLAGS) event_gui_LDFLAGS = -no-install endif diff --git a/tools/event-gui.c b/tools/event-gui.c index b6d21b66..b950f92c 100644 --- a/tools/event-gui.c +++ b/tools/event-gui.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -40,8 +39,12 @@ #include #include +#include "shared.h" + #define clip(val_, min_, max_) min((max_), max((min_), (val_))) +struct tools_options options; + struct touch { int active; int x, y; @@ -95,12 +98,6 @@ msg(const char *fmt, ...) va_end(args); } -static void -usage(void) -{ - printf("%s [path/to/device]\n", program_invocation_short_name); -} - static gboolean draw(GtkWidget *widget, cairo_t *cr, gpointer data) { @@ -490,35 +487,6 @@ sockets_init(struct libinput *li) g_io_add_watch(c, G_IO_IN, handle_event_libinput, li); } -static int -parse_opts(int argc, char *argv[]) -{ - while (1) { - static struct option long_options[] = { - { "help", no_argument, 0, 'h' }, - }; - - int option_index = 0; - int c; - - c = getopt_long(argc, argv, "h", long_options, - &option_index); - if (c == -1) - break; - - switch(c) { - case 'h': - usage(); - return 0; - default: - usage(); - return 1; - } - } - - return 0; -} - static int open_restricted(const char *path, int flags, void *user_data) { @@ -546,16 +514,18 @@ main(int argc, char *argv[]) gtk_init(&argc, &argv); - if (parse_opts(argc, argv) != 0) + tools_init_options(&options); + + if (tools_parse_args(argc, argv, &options) != 0) return 1; udev = udev_new(); if (!udev) error("Failed to initialize udev\n"); - li = libinput_udev_create_context(&interface, &w, udev); - if (!li || libinput_udev_assign_seat(li, "seat0") != 0) - error("Failed to initialize context from udev\n"); + li = tools_open_backend(&options, &interface); + if (!li) + return 1; window_init(&w); sockets_init(li); From df472317194f3ef83c4c22cd134b0639a8536367 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 23 Dec 2014 11:13:33 +1000 Subject: [PATCH 23/55] tools: pass the userdata to the context The event-gui needs this but it got dropped in 6ee8c585, causing a crash. Oops. Signed-off-by: Peter Hutterer --- tools/event-debug.c | 2 +- tools/event-gui.c | 2 +- tools/shared.c | 11 +++++++---- tools/shared.h | 1 + 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tools/event-debug.c b/tools/event-debug.c index ffc9a132..da581c82 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -368,7 +368,7 @@ main(int argc, char **argv) if (tools_parse_args(argc, argv, &options)) return 1; - li = tools_open_backend(&options, &interface); + li = tools_open_backend(&options, NULL, &interface); if (!li) return 1; diff --git a/tools/event-gui.c b/tools/event-gui.c index b950f92c..9a08d8ef 100644 --- a/tools/event-gui.c +++ b/tools/event-gui.c @@ -523,7 +523,7 @@ main(int argc, char *argv[]) if (!udev) error("Failed to initialize udev\n"); - li = tools_open_backend(&options, &interface); + li = tools_open_backend(&options, &w, &interface); if (!li) return 1; diff --git a/tools/shared.c b/tools/shared.c index 8439cb27..3e1368d1 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -170,6 +170,7 @@ tools_parse_args(int argc, char **argv, struct tools_options *options) static struct libinput * open_udev(const struct libinput_interface *interface, + void *userdata, const char *seat, int verbose) { @@ -181,7 +182,7 @@ open_udev(const struct libinput_interface *interface, return NULL; } - li = libinput_udev_create_context(interface, NULL, udev); + li = libinput_udev_create_context(interface, userdata, udev); if (!li) { fprintf(stderr, "Failed to initialize context from udev\n"); goto out; @@ -206,13 +207,14 @@ out: static struct libinput * open_device(const struct libinput_interface *interface, + void *userdata, const char *path, int verbose) { struct libinput_device *device; struct libinput *li; - li = libinput_path_create_context(interface, NULL); + li = libinput_path_create_context(interface, userdata); if (!li) { fprintf(stderr, "Failed to initialize context from %s\n", path); return NULL; @@ -235,14 +237,15 @@ open_device(const struct libinput_interface *interface, struct libinput * tools_open_backend(struct tools_options *options, + void *userdata, const struct libinput_interface *interface) { struct libinput *li = NULL; if (options->backend == BACKEND_UDEV) { - li = open_udev(interface, options->seat, options->verbose); + li = open_udev(interface, userdata, options->seat, options->verbose); } else if (options->backend == BACKEND_DEVICE) { - li = open_device(interface, options->device, options->verbose); + li = open_device(interface, userdata, options->device, options->verbose); } else abort(); diff --git a/tools/shared.h b/tools/shared.h index 9ecd3adb..4388cea6 100644 --- a/tools/shared.h +++ b/tools/shared.h @@ -44,6 +44,7 @@ struct tools_options { void tools_init_options(struct tools_options *options); int tools_parse_args(int argc, char **argv, struct tools_options *options); struct libinput* tools_open_backend(struct tools_options *options, + void *userdata, const struct libinput_interface *interface); void tools_device_apply_config(struct libinput_device *device, struct tools_options *options); From 6138babc12ebd03d8482542137aac50913be405c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 13:52:36 +1000 Subject: [PATCH 24/55] test: switch touch points around for semi-mt tap-n-drag testing The tests ignored it when motion events never happened - but that's mostly what these tests are about. This only happened for semi-mt devices that use the bounding box only, not separate touch points. Switching the touch points around that the bounding box doesn't interfere causes the test to work as expected. Signed-off-by: Peter Hutterer --- test/touchpad.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/touchpad.c b/test/touchpad.c index 84b30804..e6f0eb60 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -211,11 +211,11 @@ START_TEST(touchpad_2fg_tap_n_drag) litest_drain_events(li); - litest_touch_down(dev, 0, 50, 50); + litest_touch_down(dev, 0, 30, 70); litest_touch_up(dev, 0); - litest_touch_down(dev, 0, 50, 50); - litest_touch_down(dev, 1, 60, 50); - litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40); + litest_touch_down(dev, 0, 30, 70); + litest_touch_down(dev, 1, 80, 70); + litest_touch_move_to(dev, 0, 30, 70, 30, 30, 5, 40); libinput_dispatch(li); litest_assert_button_event(li, BTN_LEFT, @@ -250,11 +250,11 @@ START_TEST(touchpad_2fg_tap_n_drag_3fg_btntool) litest_drain_events(li); - litest_touch_down(dev, 0, 50, 50); + litest_touch_down(dev, 0, 30, 70); litest_touch_up(dev, 0); - litest_touch_down(dev, 0, 50, 50); - litest_touch_down(dev, 1, 60, 50); - litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40); + litest_touch_down(dev, 0, 30, 70); + litest_touch_down(dev, 1, 80, 90); + litest_touch_move_to(dev, 0, 30, 70, 30, 30, 5, 40); libinput_dispatch(li); litest_assert_button_event(li, BTN_LEFT, From c464458f829361e38e4ee07a34538a9660f8d0c5 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 11:29:32 +1000 Subject: [PATCH 25/55] test: add helper function for checking for a specific event type In a few tests we care about that a specific set of events are in the queue but not about the details of the events (usually checked elsewhere). Instead of manual loops, provide a helper function that also checks that there is at least one of those events in the queue. Signed-off-by: Peter Hutterer --- test/litest.c | 21 +++++++++++++++++++++ test/litest.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/test/litest.c b/test/litest.c index befad5aa..392ffe25 100644 --- a/test/litest.c +++ b/test/litest.c @@ -1223,6 +1223,27 @@ litest_assert_scroll(struct libinput *li, } } +void +litest_assert_only_typed_events(struct libinput *li, + enum libinput_event_type type) +{ + struct libinput_event *event; + + assert(type != LIBINPUT_EVENT_NONE); + + libinput_dispatch(li); + event = libinput_get_event(li); + ck_assert_notnull(event); + + while (event) { + ck_assert_int_eq(libinput_event_get_type(event), + type); + libinput_event_destroy(event); + libinput_dispatch(li); + event = libinput_get_event(li); + } +} + void litest_timeout_tap(void) { diff --git a/test/litest.h b/test/litest.h index 99c6ae3b..31011a2b 100644 --- a/test/litest.h +++ b/test/litest.h @@ -162,6 +162,8 @@ void litest_assert_button_event(struct libinput *li, void litest_assert_scroll(struct libinput *li, enum libinput_pointer_axis axis, int minimum_movement); +void litest_assert_only_typed_events(struct libinput *li, + enum libinput_event_type type); struct libevdev_uinput * litest_create_uinput_device(const char *name, struct input_id *id, From b74330255b8aa65979ce3d1621c847b58627080e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 11:52:31 +1000 Subject: [PATCH 26/55] test: switch tests to use the new helper function Signed-off-by: Peter Hutterer --- test/touchpad.c | 79 +++++-------------------------------------------- 1 file changed, 8 insertions(+), 71 deletions(-) diff --git a/test/touchpad.c b/test/touchpad.c index e6f0eb60..1a0414cc 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -121,7 +121,6 @@ START_TEST(touchpad_1fg_tap_n_drag) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; - struct libinput_event *event; libinput_device_config_tap_set_enabled(dev->libinput_device, LIBINPUT_CONFIG_TAP_ENABLED); @@ -140,27 +139,15 @@ START_TEST(touchpad_1fg_tap_n_drag) LIBINPUT_BUTTON_STATE_PRESSED); libinput_dispatch(li); - while (libinput_next_event_type(li) == LIBINPUT_EVENT_POINTER_MOTION) { - event = libinput_get_event(li); - libinput_event_destroy(event); - libinput_dispatch(li); - } - ck_assert_int_eq(libinput_next_event_type(li), LIBINPUT_EVENT_NONE); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); /* lift finger, set down again, should continue dragging */ litest_touch_down(dev, 0, 50, 50); litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40); litest_touch_up(dev, 0); - libinput_dispatch(li); - while (libinput_next_event_type(li) == LIBINPUT_EVENT_POINTER_MOTION) { - event = libinput_get_event(li); - libinput_event_destroy(event); - libinput_dispatch(li); - } - - ck_assert_int_eq(libinput_next_event_type(li), LIBINPUT_EVENT_NONE); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); litest_timeout_tap(); @@ -204,7 +191,6 @@ START_TEST(touchpad_2fg_tap_n_drag) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; - struct libinput_event *event; libinput_device_config_tap_set_enabled(dev->libinput_device, LIBINPUT_CONFIG_TAP_ENABLED); @@ -221,12 +207,7 @@ START_TEST(touchpad_2fg_tap_n_drag) litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED); - while (libinput_next_event_type(li) == LIBINPUT_EVENT_POINTER_MOTION) { - event = libinput_get_event(li); - libinput_event_destroy(event); - libinput_dispatch(li); - } - litest_assert_empty_queue(li); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); litest_touch_up(dev, 0); litest_touch_up(dev, 1); @@ -243,7 +224,6 @@ START_TEST(touchpad_2fg_tap_n_drag_3fg_btntool) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; - struct libinput_event *event; libinput_device_config_tap_set_enabled(dev->libinput_device, LIBINPUT_CONFIG_TAP_ENABLED); @@ -260,12 +240,7 @@ START_TEST(touchpad_2fg_tap_n_drag_3fg_btntool) litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED); - while (libinput_next_event_type(li) == LIBINPUT_EVENT_POINTER_MOTION) { - event = libinput_get_event(li); - libinput_event_destroy(event); - libinput_dispatch(li); - } - litest_assert_empty_queue(li); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); /* Putting down a third finger should end the drag */ litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1); @@ -591,7 +566,6 @@ START_TEST(touchpad_1fg_tap_n_drag_click) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; - struct libinput_event *event; libinput_device_config_tap_set_enabled(dev->libinput_device, LIBINPUT_CONFIG_TAP_ENABLED); @@ -608,15 +582,7 @@ START_TEST(touchpad_1fg_tap_n_drag_click) litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED); - libinput_dispatch(li); - - ck_assert_int_eq(libinput_next_event_type(li), - LIBINPUT_EVENT_POINTER_MOTION); - while (libinput_next_event_type(li) == LIBINPUT_EVENT_POINTER_MOTION) { - event = libinput_get_event(li); - libinput_event_destroy(event); - libinput_dispatch(li); - } + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); litest_event(dev, EV_KEY, BTN_LEFT, 1); litest_event(dev, EV_SYN, SYN_REPORT, 0); @@ -873,7 +839,6 @@ START_TEST(clickpad_click_n_drag) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; - struct libinput_event *event; litest_drain_events(li); @@ -893,14 +858,7 @@ START_TEST(clickpad_click_n_drag) litest_touch_move_to(dev, 1, 70, 70, 80, 50, 5, 0); litest_touch_up(dev, 1); - libinput_dispatch(li); - ck_assert_int_eq(libinput_next_event_type(li), - LIBINPUT_EVENT_POINTER_MOTION); - do { - event = libinput_get_event(li); - libinput_event_destroy(event); - libinput_dispatch(li); - } while (libinput_next_event_type(li) == LIBINPUT_EVENT_POINTER_MOTION); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); litest_event(dev, EV_KEY, BTN_LEFT, 0); litest_event(dev, EV_SYN, SYN_REPORT, 0); @@ -1697,8 +1655,6 @@ START_TEST(touchpad_palm_detect_palm_becomes_pointer) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; - struct libinput_event *ev; - enum libinput_event_type type; if (!touchpad_has_palm_detect_size(dev)) return; @@ -1711,15 +1667,7 @@ START_TEST(touchpad_palm_detect_palm_becomes_pointer) libinput_dispatch(li); - ev = libinput_get_event(li); - ck_assert_notnull(ev); - do { - type = libinput_event_get_type(ev); - ck_assert_int_eq(type, LIBINPUT_EVENT_POINTER_MOTION); - - libinput_event_destroy(ev); - ev = libinput_get_event(li); - } while (ev); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); litest_assert_empty_queue(li); } @@ -1729,8 +1677,6 @@ START_TEST(touchpad_palm_detect_no_palm_moving_into_edges) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; - struct libinput_event *ev; - enum libinput_event_type type; if (!touchpad_has_palm_detect_size(dev)) return; @@ -1746,16 +1692,7 @@ START_TEST(touchpad_palm_detect_no_palm_moving_into_edges) litest_touch_move_to(dev, 0, 99, 50, 99, 90, 5, 0); libinput_dispatch(li); - type = libinput_next_event_type(li); - do { - - ck_assert_int_eq(type, LIBINPUT_EVENT_POINTER_MOTION); - ev = libinput_get_event(li); - libinput_event_destroy(ev); - - type = libinput_next_event_type(li); - libinput_dispatch(li); - } while (type != LIBINPUT_EVENT_NONE); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); litest_touch_up(dev, 0); libinput_dispatch(li); From 54c972402fd69ac0c495e2af00fb797a4dec4ba9 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 10:21:48 +1000 Subject: [PATCH 27/55] touchpad: rename scroll.state to scroll.edge_state In preparation for a twofinger_state field, to avoid confusion. Signed-off-by: Peter Hutterer --- src/evdev-mt-touchpad-edge-scroll.c | 6 +++--- src/evdev-mt-touchpad.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c index 616080fa..bc6831dd 100644 --- a/src/evdev-mt-touchpad-edge-scroll.c +++ b/src/evdev-mt-touchpad-edge-scroll.c @@ -69,7 +69,7 @@ tp_edge_scroll_set_state(struct tp_dispatch *tp, { libinput_timer_cancel(&t->scroll.timer); - t->scroll.state = state; + t->scroll.edge_state = state; switch (state) { case EDGE_SCROLL_TOUCH_STATE_NONE: @@ -207,7 +207,7 @@ tp_edge_scroll_handle_event(struct tp_dispatch *tp, struct tp_touch *t, enum scroll_event event) { - switch (t->scroll.state) { + switch (t->scroll.edge_state) { case EDGE_SCROLL_TOUCH_STATE_NONE: tp_edge_scroll_handle_none(tp, t, event); break; @@ -374,5 +374,5 @@ tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time) int tp_edge_scroll_touch_active(struct tp_dispatch *tp, struct tp_touch *t) { - return t->scroll.state == EDGE_SCROLL_TOUCH_STATE_AREA; + return t->scroll.edge_state == EDGE_SCROLL_TOUCH_STATE_AREA; } diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index 14502882..e2849280 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -165,7 +165,7 @@ struct tp_touch { } tap; struct { - enum tp_edge_scroll_touch_state state; + enum tp_edge_scroll_touch_state edge_state; uint32_t edge; int direction; double threshold; From 6028e126fe006d0099aee965db669e8752f7bd42 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 10:37:38 +1000 Subject: [PATCH 28/55] touchpad: revert to pointer movement when stopping twofinger scrolling Add a boolean state machine for two-finger scrolling so we know when we're currently scrolling. If we were scrolling and it stops, pick the active touch as pointer touch so we can go back to pointer movement without having to lift the finger off the touchpad. https://bugs.freedesktop.org/show_bug.cgi?id=86807 Signed-off-by: Peter Hutterer --- src/evdev-mt-touchpad.c | 40 ++++++++++++++++++++++++++++++++++------ src/evdev-mt-touchpad.h | 6 ++++++ test/touchpad.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 964900d2..0f3e72a6 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -436,6 +436,33 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time) tp_filter_motion(tp, &dx, &dy, NULL, NULL, time); evdev_post_scroll(tp->device, time, dx, dy); + tp->scroll.twofinger_state = TWOFINGER_SCROLL_STATE_ACTIVE; +} + +static void +tp_twofinger_stop_scroll(struct tp_dispatch *tp, uint64_t time) +{ + struct tp_touch *t, *ptr = NULL; + int nfingers_down = 0; + + evdev_stop_scroll(tp->device, time); + + /* If we were scrolling and now there's exactly 1 active finger, + switch back to pointer movement */ + if (tp->scroll.twofinger_state == TWOFINGER_SCROLL_STATE_ACTIVE) { + tp_for_each_touch(tp, t) { + if (tp_touch_active(tp, t)) { + nfingers_down++; + if (ptr == NULL) + ptr = t; + } + } + + if (nfingers_down == 1) + tp_set_pointer(tp, ptr); + } + + tp->scroll.twofinger_state = TWOFINGER_SCROLL_STATE_NONE; } static int @@ -458,13 +485,14 @@ tp_twofinger_scroll_post_events(struct tp_dispatch *tp, uint64_t time) nfingers_down++; } - if (nfingers_down != 2) { - evdev_stop_scroll(tp->device, time); - return 0; + if (nfingers_down == 2) { + tp_post_twofinger_scroll(tp, time); + return 1; } - tp_post_twofinger_scroll(tp, time); - return 1; + tp_twofinger_stop_scroll(tp, time); + + return 0; } static void @@ -504,7 +532,7 @@ tp_stop_scroll_events(struct tp_dispatch *tp, uint64_t time) case LIBINPUT_CONFIG_SCROLL_NO_SCROLL: break; case LIBINPUT_CONFIG_SCROLL_2FG: - evdev_stop_scroll(tp->device, time); + tp_twofinger_stop_scroll(tp, time); break; case LIBINPUT_CONFIG_SCROLL_EDGE: tp_edge_scroll_stop_events(tp, time); diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index e2849280..5807f08c 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -117,6 +117,11 @@ enum tp_edge_scroll_touch_state { EDGE_SCROLL_TOUCH_STATE_AREA, }; +enum tp_twofinger_scroll_state { + TWOFINGER_SCROLL_STATE_NONE, + TWOFINGER_SCROLL_STATE_ACTIVE, +}; + struct tp_motion { int32_t x; int32_t y; @@ -238,6 +243,7 @@ struct tp_dispatch { enum libinput_config_scroll_method method; int32_t right_edge; int32_t bottom_edge; + enum tp_twofinger_scroll_state twofinger_state; } scroll; enum touchpad_event queued; diff --git a/test/touchpad.c b/test/touchpad.c index 1a0414cc..8602e039 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -1461,6 +1461,44 @@ START_TEST(touchpad_2fg_scroll_slow_distance) } END_TEST +START_TEST(touchpad_2fg_scroll_return_to_motion) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + litest_drain_events(li); + + /* start with motion */ + litest_touch_down(dev, 0, 70, 70); + litest_touch_move_to(dev, 0, 70, 70, 47, 50, 10, 0); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); + + /* 2fg scroll */ + litest_touch_down(dev, 1, 53, 50); + litest_touch_move_to(dev, 0, 47, 50, 47, 70, 5, 0); + litest_touch_move_to(dev, 1, 53, 50, 53, 70, 5, 0); + litest_touch_up(dev, 1); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS); + + litest_touch_move_to(dev, 0, 47, 70, 47, 50, 10, 0); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); + + /* back to 2fg scroll, lifting the other finger */ + litest_touch_down(dev, 1, 50, 50); + litest_touch_move_to(dev, 0, 47, 50, 47, 70, 5, 0); + litest_touch_move_to(dev, 1, 53, 50, 53, 70, 5, 0); + litest_touch_up(dev, 0); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS); + + /* move with second finger */ + litest_touch_move_to(dev, 1, 53, 70, 53, 50, 10, 0); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); + + litest_touch_up(dev, 1); + litest_assert_empty_queue(li); +} +END_TEST + START_TEST(touchpad_scroll_natural_defaults) { struct litest_device *dev = litest_current_device(); @@ -2059,6 +2097,7 @@ int main(int argc, char **argv) { litest_add("touchpad:scroll", touchpad_2fg_scroll, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:scroll", touchpad_2fg_scroll_slow_distance, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("touchpad:scroll", touchpad_2fg_scroll_return_to_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:scroll", touchpad_scroll_natural_defaults, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:scroll", touchpad_scroll_natural_enable_config, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:scroll", touchpad_scroll_natural, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); From 7a65c1f63637f47e45892422f7078b1af5dd0e2a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 18 Dec 2014 14:18:53 +1000 Subject: [PATCH 29/55] Declare libinput.sym as dependency We want to rebuild whenever it changes Signed-off-by: Peter Hutterer --- src/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.am b/src/Makefile.am index eeaf439b..b5eba731 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,6 +36,7 @@ libinput_la_CFLAGS = -I$(top_srcdir)/include \ $(LIBUDEV_CFLAGS) \ $(LIBEVDEV_CFLAGS) \ $(GCC_CFLAGS) +EXTRA_libinput_la_DEPENDENCIES = $(srcdir)/libinput.sym libinput_util_la_SOURCES = \ libinput-util.c \ From 6e6cca47af6e8858c0e3ae9ec8309f7f59ba8708 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 23 Dec 2014 13:37:28 +1000 Subject: [PATCH 30/55] Add libinput_set_user_data Previously, the pointer could only be passed into the context on creation time and was immutable after that. Signed-off-by: Peter Hutterer --- src/libinput.c | 7 +++++++ src/libinput.h | 11 +++++++++++ src/libinput.sym | 1 + test/path.c | 16 ++++++++++++++++ test/udev.c | 21 +++++++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/src/libinput.c b/src/libinput.c index fbefbb38..d78e26db 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -1173,6 +1173,13 @@ libinput_next_event_type(struct libinput *libinput) return event->type; } +LIBINPUT_EXPORT void +libinput_set_user_data(struct libinput *libinput, + void *user_data) +{ + libinput->user_data = user_data; +} + LIBINPUT_EXPORT void * libinput_get_user_data(struct libinput *libinput) { diff --git a/src/libinput.h b/src/libinput.h index e156a3a0..d43b0f6a 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -1002,6 +1002,17 @@ libinput_get_event(struct libinput *libinput); enum libinput_event_type libinput_next_event_type(struct libinput *libinput); +/** + * @ingroup base + * + * @param libinput A previously initialized libinput context + * @param user_data Caller-specific data passed to the various callback + * interfaces. + */ +void +libinput_set_user_data(struct libinput *libinput, + void *user_data); + /** * @ingroup base * diff --git a/src/libinput.sym b/src/libinput.sym index f35a0cdf..057919c9 100644 --- a/src/libinput.sym +++ b/src/libinput.sym @@ -108,6 +108,7 @@ global: libinput_seat_ref; libinput_seat_set_user_data; libinput_seat_unref; + libinput_set_user_data; libinput_suspend; libinput_udev_assign_seat; libinput_udev_create_context; diff --git a/test/path.c b/test/path.c index 3a2bf2f8..243edd79 100644 --- a/test/path.c +++ b/test/path.c @@ -133,6 +133,21 @@ START_TEST(path_create_destroy) } END_TEST +START_TEST(path_set_user_data) +{ + struct libinput *li; + int data1, data2; + + li = libinput_path_create_context(&simple_interface, &data1); + ck_assert(li != NULL); + ck_assert(libinput_get_user_data(li) == &data1); + libinput_set_user_data(li, &data2); + ck_assert(libinput_get_user_data(li) == &data2); + + libinput_unref(li); +} +END_TEST + START_TEST(path_added_seat) { struct litest_device *dev = litest_current_device(); @@ -867,6 +882,7 @@ 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:create", path_set_user_data); 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); diff --git a/test/udev.c b/test/udev.c index f5d2c883..c351bed5 100644 --- a/test/udev.c +++ b/test/udev.c @@ -129,6 +129,26 @@ START_TEST(udev_create_empty_seat) } END_TEST +START_TEST(udev_set_user_data) +{ + struct libinput *li; + struct udev *udev; + int data1, data2; + + udev = udev_new(); + ck_assert(udev != NULL); + + li = libinput_udev_create_context(&simple_interface, &data1, udev); + ck_assert(li != NULL); + ck_assert(libinput_get_user_data(li) == &data1); + libinput_set_user_data(li, &data2); + ck_assert(libinput_get_user_data(li) == &data2); + + libinput_unref(li); + udev_unref(udev); +} +END_TEST + /** * This test only works if there's at least one device in the system that is * assigned the default seat. Should cover the 99% case. @@ -488,6 +508,7 @@ 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:create", udev_set_user_data); litest_add_no_device("udev:seat", udev_added_seat_default); litest_add_no_device("udev:seat", udev_change_seat); From 7779b25f806e11ea68531e349ed65b9a8cd04f6f Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 24 Dec 2014 10:16:12 +1000 Subject: [PATCH 31/55] test: add edge-scrolling tests Signed-off-by: Peter Hutterer --- test/touchpad.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/test/touchpad.c b/test/touchpad.c index 8602e039..19e1c284 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -1545,6 +1545,127 @@ START_TEST(touchpad_scroll_natural) } END_TEST +START_TEST(touchpad_edge_scroll) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + litest_drain_events(li); + + litest_touch_down(dev, 0, 99, 20); + litest_touch_move_to(dev, 0, 99, 20, 99, 80, 10, 0); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 10); + litest_assert_empty_queue(li); + + litest_touch_down(dev, 0, 99, 80); + litest_touch_move_to(dev, 0, 99, 80, 99, 20, 10, 0); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -10); + litest_assert_empty_queue(li); + + litest_touch_down(dev, 0, 20, 99); + litest_touch_move_to(dev, 0, 20, 99, 70, 99, 10, 0); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 10); + litest_assert_empty_queue(li); + + litest_touch_down(dev, 0, 70, 99); + litest_touch_move_to(dev, 0, 70, 99, 20, 99, 10, 0); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -10); + litest_assert_empty_queue(li); +} +END_TEST + +START_TEST(touchpad_edge_scroll_slow_distance) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_pointer *ptrev; + + litest_drain_events(li); + + litest_touch_down(dev, 0, 99, 20); + litest_touch_move_to(dev, 0, 99, 20, 99, 80, 60, 10); + litest_touch_up(dev, 0); + libinput_dispatch(li); + + event = libinput_get_event(li); + ck_assert_notnull(event); + + while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) { + ck_assert_int_eq(libinput_event_get_type(event), + LIBINPUT_EVENT_POINTER_AXIS); + ptrev = libinput_event_get_pointer_event(event); + + ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev), + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + ck_assert(libinput_event_pointer_get_axis_value(ptrev) > 0.0); + + /* this is to verify we test the right thing, if the value + is greater than scroll.threshold we triggered the wrong + condition */ + ck_assert(libinput_event_pointer_get_axis_value(ptrev) < 5.0); + + libinput_event_destroy(event); + event = libinput_get_event(li); + } + + litest_assert_empty_queue(li); + libinput_event_destroy(event); +} +END_TEST + +START_TEST(touchpad_edge_scroll_no_motion) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + litest_drain_events(li); + + litest_touch_down(dev, 0, 99, 20); + litest_touch_move_to(dev, 0, 99, 20, 99, 60, 10, 0); + /* moving outside -> no motion event */ + litest_touch_move_to(dev, 0, 99, 60, 20, 80, 10, 0); + /* moving down outside edge once scrolling had started -> scroll */ + litest_touch_move_to(dev, 0, 20, 80, 40, 99, 10, 0); + litest_touch_up(dev, 0); + libinput_dispatch(li); + + litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 5); + litest_assert_empty_queue(li); +} +END_TEST + +START_TEST(touchpad_edge_scroll_no_edge_after_motion) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + litest_drain_events(li); + + /* moving into the edge zone must not trigger scroll events */ + litest_touch_down(dev, 0, 20, 20); + litest_touch_move_to(dev, 0, 20, 20, 99, 20, 10, 0); + litest_touch_move_to(dev, 0, 99, 20, 99, 80, 10, 0); + litest_touch_up(dev, 0); + libinput_dispatch(li); + + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); + litest_assert_empty_queue(li); +} +END_TEST + START_TEST(touchpad_tap_is_available) { struct litest_device *dev = litest_current_device(); @@ -2101,6 +2222,10 @@ int main(int argc, char **argv) { litest_add("touchpad:scroll", touchpad_scroll_natural_defaults, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:scroll", touchpad_scroll_natural_enable_config, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:scroll", touchpad_scroll_natural, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("touchpad:scroll", touchpad_edge_scroll, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY); + litest_add("touchpad:scroll", touchpad_edge_scroll_no_motion, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY); + litest_add("touchpad:scroll", touchpad_edge_scroll_no_edge_after_motion, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY); + litest_add("touchpad:scroll", touchpad_edge_scroll_slow_distance, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY); litest_add("touchpad:palm", touchpad_palm_detect_at_edge, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:palm", touchpad_palm_detect_at_bottom_corners, LITEST_TOUCHPAD, LITEST_CLICKPAD); From 20ac4b3abd722c3bb415c545f5769b9f1cac15ba Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 5 Nov 2014 16:22:07 +1000 Subject: [PATCH 32/55] Add pointer axis sources to the API For a caller to implement/provide kinetic scrolling ("inertial scrolling", "fling scrolling"), it needs to know how the scrolling motion was implemented, and what to expect in the future. Add this information to the pointer axis event. The three scroll sources we have are: * wheels: scrolling is in discreet steps, you don't know when it ends, the wheel will just stop sending events * fingers: scrolling is continuous coordinate space, we know when it stops and we can tell the caller * continuous: scrolling is in continuous coordinate space but we may or may not know when it stops. if scroll lock is used, the device may never technically get out of scroll mode even if it doesn't send events at any given moment Use case: trackpoint/trackball scroll emulation on button press The stop event is now codified in the API documentation, so callers can use that for kinetic scrolling. libinput does not implement kinetic scrolling itself. Not covered by this patch: * The wheel event is currently defined as "typical mouse wheel step", this is different to Qt where the step value is 1/8 of a degree. Some better definition here may help. * It is unclear how an absolute device would map into relative motion if the device itself is not controlling absolute motion. * For diagonal scrolling, the vertical/horizontal terminator events would come in separately. The caller would have to deal with that somehow. Signed-off-by: Peter Hutterer Original patch, before the rebase onto today's master: Reviewed-by: Hans de Goede --- src/evdev-mt-touchpad-edge-scroll.c | 12 ++++-- src/evdev-mt-touchpad.c | 13 ++++-- src/evdev.c | 17 +++++++- src/evdev.h | 5 ++- src/libinput-private.h | 1 + src/libinput.c | 9 ++++ src/libinput.h | 65 +++++++++++++++++++++++++++-- src/libinput.sym | 1 + test/pointer.c | 2 + test/touchpad.c | 51 ++++++++++++++++++++++ test/trackpoint.c | 24 +++++++++++ 11 files changed, 188 insertions(+), 12 deletions(-) diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c index bc6831dd..a4dc0939 100644 --- a/src/evdev-mt-touchpad-edge-scroll.c +++ b/src/evdev-mt-touchpad-edge-scroll.c @@ -325,7 +325,9 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time) if (t->scroll.direction != -1) { /* Send stop scroll event */ pointer_notify_axis(device, time, - t->scroll.direction, 0.0); + t->scroll.direction, + LIBINPUT_POINTER_AXIS_SOURCE_FINGER, + 0.0); t->scroll.direction = -1; } continue; @@ -347,7 +349,9 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time) if (fabs(*delta) < t->scroll.threshold) continue; - pointer_notify_axis(device, time, axis, *delta); + pointer_notify_axis(device, time, axis, + LIBINPUT_POINTER_AXIS_SOURCE_FINGER, + *delta); t->scroll.direction = axis; tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_POSTED); @@ -365,7 +369,9 @@ tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time) tp_for_each_touch(tp, t) { if (t->scroll.direction != -1) { pointer_notify_axis(device, time, - t->scroll.direction, 0.0); + t->scroll.direction, + LIBINPUT_POINTER_AXIS_SOURCE_FINGER, + 0.0); t->scroll.direction = -1; } } diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 0f3e72a6..7e8306d4 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -435,7 +435,10 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time) tp_filter_motion(tp, &dx, &dy, NULL, NULL, time); - evdev_post_scroll(tp->device, time, dx, dy); + evdev_post_scroll(tp->device, + time, + LIBINPUT_POINTER_AXIS_SOURCE_FINGER, + dx, dy); tp->scroll.twofinger_state = TWOFINGER_SCROLL_STATE_ACTIVE; } @@ -445,7 +448,9 @@ tp_twofinger_stop_scroll(struct tp_dispatch *tp, uint64_t time) struct tp_touch *t, *ptr = NULL; int nfingers_down = 0; - evdev_stop_scroll(tp->device, time); + evdev_stop_scroll(tp->device, + time, + LIBINPUT_POINTER_AXIS_SOURCE_FINGER); /* If we were scrolling and now there's exactly 1 active finger, switch back to pointer movement */ @@ -846,7 +851,9 @@ tp_trackpoint_event(uint64_t time, struct libinput_event *event, void *data) return; if (!tp->sendevents.trackpoint_active) { - evdev_stop_scroll(tp->device, time); + evdev_stop_scroll(tp->device, + time, + LIBINPUT_POINTER_AXIS_SOURCE_FINGER); tp_tap_suspend(tp, time); tp->sendevents.trackpoint_active = true; } diff --git a/src/evdev.c b/src/evdev.c index 06dd1df1..1718491d 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -222,6 +222,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time) hw_is_key_down(device, device->scroll.button)) { if (device->scroll.button_scroll_active) evdev_post_scroll(device, time, + LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS, dx_unaccel, dy_unaccel); break; } @@ -394,7 +395,8 @@ evdev_button_scroll_button(struct evdev_device *device, } else { libinput_timer_cancel(&device->scroll.timer); if (device->scroll.button_scroll_active) { - evdev_stop_scroll(device, time); + evdev_stop_scroll(device, time, + LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS); device->scroll.button_scroll_active = false; } else { /* If the button is released quickly enough emit the @@ -538,6 +540,7 @@ static void evdev_notify_axis(struct evdev_device *device, uint64_t time, enum libinput_pointer_axis axis, + enum libinput_pointer_axis_source source, double value) { if (device->scroll.natural_scrolling_enabled) @@ -546,6 +549,7 @@ evdev_notify_axis(struct evdev_device *device, pointer_notify_axis(&device->base, time, axis, + source, value); } @@ -572,6 +576,7 @@ evdev_process_relative(struct evdev_device *device, device, time, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, + LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, -1 * e->value * DEFAULT_AXIS_STEP_DISTANCE); break; case REL_HWHEEL: @@ -580,6 +585,7 @@ evdev_process_relative(struct evdev_device *device, device, time, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, + LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, e->value * DEFAULT_AXIS_STEP_DISTANCE); break; } @@ -1781,6 +1787,7 @@ evdev_start_scrolling(struct evdev_device *device, void evdev_post_scroll(struct evdev_device *device, uint64_t time, + enum libinput_pointer_axis_source source, double dx, double dy) { @@ -1831,6 +1838,7 @@ evdev_post_scroll(struct evdev_device *device, evdev_notify_axis(device, time, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, + source, dy); } @@ -1840,23 +1848,28 @@ evdev_post_scroll(struct evdev_device *device, evdev_notify_axis(device, time, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, + source, dx); } } void -evdev_stop_scroll(struct evdev_device *device, uint64_t time) +evdev_stop_scroll(struct evdev_device *device, + uint64_t time, + enum libinput_pointer_axis_source source) { /* terminate scrolling with a zero scroll event */ if (device->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) pointer_notify_axis(&device->base, time, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, + source, 0); if (device->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) pointer_notify_axis(&device->base, time, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, + source, 0); device->scroll.buildup_horizontal = 0; diff --git a/src/evdev.h b/src/evdev.h index 820fdccd..a75dd134 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -298,12 +298,15 @@ evdev_init_natural_scroll(struct evdev_device *device); void evdev_post_scroll(struct evdev_device *device, uint64_t time, + enum libinput_pointer_axis_source source, double dx, double dy); void -evdev_stop_scroll(struct evdev_device *device, uint64_t time); +evdev_stop_scroll(struct evdev_device *device, + uint64_t time, + enum libinput_pointer_axis_source source); void evdev_device_remove(struct evdev_device *device); diff --git a/src/libinput-private.h b/src/libinput-private.h index b36dc954..84a0d440 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -279,6 +279,7 @@ void pointer_notify_axis(struct libinput_device *device, uint64_t time, enum libinput_pointer_axis axis, + enum libinput_pointer_axis_source source, double value); void diff --git a/src/libinput.c b/src/libinput.c index d78e26db..426c3069 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -65,6 +65,7 @@ struct libinput_event_pointer { uint32_t seat_button_count; enum libinput_button_state state; enum libinput_pointer_axis axis; + enum libinput_pointer_axis_source source; double value; }; @@ -390,6 +391,12 @@ libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event) return event->value; } +LIBINPUT_EXPORT enum libinput_pointer_axis_source +libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event) +{ + return event->source; +} + LIBINPUT_EXPORT uint32_t libinput_event_touch_get_time(struct libinput_event_touch *event) { @@ -986,6 +993,7 @@ void pointer_notify_axis(struct libinput_device *device, uint64_t time, enum libinput_pointer_axis axis, + enum libinput_pointer_axis_source source, double value) { struct libinput_event_pointer *axis_event; @@ -998,6 +1006,7 @@ pointer_notify_axis(struct libinput_device *device, .time = time, .axis = axis, .value = value, + .source = source, }; post_device_event(device, time, diff --git a/src/libinput.h b/src/libinput.h index d43b0f6a..0f251b5e 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -107,6 +107,28 @@ enum libinput_pointer_axis { LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL = 1, }; +/** + * @ingroup device + * + * The source for a libinput_pointer_axis event. See + * libinput_event_pointer_get_axis_source() for details. + */ +enum libinput_pointer_axis_source { + /** + * The event is caused by the rotation of a wheel. + */ + LIBINPUT_POINTER_AXIS_SOURCE_WHEEL = 1, + /** + * The event is caused by the movement of one or more fingers on a + * device. + */ + LIBINPUT_POINTER_AXIS_SOURCE_FINGER, + /** + * The event is caused by the motion of some device. + */ + LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS, +}; + /** * @ingroup base * @@ -651,9 +673,8 @@ libinput_event_pointer_get_axis(struct libinput_event_pointer *event); * @ref LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL and * @ref LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, the value of the event is in * relative scroll units, with the positive direction being down or right, - * respectively. The dimension of a scroll unit is equal to one unit of - * motion in the respective axis, where applicable (e.g. touchpad two-finger - * scrolling). + * respectively. For the interpretation of the value, see + * libinput_event_pointer_get_axis_source(). * * For pointer events that are not of type @ref LIBINPUT_EVENT_POINTER_AXIS, * this function returns 0. @@ -666,6 +687,44 @@ libinput_event_pointer_get_axis(struct libinput_event_pointer *event); double libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event); +/** + * @ingroup event_pointer + * + * Return the source for a given axis event. Axis events (scroll events) can + * be caused by a hardware item such as a scroll wheel or emulated from + * other input sources, such as two-finger or edge scrolling on a + * touchpad. + * + * If the source is @ref LIBINPUT_POINTER_AXIS_SOURCE_FINGER, libinput + * guarantees that a scroll sequence is terminated with a scroll value of 0. + * A caller may use this information to decide on whether kinetic scrolling + * should be triggered on this scroll sequence. + * The coordinate system is identical to the cursor movement, i.e. a + * scroll value of 1 represents the equivalent relative motion of 1. + * + * If the source is @ref LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, no terminating + * event is guaranteed (though it may happen). + * Scrolling is in discreet steps, a value of 10 representing one click + * of a typical mouse wheel. Some mice may have differently grained wheels, + * libinput will adjust the value accordingly. It is up to the caller how to + * interpret such different step sizes. + * + * If the source is @ref LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS, no + * terminating event is guaranteed (though it may happen). + * The coordinate system is identical to the cursor movement, i.e. a + * scroll value of 1 represents the equivalent relative motion of 1. + * + * For pointer events that are not of type LIBINPUT_EVENT_POINTER_AXIS, + * this function returns 0. + * + * @note It is an application bug to call this function for events other than + * LIBINPUT_EVENT_POINTER_AXIS. + * + * @return the source for this axis event + */ +enum libinput_pointer_axis_source +libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event); + /** * @ingroup event_pointer * diff --git a/src/libinput.sym b/src/libinput.sym index 057919c9..826bfde4 100644 --- a/src/libinput.sym +++ b/src/libinput.sym @@ -71,6 +71,7 @@ global: libinput_event_pointer_get_absolute_y; libinput_event_pointer_get_absolute_y_transformed; libinput_event_pointer_get_axis; + libinput_event_pointer_get_axis_source; libinput_event_pointer_get_axis_value; libinput_event_pointer_get_base_event; libinput_event_pointer_get_button_state; diff --git a/test/pointer.c b/test/pointer.c index dfed6b7d..b9bd3cc8 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -377,6 +377,8 @@ test_wheel_event(struct litest_device *dev, int which, int amount) LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL : LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev), expected); + ck_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev), + LIBINPUT_POINTER_AXIS_SOURCE_WHEEL); libinput_event_destroy(event); } diff --git a/test/touchpad.c b/test/touchpad.c index 19e1c284..422e8fe6 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -1461,6 +1461,29 @@ START_TEST(touchpad_2fg_scroll_slow_distance) } END_TEST +START_TEST(touchpad_2fg_scroll_source) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_pointer *ptrev; + + litest_drain_events(li); + + test_2fg_scroll(dev, 0, 20, 0); + litest_wait_for_event_of_type(li, LIBINPUT_EVENT_POINTER_AXIS, -1); + + while ((event = libinput_get_event(li))) { + ck_assert_int_eq(libinput_event_get_type(event), + LIBINPUT_EVENT_POINTER_AXIS); + ptrev = libinput_event_get_pointer_event(event); + ck_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev), + LIBINPUT_POINTER_AXIS_SOURCE_FINGER); + libinput_event_destroy(event); + } +} +END_TEST + START_TEST(touchpad_2fg_scroll_return_to_motion) { struct litest_device *dev = litest_current_device(); @@ -1666,6 +1689,32 @@ START_TEST(touchpad_edge_scroll_no_edge_after_motion) } END_TEST +START_TEST(touchpad_edge_scroll_source) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_pointer *ptrev; + + litest_drain_events(li); + + litest_touch_down(dev, 0, 99, 20); + litest_touch_move_to(dev, 0, 99, 20, 99, 80, 10, 0); + litest_touch_up(dev, 0); + + litest_wait_for_event_of_type(li, LIBINPUT_EVENT_POINTER_AXIS, -1); + + while ((event = libinput_get_event(li))) { + ck_assert_int_eq(libinput_event_get_type(event), + LIBINPUT_EVENT_POINTER_AXIS); + ptrev = libinput_event_get_pointer_event(event); + ck_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev), + LIBINPUT_POINTER_AXIS_SOURCE_FINGER); + libinput_event_destroy(event); + } +} +END_TEST + START_TEST(touchpad_tap_is_available) { struct litest_device *dev = litest_current_device(); @@ -2219,6 +2268,7 @@ int main(int argc, char **argv) { litest_add("touchpad:scroll", touchpad_2fg_scroll, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:scroll", touchpad_2fg_scroll_slow_distance, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:scroll", touchpad_2fg_scroll_return_to_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("touchpad:scroll", touchpad_2fg_scroll_source, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:scroll", touchpad_scroll_natural_defaults, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:scroll", touchpad_scroll_natural_enable_config, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:scroll", touchpad_scroll_natural, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); @@ -2226,6 +2276,7 @@ int main(int argc, char **argv) { litest_add("touchpad:scroll", touchpad_edge_scroll_no_motion, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY); litest_add("touchpad:scroll", touchpad_edge_scroll_no_edge_after_motion, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY); litest_add("touchpad:scroll", touchpad_edge_scroll_slow_distance, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY); + litest_add("touchpad:scroll", touchpad_edge_scroll_source, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY); litest_add("touchpad:palm", touchpad_palm_detect_at_edge, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:palm", touchpad_palm_detect_at_bottom_corners, LITEST_TOUCHPAD, LITEST_CLICKPAD); diff --git a/test/trackpoint.c b/test/trackpoint.c index 1d1a10a0..2708bad2 100644 --- a/test/trackpoint.c +++ b/test/trackpoint.c @@ -107,11 +107,35 @@ START_TEST(trackpoint_middlebutton_noscroll) } END_TEST +START_TEST(trackpoint_scroll_source) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_pointer *ptrev; + + litest_drain_events(li); + + litest_button_scroll(dev, BTN_MIDDLE, 0, 6); + litest_wait_for_event_of_type(li, LIBINPUT_EVENT_POINTER_AXIS, -1); + + while ((event = libinput_get_event(li))) { + ptrev = libinput_event_get_pointer_event(event); + + ck_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev), + LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS); + + libinput_event_destroy(event); + } +} +END_TEST + int main(int argc, char **argv) { litest_add("trackpoint:middlebutton", trackpoint_middlebutton, LITEST_POINTINGSTICK, LITEST_ANY); litest_add("trackpoint:middlebutton", trackpoint_middlebutton_noscroll, LITEST_POINTINGSTICK, LITEST_ANY); litest_add("trackpoint:scroll", trackpoint_scroll, LITEST_POINTINGSTICK, LITEST_ANY); + litest_add("trackpoint:scroll", trackpoint_scroll_source, LITEST_POINTINGSTICK, LITEST_ANY); return litest_run(argc, argv); } From 9c297aefae3538320aacc80142ad8c52370c291a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 5 Jan 2015 08:40:35 +1000 Subject: [PATCH 33/55] tools: change name/seat/logical seat format string Change the seat field widths to match the usual seat0/default. This compresses the output a bit, we're printing too much already. Also, one of my mice has >30 chars, it's annoying to look at. Fix this. Signed-off-by: Peter Hutterer --- tools/event-debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/event-debug.c b/tools/event-debug.c index da581c82..5750bcac 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -125,7 +125,7 @@ print_device_notify(struct libinput_event *ev) double w, h; uint32_t scroll_methods; - printf("%-30s %s %s", + printf("%-33s %5s %7s", libinput_device_get_name(dev), libinput_seat_get_physical_name(seat), libinput_seat_get_logical_name(seat)); From f11cd30f0088a0f921bc03ed4fe683db5797c13f Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 5 Jan 2015 08:36:00 +1000 Subject: [PATCH 34/55] tools: print device capabilities in event-debug Signed-off-by: Peter Hutterer --- tools/event-debug.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/event-debug.c b/tools/event-debug.c index 5750bcac..8fbea24a 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -130,6 +130,17 @@ print_device_notify(struct libinput_event *ev) libinput_seat_get_physical_name(seat), libinput_seat_get_logical_name(seat)); + printf(" cap:"); + if (libinput_device_has_capability(dev, + LIBINPUT_DEVICE_CAP_KEYBOARD)) + printf("k"); + if (libinput_device_has_capability(dev, + LIBINPUT_DEVICE_CAP_POINTER)) + printf("p"); + if (libinput_device_has_capability(dev, + LIBINPUT_DEVICE_CAP_TOUCH)) + printf("t"); + if (libinput_device_get_size(dev, &w, &h) == 0) printf("\tsize %.2f/%.2fmm", w, h); From f0abc31f1c8de54d48e277dcaa01385c133e8de7 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 24 Dec 2014 11:12:41 +1000 Subject: [PATCH 35/55] Minor documentation wording improvement Signed-off-by: Peter Hutterer --- src/libinput.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libinput.h b/src/libinput.h index 0f251b5e..56b77c23 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -669,7 +669,7 @@ libinput_event_pointer_get_axis(struct libinput_event_pointer *event); * @ingroup event_pointer * * Return the axis value of the given axis. The interpretation of the value - * is dependent on the axis. For the two scrolling axes + * depends on the axis. For the two scrolling axes * @ref LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL and * @ref LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, the value of the event is in * relative scroll units, with the positive direction being down or right, From bdb8fd911c096fc0f16d9bb7fda9f941d52235d6 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 6 Jan 2015 08:50:03 +1000 Subject: [PATCH 36/55] Drop unused function calc_penumbral_gradient Unused since 4913fd7a4806e54ebe4eb7f5f3f1d2fa3b8fdbdb Signed-off-by: Peter Hutterer --- src/filter.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/filter.c b/src/filter.c index afb87ef2..89390d12 100644 --- a/src/filter.c +++ b/src/filter.c @@ -308,14 +308,6 @@ create_pointer_accelerator_filter(accel_profile_func_t profile) return &filter->base; } -static inline double -calc_penumbral_gradient(double x) -{ - x *= 2.0; - x -= 1.0; - return 0.5 + (x * sqrt(1.0 - x * x) + asin(x)) / M_PI; -} - double pointer_accel_profile_linear(struct motion_filter *filter, void *data, From f9ccfdb49a57b891493ccef4854de27163859b16 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 6 Jan 2015 08:52:49 +1000 Subject: [PATCH 37/55] test: drop empty test device interfaces We can just set the interface component to NULL directly instead. Fixes clang warnings: litest-mouse.c:38:1: warning: missing field 'touch_move' initializer [-Wmissing-field-initializers] litest-trackpoint.c:38:1: warning: missing field 'touch_move' initializer [-Wmissing-field-initializers] Signed-off-by: Peter Hutterer --- test/litest-mouse.c | 6 +----- test/litest-trackpoint.c | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/test/litest-mouse.c b/test/litest-mouse.c index cf0a7a05..3f68521f 100644 --- a/test/litest-mouse.c +++ b/test/litest-mouse.c @@ -33,10 +33,6 @@ static void litest_mouse_setup(void) litest_set_current_device(d); } -static struct litest_device_interface interface = { - NULL -}; - static struct input_id input_id = { .bustype = 0x3, .vendor = 0x17ef, @@ -58,7 +54,7 @@ struct litest_test_device litest_mouse_device = { .features = LITEST_RELATIVE | LITEST_BUTTON | LITEST_WHEEL, .shortname = "mouse", .setup = litest_mouse_setup, - .interface = &interface, + .interface = NULL, .name = "Lenovo Optical USB Mouse", .id = &input_id, diff --git a/test/litest-trackpoint.c b/test/litest-trackpoint.c index 061835fc..09f8b704 100644 --- a/test/litest-trackpoint.c +++ b/test/litest-trackpoint.c @@ -33,10 +33,6 @@ static void litest_trackpoint_setup(void) litest_set_current_device(d); } -static struct litest_device_interface interface = { - NULL -}; - static struct input_id input_id = { .bustype = 0x11, .vendor = 0x2, @@ -59,7 +55,7 @@ struct litest_test_device litest_trackpoint_device = { .features = LITEST_RELATIVE | LITEST_BUTTON | LITEST_POINTINGSTICK, .shortname = "trackpoint", .setup = litest_trackpoint_setup, - .interface = &interface, + .interface = NULL, .name = "TPPS/2 IBM TrackPoint", .id = &input_id, From 70a34b0bc435a023264f479a0793b3bfe9c4ecb1 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 6 Jan 2015 08:49:11 +1000 Subject: [PATCH 38/55] test: fix a clang compiler warning misc.c:562:10: warning: missing field 'expected_dpi' initializer [-Wmissing-field-initializers] { NULL } Signed-off-by: Peter Hutterer --- test/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/misc.c b/test/misc.c index 4d4c22ca..c7d9ddf5 100644 --- a/test/misc.c +++ b/test/misc.c @@ -559,7 +559,7 @@ START_TEST(dpi_parser) { "", 0 }, { " ", 0 }, { "* ", 0 }, - { NULL } + { NULL, 0 } }; int i, dpi; From d61f050d7fc46122411af8b4f8bd55045e67ac68 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 6 Jan 2015 09:34:06 +1000 Subject: [PATCH 39/55] touchpad: fix a clang compiler warning Causes the valgrind tests to fail as tp is considered uninitialized. Signed-off-by: Peter Hutterer --- src/evdev-mt-touchpad-tap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index c34b2034..0e37c5ee 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -664,8 +664,9 @@ tp_tap_config_set_enabled(struct libinput_device *device, enum libinput_config_tap_state enabled) { struct evdev_dispatch *dispatch = ((struct evdev_device *) device)->dispatch; - struct tp_dispatch *tp = container_of(dispatch, tp, base); + struct tp_dispatch *tp = NULL; + tp = container_of(dispatch, tp, base); tp_tap_enabled_update(tp, tp->tap.suspended, (enabled == LIBINPUT_CONFIG_TAP_ENABLED), libinput_now(device->seat->libinput)); From bdebf2bc4e40ea4d3edb1ab59d2a60cfbcac95e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 7 Jan 2015 12:03:53 +0800 Subject: [PATCH 40/55] s/discreet/discrete/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Discreet means to not draw attention. Discrete means non-continuous. Signed-off-by: Jonas Ådahl Reviewed-by: Peter Hutterer --- src/libinput.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libinput.h b/src/libinput.h index 56b77c23..6cb3a9e2 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -704,7 +704,7 @@ libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event); * * If the source is @ref LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, no terminating * event is guaranteed (though it may happen). - * Scrolling is in discreet steps, a value of 10 representing one click + * Scrolling is in discrete steps, a value of 10 representing one click * of a typical mouse wheel. Some mice may have differently grained wheels, * libinput will adjust the value accordingly. It is up to the caller how to * interpret such different step sizes. @@ -1954,7 +1954,7 @@ libinput_device_config_accel_is_available(struct libinput_device *device); * this device. The actual pointer acceleration mechanism is * implementation-dependent, as is the number of steps available within the * range. libinput picks the semantically closest acceleration step if the - * requested value does not match a discreet setting. + * requested value does not match a discrete setting. * * @param device The device to configure * @param speed The normalized speed, in a range of [-1, 1] From 2b00d24a944e9a8db6ce0c93f7582f6e4145ed69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 7 Jan 2015 12:10:28 +0800 Subject: [PATCH 41/55] Dropped an extra 'the' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonas Ådahl Reviewed-by: Peter Hutterer --- src/libinput.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libinput.h b/src/libinput.h index 6cb3a9e2..27c5868d 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -638,7 +638,7 @@ libinput_event_pointer_get_button_state(struct libinput_event_pointer *event); * * For the button of a @ref LIBINPUT_EVENT_POINTER_BUTTON event, return the * total number of buttons pressed on all devices on the associated seat - * after the the event was triggered. + * after the event was triggered. * " @note It is an application bug to call this function for events other than * @ref LIBINPUT_EVENT_POINTER_BUTTON. For other events, this function From 01b0c8fbf58607638765bc19d8e6b38c29635cd1 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 7 Jan 2015 14:09:00 +1000 Subject: [PATCH 42/55] tools: fail if we can't set up signal handlers in event-debug Signed-off-by: Peter Hutterer --- tools/event-debug.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/event-debug.c b/tools/event-debug.c index 8fbea24a..c567550f 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -351,6 +351,7 @@ mainloop(struct libinput *li) sigprocmask(SIG_BLOCK, &mask, NULL) == -1) { fprintf(stderr, "Failed to set up signal handling (%s)\n", strerror(errno)); + return; } /* Handle already-pending device added events */ From fe8e6706bd847ddfe43337d544f88318ec63946d Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 7 Jan 2015 14:32:16 +1000 Subject: [PATCH 43/55] tools: switch signal handler in event-debug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Under gdb, signalfd will still deliver the signal when gdb itself is interrupted and quit event-debug. For a debugging tool, that's not optimal. Switch to a normal signal handler instead, signalfd is overkill here anyway. Signed-off-by: Peter Hutterer Reviewed-by: Jonas Ådahl --- tools/event-debug.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/tools/event-debug.c b/tools/event-debug.c index c567550f..090fc3f0 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -32,7 +32,6 @@ #include #include "linux/input.h" #include -#include #include @@ -42,6 +41,7 @@ uint32_t start_time; static const uint32_t screen_width = 100; static const uint32_t screen_height = 100; struct tools_options options; +static unsigned int stop = 0; static int open_restricted(const char *path, int flags, void *user_data) @@ -330,25 +330,27 @@ handle_and_print_events(struct libinput *li) return rc; } +static void +sighandler(int signal, siginfo_t *siginfo, void *userdata) +{ + stop = 1; +} + static void mainloop(struct libinput *li) { - struct pollfd fds[2]; - sigset_t mask; + struct pollfd fds; + struct sigaction act; - fds[0].fd = libinput_get_fd(li); - fds[0].events = POLLIN; - fds[0].revents = 0; + fds.fd = libinput_get_fd(li); + fds.events = POLLIN; + fds.revents = 0; - sigemptyset(&mask); - sigaddset(&mask, SIGINT); + memset(&act, 0, sizeof(act)); + act.sa_sigaction = sighandler; + act.sa_flags = SA_SIGINFO; - fds[1].fd = signalfd(-1, &mask, SFD_NONBLOCK); - fds[1].events = POLLIN; - fds[1].revents = 0; - - if (fds[1].fd == -1 || - sigprocmask(SIG_BLOCK, &mask, NULL) == -1) { + if (sigaction(SIGINT, &act, NULL) == -1) { fprintf(stderr, "Failed to set up signal handling (%s)\n", strerror(errno)); return; @@ -359,14 +361,8 @@ mainloop(struct libinput *li) fprintf(stderr, "Expected device added events on startup but got none. " "Maybe you don't have the right permissions?\n"); - while (poll(fds, 2, -1) > -1) { - if (fds[1].revents) - break; - + while (!stop && poll(&fds, 1, -1) > -1) handle_and_print_events(li); - } - - close(fds[1].fd); } int From 6ba8f547d251f91cb539c4c6fd0b22e73ae76bcd Mon Sep 17 00:00:00 2001 From: Marek Chalupa Date: Fri, 9 Jan 2015 10:34:46 +0100 Subject: [PATCH 44/55] build-pedantic: use main(void) Main has unused parameters argc and argv. Since they are unused and C 99 allows to prototype main as 'int main(void)', remove them and replace by void. It fixes build when unused parameters are treated as errors. Signed-off-by: Marek Chalupa Signed-off-by: Peter Hutterer --- test/build-pedantic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/build-pedantic.c b/test/build-pedantic.c index 1dfb67df..920fc4ab 100644 --- a/test/build-pedantic.c +++ b/test/build-pedantic.c @@ -3,6 +3,6 @@ /* This is a build-test only */ int -main(int argc, char **argv) { +main(void) { return 0; } From d28da2ca4ea8f5a51d97980b9e9cc184db5e5171 Mon Sep 17 00:00:00 2001 From: Stephen Chandler Paul Date: Mon, 5 Jan 2015 17:44:37 -0500 Subject: [PATCH 45/55] libinput.h: Fix some line wrapping in documentation Signed-off-by: Peter Hutterer --- src/libinput.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libinput.h b/src/libinput.h index 27c5868d..d0518cc6 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -2141,8 +2141,8 @@ libinput_device_config_buttons_get_left_handed(struct libinput_device *device); * Get the default left-handed configuration of the device. * * @param device The device to configure - * @return Zero if the device is in right-handed mode by default, or non-zero if the - * device is in left-handed mode by default + * @return Zero if the device is in right-handed mode by default, or non-zero + * if the device is in left-handed mode by default * * @see libinput_device_config_buttons_has_left_handed * @see libinput_device_config_buttons_set_left_handed From 2ff009a45dd59caf8747b5bbf0e16358a1a741a1 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 12 Jan 2015 08:15:12 +1000 Subject: [PATCH 46/55] Add a comment to clarify what the prop parameter is prop isn't the full property line, just the value. And document the return value too while we're at it. Signed-off-by: Peter Hutterer --- src/libinput-util.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libinput-util.c b/src/libinput-util.c index 923e1162..c16de1bf 100644 --- a/src/libinput-util.c +++ b/src/libinput-util.c @@ -131,6 +131,9 @@ ratelimit_test(struct ratelimit *r) * use a reasonable default instead. If the property contains multiple DPI * settings but none flagged as default, we return the last because we're * lazy and that's a silly way to set the property anyway. + * + * @param prop The value of the udev property (without the MOUSE_DPI=) + * @return The default dpi value on success, 0 on error */ int parse_mouse_dpi_property(const char *prop) From 2708be27b29ad7f7cc5d99a8ba0ebba490847e01 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 9 Jan 2015 17:03:45 +1000 Subject: [PATCH 47/55] Change the scroll step distance to 15 and document it as degrees MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to the mouse resolution, let's make the scroll distance a sensible predictable value. Most mice use a 15 degree angle per scroll click, so let's change to that. This will alter behaviour in clients that expect 10. We return doubles for the axis value, so that leaves the option of really fine-grained step sizes in the future. We currently assume all mice have 15 degree angles. Like the DPI settings, it will require a udev property to be set. Patch for that to follow. Signed-off-by: Peter Hutterer Reviewed-by: Jonas Ådahl --- src/evdev.c | 6 +++--- src/libinput.h | 8 ++++---- test/pointer.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index 1718491d..d8b61299 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -40,7 +40,7 @@ #include "filter.h" #include "libinput-private.h" -#define DEFAULT_AXIS_STEP_DISTANCE 10 +#define DEFAULT_WHEEL_CLICK_ANGLE 15 #define DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT 200 enum evdev_key_type { @@ -577,7 +577,7 @@ evdev_process_relative(struct evdev_device *device, time, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, - -1 * e->value * DEFAULT_AXIS_STEP_DISTANCE); + -1 * e->value * DEFAULT_WHEEL_CLICK_ANGLE); break; case REL_HWHEEL: evdev_flush_pending_event(device, time); @@ -586,7 +586,7 @@ evdev_process_relative(struct evdev_device *device, time, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, - e->value * DEFAULT_AXIS_STEP_DISTANCE); + e->value * DEFAULT_WHEEL_CLICK_ANGLE); break; } } diff --git a/src/libinput.h b/src/libinput.h index d0518cc6..f605e52b 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -704,10 +704,10 @@ libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event); * * If the source is @ref LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, no terminating * event is guaranteed (though it may happen). - * Scrolling is in discrete steps, a value of 10 representing one click - * of a typical mouse wheel. Some mice may have differently grained wheels, - * libinput will adjust the value accordingly. It is up to the caller how to - * interpret such different step sizes. + * Scrolling is in discrete steps, the value is the angle the wheel moved + * in degrees. The default is 15 degrees per wheel click, but some mice may + * have differently grained wheels. It is up to the caller how to interpret + * such different step sizes. * * If the source is @ref LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS, no * terminating event is guaranteed (though it may happen). diff --git a/test/pointer.c b/test/pointer.c index b9bd3cc8..d12c9f6b 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -350,8 +350,8 @@ test_wheel_event(struct litest_device *dev, int which, int amount) struct libinput_event_pointer *ptrev; /* the current evdev implementation scales the scroll wheel events - up by a factor 10 */ - const int scroll_step = 10; + up by a factor 15 */ + const int scroll_step = 15; int expected = amount * scroll_step; if (libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device)) From c35885e87dabdcba016cbfa124c384dd440411f1 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 12 Jan 2015 08:39:47 +1000 Subject: [PATCH 48/55] Parse the MOUSE_WHEEL_CLICK_ANGLE udev property if present MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Hutterer Reviewed-by: Jonas Ådahl --- doc/device-configuration-via-udev.dox | 4 ++++ src/evdev.c | 29 +++++++++++++++++++++-- src/evdev.h | 3 +++ src/libinput-util.c | 30 +++++++++++++++++++++++ src/libinput-util.h | 1 + test/misc.c | 34 +++++++++++++++++++++++++-- 6 files changed, 97 insertions(+), 4 deletions(-) diff --git a/doc/device-configuration-via-udev.dox b/doc/device-configuration-via-udev.dox index b8540351..bee36598 100644 --- a/doc/device-configuration-via-udev.dox +++ b/doc/device-configuration-via-udev.dox @@ -23,6 +23,10 @@ context. Defaults to "default".
HW resolution and sampling frequency of a relative pointer device. See @ref motion_normalization for details.
+
MOUSE_WHEEL_CLICK_ANGLE
+
The angle in degrees for each click on a mouse wheel. See +libinput_pointer_get_axis_source() for details. +
Below is an example udev rule to assign "seat1" to a device from vendor diff --git a/src/evdev.c b/src/evdev.c index d8b61299..d80594df 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -577,7 +577,7 @@ evdev_process_relative(struct evdev_device *device, time, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, - -1 * e->value * DEFAULT_WHEEL_CLICK_ANGLE); + -1 * e->value * device->scroll.wheel_click_angle); break; case REL_HWHEEL: evdev_flush_pending_event(device, time); @@ -586,7 +586,7 @@ evdev_process_relative(struct evdev_device *device, time, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, - e->value * DEFAULT_WHEEL_CLICK_ANGLE); + e->value * device->scroll.wheel_click_angle); break; } } @@ -1239,6 +1239,29 @@ evdev_tag_device(struct evdev_device *device) device->udev_device); } +static inline int +evdev_read_wheel_click_prop(struct evdev_device *device) +{ + struct libinput *libinput = device->base.seat->libinput; + const char *prop; + int angle = DEFAULT_WHEEL_CLICK_ANGLE; + + prop = udev_device_get_property_value(device->udev_device, + "MOUSE_WHEEL_CLICK_ANGLE"); + if (prop) { + angle = parse_mouse_wheel_click_angle_property(prop); + if (!angle) { + log_error(libinput, + "Mouse wheel click angle '%s' is present but invalid," + "using %d degrees instead\n", + device->devname, + DEFAULT_WHEEL_CLICK_ANGLE); + angle = DEFAULT_WHEEL_CLICK_ANGLE; + } + } + + return angle; +} static inline int evdev_read_dpi_prop(struct evdev_device *device) { @@ -1568,6 +1591,8 @@ evdev_device_create(struct libinput_seat *seat, device->devname = libevdev_get_name(device->evdev); device->scroll.threshold = 5.0; /* Default may be overridden */ device->scroll.direction = 0; + device->scroll.wheel_click_angle = + evdev_read_wheel_click_prop(device); device->dpi = evdev_read_dpi_prop(device); /* at most 5 SYN_DROPPED log-messages per 30s */ ratelimit_init(&device->syn_drop_limit, 30ULL * 1000, 5); diff --git a/src/evdev.h b/src/evdev.h index a75dd134..2171c5ad 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -119,6 +119,9 @@ struct evdev_device { /* set during device init if we want natural scrolling, * used at runtime to enable/disable the feature */ bool natural_scrolling_enabled; + + /* angle per REL_WHEEL click in degrees */ + int wheel_click_angle; } scroll; enum evdev_event_type pending_event; diff --git a/src/libinput-util.c b/src/libinput-util.c index c16de1bf..49e297af 100644 --- a/src/libinput-util.c +++ b/src/libinput-util.c @@ -171,3 +171,33 @@ parse_mouse_dpi_property(const char *prop) } return dpi; } + +/** + * Helper function to parse the MOUSE_WHEEL_CLICK_ANGLE property from udev. + * Property is of the form: + * MOUSE_WHEEL_CLICK_ANGLE= + * Where the number indicates the degrees travelled for each click. + * + * We skip preceding whitespaces and parse the first number seen. If + * multiple numbers are specified, we ignore those. + * + * @param prop The value of the udev property (without the MOUSE_WHEEL_CLICK_ANGLE=) + * @return The angle of the wheel (may be negative) or 0 on error. + */ +int +parse_mouse_wheel_click_angle_property(const char *prop) +{ + int angle = 0, + nread = 0; + + while(*prop != 0 && *prop == ' ') + prop++; + + sscanf(prop, "%d%n", &angle, &nread); + if (nread == 0 || angle == 0 || abs(angle) > 360) + return 0; + if (prop[nread] != ' ' && prop[nread] != '\0') + return 0; + + return angle; +} diff --git a/src/libinput-util.h b/src/libinput-util.h index 68258414..dc70bcd2 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -297,5 +297,6 @@ void ratelimit_init(struct ratelimit *r, uint64_t ival_ms, unsigned int burst); enum ratelimit_state ratelimit_test(struct ratelimit *r); int parse_mouse_dpi_property(const char *prop); +int parse_mouse_wheel_click_angle_property(const char *prop); #endif /* LIBINPUT_UTIL_H */ diff --git a/test/misc.c b/test/misc.c index c7d9ddf5..779b600f 100644 --- a/test/misc.c +++ b/test/misc.c @@ -531,7 +531,7 @@ END_TEST struct parser_test { char *tag; - int expected_dpi; + int expected_value; }; START_TEST(dpi_parser) @@ -565,7 +565,36 @@ START_TEST(dpi_parser) for (i = 0; tests[i].tag != NULL; i++) { dpi = parse_mouse_dpi_property(tests[i].tag); - ck_assert_int_eq(dpi, tests[i].expected_dpi); + ck_assert_int_eq(dpi, tests[i].expected_value); + } +} +END_TEST + +START_TEST(wheel_click_parser) +{ + struct parser_test tests[] = { + { "1", 1 }, + { "10", 10 }, + { "-12", -12 }, + { "360", 360 }, + { "66 ", 66 }, + { " 100 ", 100 }, + + { "0", 0 }, + { "-0", 0 }, + { "a", 0 }, + { "10a", 0 }, + { "10-", 0 }, + { "sadfasfd", 0 }, + { "361", 0 }, + { NULL, 0 } + }; + + int i, angle; + + for (i = 0; tests[i].tag != NULL; i++) { + angle = parse_mouse_wheel_click_angle_property(tests[i].tag); + ck_assert_int_eq(angle, tests[i].expected_value); } } END_TEST @@ -582,6 +611,7 @@ int main (int argc, char **argv) { litest_add_no_device("misc:matrix", matrix_helpers); litest_add_no_device("misc:ratelimit", ratelimit_helpers); litest_add_no_device("misc:dpi parser", dpi_parser); + litest_add_no_device("misc:wheel click parser", wheel_click_parser); return litest_run(argc, argv); } From 1baf109b40e5d610cb46d313d7c412419af8c9e0 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 24 Dec 2014 11:10:04 +1000 Subject: [PATCH 49/55] Change axis events to carry all directions Sending separate axis events instead of one unified events is limiting, especially when simultaneously scrolling in both directions and the caller tries to implement kinetic scrolling. Take a page from the tablet-support branch and instead implement the axis event as a generic event that can contain multiple axes simultaneously. Right now we only have two (scroll) axes and we could easily just check both for non-zero values. If we want to allow further axes in the future, we need a check whether an axis is set in an event, that's what libinput_event_pointer_has_axis to scroll events() is for. We also need the mask to notify of a scroll stop event, which could otherwise be confused as a vertical-only or horizontal-only event. This is an API and ABI break. Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- src/evdev-mt-touchpad-edge-scroll.c | 13 +++--- src/evdev.c | 63 +++++++++++++---------------- src/libinput-private.h | 4 +- src/libinput-util.h | 1 + src/libinput.c | 47 ++++++++++++++++----- src/libinput.h | 22 +++++----- src/libinput.sym | 1 + test/litest.c | 19 ++++----- test/pointer.c | 11 +++-- test/touchpad.c | 16 ++++---- tools/event-debug.c | 26 +++++------- tools/event-gui.c | 18 ++++----- 12 files changed, 133 insertions(+), 108 deletions(-) diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c index a4dc0939..6268986a 100644 --- a/src/evdev-mt-touchpad-edge-scroll.c +++ b/src/evdev-mt-touchpad-edge-scroll.c @@ -325,9 +325,9 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time) if (t->scroll.direction != -1) { /* Send stop scroll event */ pointer_notify_axis(device, time, - t->scroll.direction, + AS_MASK(t->scroll.direction), LIBINPUT_POINTER_AXIS_SOURCE_FINGER, - 0.0); + 0.0, 0.0); t->scroll.direction = -1; } continue; @@ -349,9 +349,10 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time) if (fabs(*delta) < t->scroll.threshold) continue; - pointer_notify_axis(device, time, axis, + pointer_notify_axis(device, time, + AS_MASK(axis), LIBINPUT_POINTER_AXIS_SOURCE_FINGER, - *delta); + dx, dy); t->scroll.direction = axis; tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_POSTED); @@ -369,9 +370,9 @@ tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time) tp_for_each_touch(tp, t) { if (t->scroll.direction != -1) { pointer_notify_axis(device, time, - t->scroll.direction, + AS_MASK(t->scroll.direction), LIBINPUT_POINTER_AXIS_SOURCE_FINGER, - 0.0); + 0.0, 0.0); t->scroll.direction = -1; } } diff --git a/src/evdev.c b/src/evdev.c index d80594df..076db29f 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -539,18 +539,20 @@ evdev_process_absolute_motion(struct evdev_device *device, static void evdev_notify_axis(struct evdev_device *device, uint64_t time, - enum libinput_pointer_axis axis, + uint32_t axes, enum libinput_pointer_axis_source source, - double value) + double x, double y) { - if (device->scroll.natural_scrolling_enabled) - value *= -1; + if (device->scroll.natural_scrolling_enabled) { + x *= -1; + y *= -1; + } pointer_notify_axis(&device->base, time, - axis, + axes, source, - value); + x, y); } static inline void @@ -575,8 +577,9 @@ evdev_process_relative(struct evdev_device *device, evdev_notify_axis( device, time, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, + AS_MASK(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL), LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, + 0, -1 * e->value * device->scroll.wheel_click_angle); break; case REL_HWHEEL: @@ -584,9 +587,10 @@ evdev_process_relative(struct evdev_device *device, evdev_notify_axis( device, time, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, + AS_MASK(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL), LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, - e->value * device->scroll.wheel_click_angle); + e->value * device->scroll.wheel_click_angle, + 0); break; } } @@ -1796,7 +1800,7 @@ evdev_is_scrolling(const struct evdev_device *device, assert(axis == LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL || axis == LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - return (device->scroll.direction & (1 << axis)) != 0; + return (device->scroll.direction & AS_MASK(axis)) != 0; } static inline void @@ -1806,7 +1810,7 @@ evdev_start_scrolling(struct evdev_device *device, assert(axis == LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL || axis == LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - device->scroll.direction |= (1 << axis); + device->scroll.direction |= AS_MASK(axis); } void @@ -1857,25 +1861,20 @@ evdev_post_scroll(struct evdev_device *device, /* We use the trigger to enable, but the delta from this event for * the actual scroll movement. Otherwise we get a jump once * scrolling engages */ - if (dy != 0.0 && - evdev_is_scrolling(device, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) { - evdev_notify_axis(device, - time, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, - source, - dy); - } + if (!evdev_is_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) + dy = 0.0; + if (!evdev_is_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) + dx = 0.0; - if (dx != 0.0 && - evdev_is_scrolling(device, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) { + if (dx != 0.0 || dy != 0.0) evdev_notify_axis(device, time, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, + device->scroll.direction, source, - dx); - } + dx, + dy); } void @@ -1884,18 +1883,12 @@ evdev_stop_scroll(struct evdev_device *device, enum libinput_pointer_axis_source source) { /* terminate scrolling with a zero scroll event */ - if (device->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) + if (device->scroll.direction != 0) pointer_notify_axis(&device->base, time, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, + device->scroll.direction, source, - 0); - if (device->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) - pointer_notify_axis(&device->base, - time, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, - source, - 0); + 0.0, 0.0); device->scroll.buildup_horizontal = 0; device->scroll.buildup_vertical = 0; diff --git a/src/libinput-private.h b/src/libinput-private.h index 84a0d440..0cb9b259 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -278,9 +278,9 @@ pointer_notify_button(struct libinput_device *device, void pointer_notify_axis(struct libinput_device *device, uint64_t time, - enum libinput_pointer_axis axis, + uint32_t axes, enum libinput_pointer_axis_source source, - double value); + double x, double y); void touch_notify_touch_down(struct libinput_device *device, diff --git a/src/libinput-util.h b/src/libinput-util.h index dc70bcd2..f76439f1 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -79,6 +79,7 @@ int list_empty(const struct list *list); #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) #define ARRAY_FOR_EACH(_arr, _elem) \ for (size_t _i = 0; _i < ARRAY_LENGTH(_arr) && (_elem = &_arr[_i]); _i++) +#define AS_MASK(v) (1 << (v)) #define min(a, b) (((a) < (b)) ? (a) : (b)) #define max(a, b) (((a) > (b)) ? (a) : (b)) diff --git a/src/libinput.c b/src/libinput.c index 426c3069..2442b065 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -64,9 +64,8 @@ struct libinput_event_pointer { uint32_t button; uint32_t seat_button_count; enum libinput_button_state state; - enum libinput_pointer_axis axis; enum libinput_pointer_axis_source source; - double value; + uint32_t axes; }; struct libinput_event_touch { @@ -379,16 +378,41 @@ libinput_event_pointer_get_seat_button_count( return event->seat_button_count; } -LIBINPUT_EXPORT enum libinput_pointer_axis -libinput_event_pointer_get_axis(struct libinput_event_pointer *event) +LIBINPUT_EXPORT int +libinput_event_pointer_has_axis(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis) { - return event->axis; + if (event->base.type == LIBINPUT_EVENT_POINTER_AXIS) { + switch (axis) { + case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + return !!(event->axes & AS_MASK(axis)); + } + } + return 0; } LIBINPUT_EXPORT double -libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event) +libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis) { - return event->value; + struct libinput *libinput = event->base.device->seat->libinput; + double value = 0; + + if (!libinput_event_pointer_has_axis(event, axis)) { + log_bug_client(libinput, "value requested for unset axis\n"); + } else { + switch (axis) { + case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: + value = event->x; + break; + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + value = event->y; + break; + } + } + + return value; } LIBINPUT_EXPORT enum libinput_pointer_axis_source @@ -992,9 +1016,9 @@ pointer_notify_button(struct libinput_device *device, void pointer_notify_axis(struct libinput_device *device, uint64_t time, - enum libinput_pointer_axis axis, + uint32_t axes, enum libinput_pointer_axis_source source, - double value) + double x, double y) { struct libinput_event_pointer *axis_event; @@ -1004,9 +1028,10 @@ pointer_notify_axis(struct libinput_device *device, *axis_event = (struct libinput_event_pointer) { .time = time, - .axis = axis, - .value = value, + .x = x, + .y = y, .source = source, + .axes = axes, }; post_device_event(device, time, diff --git a/src/libinput.h b/src/libinput.h index f605e52b..89cc0f09 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -653,17 +653,17 @@ libinput_event_pointer_get_seat_button_count( /** * @ingroup event_pointer * - * Return the axis that triggered this event. - * For pointer events that are not of type @ref LIBINPUT_EVENT_POINTER_AXIS, - * this function returns 0. + * Check if the event has a valid value for the given axis. * - * @note It is an application bug to call this function for events other than - * @ref LIBINPUT_EVENT_POINTER_AXIS. + * If this function returns non-zero for an axis and + * libinput_event_pointer_get_axis_value() returns a value of 0, the event + * is a scroll stop event. * - * @return the axis triggering this event + * @return non-zero if this event contains a value for this axis */ -enum libinput_pointer_axis -libinput_event_pointer_get_axis(struct libinput_event_pointer *event); +int +libinput_event_pointer_has_axis(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis); /** * @ingroup event_pointer @@ -676,6 +676,9 @@ libinput_event_pointer_get_axis(struct libinput_event_pointer *event); * respectively. For the interpretation of the value, see * libinput_event_pointer_get_axis_source(). * + * If libinput_event_pointer_has_axis() returns 0 for an axis, this function + * returns 0 for that axis. + * * For pointer events that are not of type @ref LIBINPUT_EVENT_POINTER_AXIS, * this function returns 0. * @@ -685,7 +688,8 @@ libinput_event_pointer_get_axis(struct libinput_event_pointer *event); * @return the axis value of this event */ double -libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event); +libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis); /** * @ingroup event_pointer diff --git a/src/libinput.sym b/src/libinput.sym index 826bfde4..c5d9b63f 100644 --- a/src/libinput.sym +++ b/src/libinput.sym @@ -82,6 +82,7 @@ global: libinput_event_pointer_get_dy_unaccelerated; libinput_event_pointer_get_seat_button_count; libinput_event_pointer_get_time; + libinput_event_pointer_has_axis; libinput_event_touch_get_base_event; libinput_event_touch_get_seat_slot; libinput_event_touch_get_slot; diff --git a/test/litest.c b/test/litest.c index 392ffe25..757f445d 100644 --- a/test/litest.c +++ b/test/litest.c @@ -983,11 +983,11 @@ litest_print_event(struct libinput_event *event) case LIBINPUT_EVENT_POINTER_AXIS: p = libinput_event_get_pointer_event(event); fprintf(stderr, - "axis %s value %.2f", - libinput_event_pointer_get_axis(p) == - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL ? - "vert" : "horiz", - libinput_event_pointer_get_axis_value(p)); + "vert %.f horiz %.2f", + libinput_event_pointer_get_axis_value(p, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL), + libinput_event_pointer_get_axis_value(p, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)); break; default: break; @@ -1198,23 +1198,24 @@ litest_assert_scroll(struct libinput *li, 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 (minimum_movement > 0) { ck_assert_int_ge( - libinput_event_pointer_get_axis_value(ptrev), + libinput_event_pointer_get_axis_value(ptrev, + axis), minimum_movement); } else { ck_assert_int_le( - libinput_event_pointer_get_axis_value(ptrev), + libinput_event_pointer_get_axis_value(ptrev, + axis), minimum_movement); } } else { /* Last scroll event, must be 0 */ ck_assert_int_eq( - libinput_event_pointer_get_axis_value(ptrev), + libinput_event_pointer_get_axis_value(ptrev, axis), 0); } libinput_event_destroy(event); diff --git a/test/pointer.c b/test/pointer.c index d12c9f6b..dd9ea0da 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -348,6 +348,7 @@ test_wheel_event(struct litest_device *dev, int which, int amount) struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_event_pointer *ptrev; + enum libinput_pointer_axis axis; /* the current evdev implementation scales the scroll wheel events up by a factor 15 */ @@ -372,11 +373,13 @@ test_wheel_event(struct litest_device *dev, int which, int amount) ptrev = libinput_event_get_pointer_event(event); ck_assert(ptrev != NULL); - ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev), - which == REL_WHEEL ? + + axis = (which == REL_WHEEL) ? LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL : - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); - ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev), expected); + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL; + + ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev, axis), + expected); ck_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev), LIBINPUT_POINTER_AXIS_SOURCE_WHEEL); libinput_event_destroy(event); diff --git a/test/touchpad.c b/test/touchpad.c index 422e8fe6..dbe16a3a 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -1439,18 +1439,19 @@ START_TEST(touchpad_2fg_scroll_slow_distance) /* last event is value 0, tested elsewhere */ while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) { + double axisval; ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_AXIS); ptrev = libinput_event_get_pointer_event(event); - ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev), - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - ck_assert(libinput_event_pointer_get_axis_value(ptrev) > 0.0); + axisval = libinput_event_pointer_get_axis_value(ptrev, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + ck_assert(axisval > 0.0); /* this is to verify we test the right thing, if the value is greater than scroll.threshold we triggered the wrong condition */ - ck_assert(libinput_event_pointer_get_axis_value(ptrev) < 5.0); + ck_assert(axisval < 5.0); libinput_event_destroy(event); event = libinput_get_event(li); @@ -1627,18 +1628,19 @@ START_TEST(touchpad_edge_scroll_slow_distance) ck_assert_notnull(event); while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) { + double axisval; ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_AXIS); ptrev = libinput_event_get_pointer_event(event); - ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev), + axisval = libinput_event_pointer_get_axis_value(ptrev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - ck_assert(libinput_event_pointer_get_axis_value(ptrev) > 0.0); + ck_assert(axisval > 0.0); /* this is to verify we test the right thing, if the value is greater than scroll.threshold we triggered the wrong condition */ - ck_assert(libinput_event_pointer_get_axis_value(ptrev) < 5.0); + ck_assert(axisval < 5.0); libinput_event_destroy(event); event = libinput_get_event(li); diff --git a/tools/event-debug.c b/tools/event-debug.c index 090fc3f0..4d845ced 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -225,24 +225,18 @@ static void print_axis_event(struct libinput_event *ev) { struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); - enum libinput_pointer_axis axis = libinput_event_pointer_get_axis(p); - const char *ax; - double val; - - switch (axis) { - case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: - ax = "vscroll"; - break; - case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: - ax = "hscroll"; - break; - default: - abort(); - } + double v = 0, h = 0; + if (libinput_event_pointer_has_axis(p, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) + v = libinput_event_pointer_get_axis_value(p, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + if (libinput_event_pointer_has_axis(p, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) + h = libinput_event_pointer_get_axis_value(p, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); print_event_time(libinput_event_pointer_get_time(p)); - val = libinput_event_pointer_get_axis_value(p); - printf("%s %.2f\n", ax, val); + printf("vert %.2f horiz %.2f\n", v, h); } static void diff --git a/tools/event-gui.c b/tools/event-gui.c index 9a08d8ef..4f9d7e67 100644 --- a/tools/event-gui.c +++ b/tools/event-gui.c @@ -358,20 +358,20 @@ static void handle_event_axis(struct libinput_event *ev, struct window *w) { struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); - enum libinput_pointer_axis axis = libinput_event_pointer_get_axis(p); - double v = libinput_event_pointer_get_axis_value(p); + double v, h; - switch (axis) { - case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + v = libinput_event_pointer_get_axis_value(p, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + h = libinput_event_pointer_get_axis_value(p, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + + if (v != 0.0) { w->vy += (int)v; w->vy = clip(w->vy, 0, w->height); - break; - case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: + } + if (h != 0.0) { w->hx += (int)v; w->hx = clip(w->hx, 0, w->width); - break; - default: - abort(); } } From 1daa1a11aa03dceec2d8c062112798abe7ce7ce0 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 13 Jan 2015 15:15:02 +1000 Subject: [PATCH 50/55] Add libinput_event_pointer_get_axis_value_discrete() to count wheel clicks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recent normalization of wheel events means we get the angle in degrees but we don't know how this corresponds to clicks. The M325 has a 20 degree click angle, most other mice have 15 degrees. So an angle of 60 can be 3 or 4 click events. Most clients care more about the click count than the angle on a mouse wheel. Provide that value when needed. Adding a discrete value to the axis event leaves the possibility of defining discrete units for finger/continuous scroll sources in the future. Right now, these will always reuturn 0. Signed-off-by: Peter Hutterer Reviewed-by: Jonas Ådahl Reviewed-by: Hans de Goede --- src/evdev-mt-touchpad-edge-scroll.c | 9 ++++++--- src/evdev.c | 26 +++++++++++++++++--------- src/libinput-private.h | 3 ++- src/libinput.c | 11 ++++++++++- src/libinput.h | 21 +++++++++++++++++++++ src/libinput.sym | 1 + test/pointer.c | 7 ++++++- 7 files changed, 63 insertions(+), 15 deletions(-) diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c index a4dc0939..8605034c 100644 --- a/src/evdev-mt-touchpad-edge-scroll.c +++ b/src/evdev-mt-touchpad-edge-scroll.c @@ -327,7 +327,8 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time) pointer_notify_axis(device, time, t->scroll.direction, LIBINPUT_POINTER_AXIS_SOURCE_FINGER, - 0.0); + 0.0, + 0); t->scroll.direction = -1; } continue; @@ -351,7 +352,8 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time) pointer_notify_axis(device, time, axis, LIBINPUT_POINTER_AXIS_SOURCE_FINGER, - *delta); + *delta, + 0); t->scroll.direction = axis; tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_POSTED); @@ -371,7 +373,8 @@ tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time) pointer_notify_axis(device, time, t->scroll.direction, LIBINPUT_POINTER_AXIS_SOURCE_FINGER, - 0.0); + 0.0, + 0); t->scroll.direction = -1; } } diff --git a/src/evdev.c b/src/evdev.c index d80594df..0e78381c 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -541,16 +541,20 @@ evdev_notify_axis(struct evdev_device *device, uint64_t time, enum libinput_pointer_axis axis, enum libinput_pointer_axis_source source, - double value) + double value, + double discrete) { - if (device->scroll.natural_scrolling_enabled) + if (device->scroll.natural_scrolling_enabled) { value *= -1; + discrete *= -1; + } pointer_notify_axis(&device->base, time, axis, source, - value); + value, + discrete); } static inline void @@ -577,7 +581,8 @@ evdev_process_relative(struct evdev_device *device, time, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, - -1 * e->value * device->scroll.wheel_click_angle); + -1 * e->value * device->scroll.wheel_click_angle, + -1 * e->value); break; case REL_HWHEEL: evdev_flush_pending_event(device, time); @@ -586,7 +591,8 @@ evdev_process_relative(struct evdev_device *device, time, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, - e->value * device->scroll.wheel_click_angle); + e->value * device->scroll.wheel_click_angle, + e->value); break; } } @@ -1864,7 +1870,8 @@ evdev_post_scroll(struct evdev_device *device, time, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, source, - dy); + dy, + 0); } if (dx != 0.0 && @@ -1874,7 +1881,8 @@ evdev_post_scroll(struct evdev_device *device, time, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, source, - dx); + dx, + 0); } } @@ -1889,13 +1897,13 @@ evdev_stop_scroll(struct evdev_device *device, time, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, source, - 0); + 0, 0); if (device->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) pointer_notify_axis(&device->base, time, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, source, - 0); + 0, 0); device->scroll.buildup_horizontal = 0; device->scroll.buildup_vertical = 0; diff --git a/src/libinput-private.h b/src/libinput-private.h index 84a0d440..415e53e3 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -280,7 +280,8 @@ pointer_notify_axis(struct libinput_device *device, uint64_t time, enum libinput_pointer_axis axis, enum libinput_pointer_axis_source source, - double value); + double value, + double discrete); void touch_notify_touch_down(struct libinput_device *device, diff --git a/src/libinput.c b/src/libinput.c index 426c3069..37df9626 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -67,6 +67,7 @@ struct libinput_event_pointer { enum libinput_pointer_axis axis; enum libinput_pointer_axis_source source; double value; + double discrete; }; struct libinput_event_touch { @@ -391,6 +392,12 @@ libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event) return event->value; } +LIBINPUT_EXPORT double +libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event) +{ + return event->discrete; +} + LIBINPUT_EXPORT enum libinput_pointer_axis_source libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event) { @@ -994,7 +1001,8 @@ pointer_notify_axis(struct libinput_device *device, uint64_t time, enum libinput_pointer_axis axis, enum libinput_pointer_axis_source source, - double value) + double value, + double discrete) { struct libinput_event_pointer *axis_event; @@ -1007,6 +1015,7 @@ pointer_notify_axis(struct libinput_device *device, .axis = axis, .value = value, .source = source, + .discrete = discrete, }; post_device_event(device, time, diff --git a/src/libinput.h b/src/libinput.h index f605e52b..c6dd57e7 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -683,6 +683,8 @@ libinput_event_pointer_get_axis(struct libinput_event_pointer *event); * @ref LIBINPUT_EVENT_POINTER_AXIS. * * @return the axis value of this event + * + * @see libinput_event_pointer_get_axis_value_discrete */ double libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event); @@ -725,6 +727,25 @@ libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event); enum libinput_pointer_axis_source libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event); +/** + * @ingroup pointer + * + * Return the axis value in discrete steps for a given axis event. How a + * value translates into a discrete step depends on the source. + * + * If the source is @ref LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, the discrete + * value correspond to the number of physical mouse clicks. + * + * If the source is @ref LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS or @ref + * LIBINPUT_POINTER_AXIS_SOURCE_FINGER, the discrete value is always 0. + * + * @return The discrete value for the given event. + * + * @see libinput_event_pointer_get_axis_value + */ +double +libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event); + /** * @ingroup event_pointer * diff --git a/src/libinput.sym b/src/libinput.sym index 826bfde4..d9ebbc27 100644 --- a/src/libinput.sym +++ b/src/libinput.sym @@ -73,6 +73,7 @@ global: libinput_event_pointer_get_axis; libinput_event_pointer_get_axis_source; libinput_event_pointer_get_axis_value; + libinput_event_pointer_get_axis_value_discrete; libinput_event_pointer_get_base_event; libinput_event_pointer_get_button_state; libinput_event_pointer_get_button; diff --git a/test/pointer.c b/test/pointer.c index d12c9f6b..2055c413 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -353,9 +353,12 @@ test_wheel_event(struct litest_device *dev, int which, int amount) up by a factor 15 */ const int scroll_step = 15; int expected = amount * scroll_step; + int discrete = amount; - if (libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device)) + if (libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device)) { expected *= -1; + discrete *= -1; + } /* mouse scroll wheels are 'upside down' */ if (which == REL_WHEEL) @@ -379,6 +382,8 @@ test_wheel_event(struct litest_device *dev, int which, int amount) ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev), expected); ck_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev), LIBINPUT_POINTER_AXIS_SOURCE_WHEEL); + ck_assert_int_eq(libinput_event_pointer_get_axis_value_discrete(ptrev), + discrete); libinput_event_destroy(event); } From 2af608cf0221d8970f8cb0aefbbc61914ed9ea21 Mon Sep 17 00:00:00 2001 From: Stephen Chandler Paul Date: Tue, 6 Jan 2015 21:20:22 -0500 Subject: [PATCH 51/55] Rename functions for left handed device configurations Some devices require more than just flipping around the buttons, such as tablets. When it comes to devices like tablets, because the position of the palm rest is on the right, the entire tablet has to be flipped around in order to be usable by lefties. As such, this requires that we reverse the coordinates of the tablets in addition to flipping the buttons on the tablet. As such, renaming these functions so that they aren't specific to devices where only the buttons are flipped seems appropriate. Signed-off-by: Stephen Chandler Paul Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- src/evdev-mt-touchpad.c | 4 +-- src/evdev.c | 34 ++++++++++++------------- src/evdev.h | 12 ++++----- src/libinput.c | 16 ++++++------ src/libinput.h | 55 ++++++++++++++++++++--------------------- src/libinput.sym | 8 +++--- test/pointer.c | 12 ++++----- test/touch.c | 8 +++--- test/touchpad.c | 18 +++++++------- tools/event-debug.c | 2 +- tools/shared.c | 2 +- 11 files changed, 85 insertions(+), 86 deletions(-) diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 7e8306d4..34b107e2 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -1310,7 +1310,7 @@ tp_change_to_left_handed(struct evdev_device *device) { struct tp_dispatch *tp = (struct tp_dispatch *)device->dispatch; - if (device->buttons.want_left_handed == device->buttons.left_handed) + if (device->left_handed.want_enabled == device->left_handed.enabled) return; if (tp->buttons.state & 0x3) /* BTN_LEFT|BTN_RIGHT */ @@ -1319,7 +1319,7 @@ tp_change_to_left_handed(struct evdev_device *device) /* tapping and clickfinger aren't affected by left-handed config, * so checking physical buttons is enough */ - device->buttons.left_handed = device->buttons.want_left_handed; + device->left_handed.enabled = device->left_handed.want_enabled; } struct model_lookup_t { diff --git a/src/evdev.c b/src/evdev.c index 2d73d690..6edacba6 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -119,8 +119,8 @@ evdev_pointer_notify_button(struct evdev_device *device, pointer_notify_button(&device->base, time, button, state); if (state == LIBINPUT_BUTTON_STATE_RELEASED && - device->buttons.change_to_left_handed) - device->buttons.change_to_left_handed(device); + device->left_handed.change_to_enabled) + device->left_handed.change_to_enabled(device); if (state == LIBINPUT_BUTTON_STATE_RELEASED && device->scroll.change_scroll_method) @@ -822,13 +822,13 @@ evdev_left_handed_has(struct libinput_device *device) static void evdev_change_to_left_handed(struct evdev_device *device) { - if (device->buttons.want_left_handed == device->buttons.left_handed) + if (device->left_handed.want_enabled == device->left_handed.enabled) return; if (evdev_any_button_down(device)) return; - device->buttons.left_handed = device->buttons.want_left_handed; + device->left_handed.enabled = device->left_handed.want_enabled; } static enum libinput_config_status @@ -836,9 +836,9 @@ evdev_left_handed_set(struct libinput_device *device, int left_handed) { struct evdev_device *evdev_device = (struct evdev_device *)device; - evdev_device->buttons.want_left_handed = left_handed ? true : false; + evdev_device->left_handed.want_enabled = left_handed ? true : false; - evdev_device->buttons.change_to_left_handed(evdev_device); + evdev_device->left_handed.change_to_enabled(evdev_device); return LIBINPUT_CONFIG_STATUS_SUCCESS; } @@ -850,7 +850,7 @@ evdev_left_handed_get(struct libinput_device *device) /* return the wanted configuration, even if it hasn't taken * effect yet! */ - return evdev_device->buttons.want_left_handed; + return evdev_device->left_handed.want_enabled; } static int @@ -863,14 +863,14 @@ int evdev_init_left_handed(struct evdev_device *device, void (*change_to_left_handed)(struct evdev_device *)) { - device->buttons.config_left_handed.has = evdev_left_handed_has; - device->buttons.config_left_handed.set = evdev_left_handed_set; - device->buttons.config_left_handed.get = evdev_left_handed_get; - device->buttons.config_left_handed.get_default = evdev_left_handed_get_default; - device->base.config.left_handed = &device->buttons.config_left_handed; - device->buttons.left_handed = false; - device->buttons.want_left_handed = false; - device->buttons.change_to_left_handed = change_to_left_handed; + device->left_handed.config.has = evdev_left_handed_has; + device->left_handed.config.set = evdev_left_handed_set; + device->left_handed.config.get = evdev_left_handed_get; + device->left_handed.config.get_default = evdev_left_handed_get_default; + device->base.config.left_handed = &device->left_handed.config; + device->left_handed.enabled = false; + device->left_handed.want_enabled = false; + device->left_handed.change_to_enabled = change_to_left_handed; return 0; } @@ -1064,7 +1064,7 @@ fallback_dispatch_create(struct libinput_device *device) dispatch->interface = &fallback_interface; - if (evdev_device->buttons.want_left_handed && + if (evdev_device->left_handed.want_enabled && evdev_init_left_handed(evdev_device, evdev_change_to_left_handed) == -1) { free(dispatch); @@ -1477,7 +1477,7 @@ evdev_configure_device(struct evdev_device *device) has_button ? " button" : ""); /* want left-handed config option */ - device->buttons.want_left_handed = true; + device->left_handed.want_enabled = true; /* want natural-scroll config option */ device->scroll.natural_scrolling_enabled = true; } diff --git a/src/evdev.h b/src/evdev.h index 2171c5ad..0f2c5acc 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -144,15 +144,15 @@ struct evdev_device { uint8_t key_count[KEY_CNT]; struct { - struct libinput_device_config_left_handed config_left_handed; + struct libinput_device_config_left_handed config; /* left-handed currently enabled */ - bool left_handed; + bool enabled; /* set during device init if we want left_handed config, * used at runtime to delay the effect until buttons are up */ - bool want_left_handed; + bool want_enabled; /* Checks if buttons are down and commits the setting */ - void (*change_to_left_handed)(struct evdev_device *device); - } buttons; + void (*change_to_enabled)(struct evdev_device *device); + } left_handed; int dpi; /* HW resolution */ struct ratelimit syn_drop_limit; /* ratelimit for SYN_DROPPED logging */ @@ -332,7 +332,7 @@ static inline uint32_t evdev_to_left_handed(struct evdev_device *device, uint32_t button) { - if (device->buttons.left_handed) { + if (device->left_handed.enabled) { if (button == BTN_LEFT) return BTN_RIGHT; else if (button == BTN_RIGHT) diff --git a/src/libinput.c b/src/libinput.c index 00ab5f21..6f45405e 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -1599,7 +1599,7 @@ libinput_device_config_scroll_get_default_natural_scroll_enabled(struct libinput } LIBINPUT_EXPORT int -libinput_device_config_buttons_has_left_handed(struct libinput_device *device) +libinput_device_config_left_handed_is_available(struct libinput_device *device) { if (!device->config.left_handed) return 0; @@ -1608,28 +1608,28 @@ libinput_device_config_buttons_has_left_handed(struct libinput_device *device) } LIBINPUT_EXPORT enum libinput_config_status -libinput_device_config_buttons_set_left_handed(struct libinput_device *device, - int left_handed) +libinput_device_config_left_handed_set(struct libinput_device *device, + int left_handed) { - if (!libinput_device_config_buttons_has_left_handed(device)) + if (!libinput_device_config_left_handed_is_available(device)) return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; return device->config.left_handed->set(device, left_handed); } LIBINPUT_EXPORT int -libinput_device_config_buttons_get_left_handed(struct libinput_device *device) +libinput_device_config_left_handed_get(struct libinput_device *device) { - if (!libinput_device_config_buttons_has_left_handed(device)) + if (!libinput_device_config_left_handed_is_available(device)) return 0; return device->config.left_handed->get(device); } LIBINPUT_EXPORT int -libinput_device_config_buttons_get_default_left_handed(struct libinput_device *device) +libinput_device_config_left_handed_get_default(struct libinput_device *device) { - if (!libinput_device_config_buttons_has_left_handed(device)) + if (!libinput_device_config_left_handed_is_available(device)) return 0; return device->config.left_handed->get_default(device); diff --git a/src/libinput.h b/src/libinput.h index 276660b9..dbc4b2e2 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -2102,33 +2102,32 @@ libinput_device_config_scroll_get_default_natural_scroll_enabled(struct libinput /** * @ingroup config * - * Check if a device has a button configuration that supports left-handed - * usage. + * Check if a device has a configuration that supports left-handed usage. * * @param device The device to configure * @return Non-zero if the device can be set to left-handed, or zero * otherwise * - * @see libinput_device_config_buttons_set_left_handed - * @see libinput_device_config_buttons_get_left_handed - * @see libinput_device_config_buttons_get_default_left_handed + * @see libinput_device_config_left_handed_set + * @see libinput_device_config_left_handed_get + * @see libinput_device_config_left_handed_get_default */ int -libinput_device_config_buttons_has_left_handed(struct libinput_device *device); +libinput_device_config_left_handed_is_available(struct libinput_device *device); /** * @ingroup config * - * Set the left-handed configuration of the device. A device in left-handed - * mode sends a left button event instead of the right button and vice - * versa. + * Set the left-handed configuration of the device. For example, a pointing + * device may reverse it's buttons and send a right button click when the + * left button is pressed, and vice versa. * - * The exact button behavior is device-dependent. On a mouse and most - * pointing devices, left and right buttons are swapped but the middle - * button is unmodified. On a touchpad, physical buttons (if present) are - * swapped. On a clickpad, the top and bottom software-emulated buttons are - * swapped where present, the main area of the touchpad remains a left - * button. Tapping and clickfinger behavior is not affected by this setting. + * The exact behavior is device-dependent. On a mouse and most pointing + * devices, left and right buttons are swapped but the middle button is + * unmodified. On a touchpad, physical buttons (if present) are swapped. On a + * clickpad, the top and bottom software-emulated buttons are swapped where + * present, the main area of the touchpad remains a left button. Tapping and + * clickfinger behavior is not affected by this setting. * * Changing the left-handed configuration of a device may not take effect * until all buttons have been logically released. @@ -2137,13 +2136,13 @@ libinput_device_config_buttons_has_left_handed(struct libinput_device *device); * @param left_handed Zero to disable, non-zero to enable left-handed mode * @return A configuration status code * - * @see libinput_device_config_buttons_has_left_handed - * @see libinput_device_config_buttons_get_left_handed - * @see libinput_device_config_buttons_get_default_left_handed + * @see libinput_device_config_left_handed_is_available + * @see libinput_device_config_left_handed_get + * @see libinput_device_config_left_handed_get_default */ enum libinput_config_status -libinput_device_config_buttons_set_left_handed(struct libinput_device *device, - int left_handed); +libinput_device_config_left_handed_set(struct libinput_device *device, + int left_handed); /** * @ingroup config @@ -2154,12 +2153,12 @@ libinput_device_config_buttons_set_left_handed(struct libinput_device *device, * @return Zero if the device is in right-handed mode, non-zero if the * device is in left-handed mode * - * @see libinput_device_config_buttons_has_left_handed - * @see libinput_device_config_buttons_set_left_handed - * @see libinput_device_config_buttons_get_default_left_handed + * @see libinput_device_config_left_handed_is_available + * @see libinput_device_config_left_handed_set + * @see libinput_device_config_left_handed_get_default */ int -libinput_device_config_buttons_get_left_handed(struct libinput_device *device); +libinput_device_config_left_handed_get(struct libinput_device *device); /** * @ingroup config @@ -2170,12 +2169,12 @@ libinput_device_config_buttons_get_left_handed(struct libinput_device *device); * @return Zero if the device is in right-handed mode by default, or non-zero * if the device is in left-handed mode by default * - * @see libinput_device_config_buttons_has_left_handed - * @see libinput_device_config_buttons_set_left_handed - * @see libinput_device_config_buttons_get_left_handed + * @see libinput_device_config_left_handed_is_available + * @see libinput_device_config_left_handed_set + * @see libinput_device_config_left_handed_get */ int -libinput_device_config_buttons_get_default_left_handed(struct libinput_device *device); +libinput_device_config_left_handed_get_default(struct libinput_device *device); /** * @ingroup config diff --git a/src/libinput.sym b/src/libinput.sym index f1fa306c..018578d6 100644 --- a/src/libinput.sym +++ b/src/libinput.sym @@ -7,10 +7,10 @@ global: libinput_device_config_accel_get_speed; libinput_device_config_accel_is_available; libinput_device_config_accel_set_speed; - libinput_device_config_buttons_get_default_left_handed; - libinput_device_config_buttons_get_left_handed; - libinput_device_config_buttons_has_left_handed; - libinput_device_config_buttons_set_left_handed; + libinput_device_config_left_handed_get_default; + libinput_device_config_left_handed_get; + libinput_device_config_left_handed_is_available; + libinput_device_config_left_handed_set; libinput_device_config_calibration_get_default_matrix; libinput_device_config_calibration_get_matrix; libinput_device_config_calibration_has_matrix; diff --git a/test/pointer.c b/test/pointer.c index 1af4f385..45e0d57e 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -577,13 +577,13 @@ START_TEST(pointer_left_handed_defaults) struct libinput_device *d = dev->libinput_device; int rc; - rc = libinput_device_config_buttons_has_left_handed(d); + rc = libinput_device_config_left_handed_is_available(d); ck_assert_int_ne(rc, 0); - rc = libinput_device_config_buttons_get_left_handed(d); + rc = libinput_device_config_left_handed_get(d); ck_assert_int_eq(rc, 0); - rc = libinput_device_config_buttons_get_default_left_handed(d); + rc = libinput_device_config_left_handed_get_default(d); ck_assert_int_eq(rc, 0); } END_TEST @@ -595,7 +595,7 @@ START_TEST(pointer_left_handed) struct libinput *li = dev->libinput; enum libinput_config_status status; - status = libinput_device_config_buttons_set_left_handed(d, 1); + status = libinput_device_config_left_handed_set(d, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_drain_events(li); @@ -645,7 +645,7 @@ START_TEST(pointer_left_handed_during_click) libinput_dispatch(li); /* Change while button is down, expect correct release event */ - status = libinput_device_config_buttons_set_left_handed(d, 1); + status = libinput_device_config_left_handed_set(d, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_button_click(dev, BTN_LEFT, 0); @@ -670,7 +670,7 @@ START_TEST(pointer_left_handed_during_click_multiple_buttons) litest_button_click(dev, BTN_LEFT, 1); libinput_dispatch(li); - status = libinput_device_config_buttons_set_left_handed(d, 1); + status = libinput_device_config_left_handed_set(d, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); /* No left-handed until all buttons were down */ diff --git a/test/touch.c b/test/touch.c index 5c9b72a8..29890a41 100644 --- a/test/touch.c +++ b/test/touch.c @@ -408,16 +408,16 @@ START_TEST(touch_no_left_handed) enum libinput_config_status status; int rc; - rc = libinput_device_config_buttons_has_left_handed(d); + rc = libinput_device_config_left_handed_is_available(d); ck_assert_int_eq(rc, 0); - rc = libinput_device_config_buttons_get_left_handed(d); + rc = libinput_device_config_left_handed_get(d); ck_assert_int_eq(rc, 0); - rc = libinput_device_config_buttons_get_default_left_handed(d); + rc = libinput_device_config_left_handed_get_default(d); ck_assert_int_eq(rc, 0); - status = libinput_device_config_buttons_set_left_handed(d, 0); + status = libinput_device_config_left_handed_set(d, 0); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); } END_TEST diff --git a/test/touchpad.c b/test/touchpad.c index dbe16a3a..c5edecc8 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -1917,7 +1917,7 @@ START_TEST(touchpad_left_handed) struct libinput *li = dev->libinput; enum libinput_config_status status; - status = libinput_device_config_buttons_set_left_handed(d, 1); + status = libinput_device_config_left_handed_set(d, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_drain_events(li); @@ -1962,7 +1962,7 @@ START_TEST(touchpad_left_handed_clickpad) struct libinput *li = dev->libinput; enum libinput_config_status status; - status = libinput_device_config_buttons_set_left_handed(d, 1); + status = libinput_device_config_left_handed_set(d, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_drain_events(li); @@ -2013,7 +2013,7 @@ START_TEST(touchpad_left_handed_clickfinger) struct libinput *li = dev->libinput; enum libinput_config_status status; - status = libinput_device_config_buttons_set_left_handed(d, 1); + status = libinput_device_config_left_handed_set(d, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_drain_events(li); @@ -2056,7 +2056,7 @@ START_TEST(touchpad_left_handed_tapping) libinput_device_config_tap_set_enabled(dev->libinput_device, LIBINPUT_CONFIG_TAP_ENABLED); - status = libinput_device_config_buttons_set_left_handed(d, 1); + status = libinput_device_config_left_handed_set(d, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_drain_events(li); @@ -2087,7 +2087,7 @@ START_TEST(touchpad_left_handed_tapping_2fg) libinput_device_config_tap_set_enabled(dev->libinput_device, LIBINPUT_CONFIG_TAP_ENABLED); - status = libinput_device_config_buttons_set_left_handed(d, 1); + status = libinput_device_config_left_handed_set(d, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_drain_events(li); @@ -2123,7 +2123,7 @@ START_TEST(touchpad_left_handed_delayed) litest_button_click(dev, BTN_LEFT, 1); libinput_dispatch(li); - status = libinput_device_config_buttons_set_left_handed(d, 1); + status = libinput_device_config_left_handed_set(d, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_button_click(dev, BTN_LEFT, 0); @@ -2140,7 +2140,7 @@ START_TEST(touchpad_left_handed_delayed) litest_button_click(dev, BTN_LEFT, 1); libinput_dispatch(li); - status = libinput_device_config_buttons_set_left_handed(d, 0); + status = libinput_device_config_left_handed_set(d, 0); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_button_click(dev, BTN_RIGHT, 0); @@ -2173,7 +2173,7 @@ START_TEST(touchpad_left_handed_clickpad_delayed) litest_button_click(dev, BTN_LEFT, 1); libinput_dispatch(li); - status = libinput_device_config_buttons_set_left_handed(d, 1); + status = libinput_device_config_left_handed_set(d, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_button_click(dev, BTN_LEFT, 0); @@ -2192,7 +2192,7 @@ START_TEST(touchpad_left_handed_clickpad_delayed) litest_button_click(dev, BTN_LEFT, 1); libinput_dispatch(li); - status = libinput_device_config_buttons_set_left_handed(d, 0); + status = libinput_device_config_left_handed_set(d, 0); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_button_click(dev, BTN_LEFT, 0); diff --git a/tools/event-debug.c b/tools/event-debug.c index 4d845ced..297e47d8 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -146,7 +146,7 @@ print_device_notify(struct libinput_event *ev) if (libinput_device_config_tap_get_finger_count((dev))) printf(" tap"); - if (libinput_device_config_buttons_has_left_handed((dev))) + if (libinput_device_config_left_handed_is_available((dev))) printf(" left"); if (libinput_device_config_scroll_has_natural_scroll((dev))) printf(" scroll-nat"); diff --git a/tools/shared.c b/tools/shared.c index 3e1368d1..b4f41d04 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -262,5 +262,5 @@ tools_device_apply_config(struct libinput_device *device, libinput_device_config_scroll_set_natural_scroll_enabled(device, options->natural_scroll); if (options->left_handed != -1) - libinput_device_config_buttons_set_left_handed(device, options->left_handed); + libinput_device_config_left_handed_set(device, options->left_handed); } From 2066f3636a949f4a5965a470876884359b68a987 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 15 Jan 2015 10:49:56 +1000 Subject: [PATCH 52/55] doc: add some missing files to EXTRA_DIST Signed-off-by: Peter Hutterer --- doc/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Makefile.am b/doc/Makefile.am index b4b5d542..51b31a92 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -35,7 +35,7 @@ clean-local: $(AM_V_at)rm -rf html doc_src= $(shell find html -type f -printf "html/%P\n" 2>/dev/null) -EXTRA_DIST += $(builddir)/html/index.html $(doc_src) +EXTRA_DIST += $(builddir)/html/index.html $(doc_src) $(diagram_files) $(header_files) endif From f2a446aafd53a0140528879204549b969c7dbda3 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 15 Jan 2015 11:43:04 +1000 Subject: [PATCH 53/55] doc: specify the IMAGE_PATH relative to the source Fixes doxygen build with custom builddirs Signed-off-by: Peter Hutterer --- doc/libinput.doxygen.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/libinput.doxygen.in b/doc/libinput.doxygen.in index 8fb045e8..254e947a 100644 --- a/doc/libinput.doxygen.in +++ b/doc/libinput.doxygen.in @@ -842,7 +842,8 @@ EXAMPLE_RECURSIVE = NO # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = svg +IMAGE_PATH = @top_srcdir@/doc/svg \ + @top_srcdir@/doc/dot # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program From f935837c45b6091e928fde7228eebeac401637f5 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 15 Jan 2015 11:43:31 +1000 Subject: [PATCH 54/55] doc: move DOTFILE_DIRS to libinput.doxygen.in We specify a bunch of other (static) things in the .in file, let's be consistent. Signed-off-by: Peter Hutterer --- doc/Makefile.am | 1 - doc/libinput.doxygen.in | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/Makefile.am b/doc/Makefile.am index 51b31a92..f66b47f1 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -28,7 +28,6 @@ diagram_files = \ html/index.html: libinput.doxygen $(header_files) $(diagram_files) $(AM_V_GEN)(cat $<; \ echo "INPUT = $(header_files)"; \ - echo "DOTFILE_DIRS = $(srcdir)/dot"; \ ) | $(DOXYGEN) - clean-local: diff --git a/doc/libinput.doxygen.in b/doc/libinput.doxygen.in index 254e947a..155880a2 100644 --- a/doc/libinput.doxygen.in +++ b/doc/libinput.doxygen.in @@ -2251,7 +2251,7 @@ DOT_PATH = # command). # This tag requires that the tag HAVE_DOT is set to YES. -DOTFILE_DIRS = +DOTFILE_DIRS = @top_srcdir@/doc/dot # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the \mscfile From c8dc81b48f856c467f38af85288cd82a2384d0b7 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 15 Jan 2015 10:40:44 +1000 Subject: [PATCH 55/55] configure.ac: libinput 0.8 Note: soname bump Signed-off-by: Peter Hutterer --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 374a63aa..1532e819 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ AC_PREREQ([2.64]) m4_define([libinput_major_version], [0]) -m4_define([libinput_minor_version], [7]) +m4_define([libinput_minor_version], [8]) 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]) # - 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=6:0:1 +LIBINPUT_LT_VERSION=7:0:0 AC_SUBST(LIBINPUT_LT_VERSION) AM_SILENT_RULES([yes])