diff --git a/.gitignore b/.gitignore index 3a9bca9..95dbc55 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ /xf86-input-libinput-0.11.0.tar.bz2 /xf86-input-libinput-0.12.0.tar.bz2 /xf86-input-libinput-0.13.0.tar.bz2 +/xf86-input-libinput-0.14.0.tar.bz2 diff --git a/0001-Add-drag-lock-support.patch b/0001-Add-drag-lock-support.patch deleted file mode 100644 index 7629c6b..0000000 --- a/0001-Add-drag-lock-support.patch +++ /dev/null @@ -1,1428 +0,0 @@ -From b9e6a0fa5804bae802cf08a121557844f0ee2fbb Mon Sep 17 00:00:00 2001 -From: Peter Hutterer -Date: Fri, 7 Aug 2015 15:19:12 +1000 -Subject: [PATCH xf86-input-libinput] Add drag lock support - -Mostly the same functionality that evdev provides with two options on how it -works: -* a single button number configures the given button to lock the next button - pressed in a logically down state until a press+ release of that same button - again -* a set of button number pairs configures each button with the to-be-locked - logical button, i.e. a pair of "1 3" will hold 3 logically down after a - button 1 press - -The property and the xorg.conf options take the same configuration as the -evdev driver (though the property has a different prefix, libinput instead of -Evdev). - -The behavior difference to evdev is in how releases are handled, evdev sends -the release on the second button press event, this implementation sends the -release on the second release event. - -Signed-off-by: Peter Hutterer ---- - Makefile.am | 2 +- - configure.ac | 1 + - include/libinput-properties.h | 6 + - man/libinput.man | 46 +++- - src/Makefile.am | 4 +- - src/draglock.c | 282 ++++++++++++++++++++++ - src/draglock.h | 159 +++++++++++++ - src/libinput.c | 146 +++++++++++- - test/.gitignore | 1 + - test/Makefile.am | 13 + - test/test-draglock.c | 540 ++++++++++++++++++++++++++++++++++++++++++ - 11 files changed, 1195 insertions(+), 5 deletions(-) - create mode 100644 src/draglock.c - create mode 100644 src/draglock.h - create mode 100644 test/.gitignore - create mode 100644 test/Makefile.am - create mode 100644 test/test-draglock.c - -diff --git a/Makefile.am b/Makefile.am -index 99e6808..ef17c35 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -21,7 +21,7 @@ - - DISTCHECK_CONFIGURE_FLAGS = --with-sdkdir='$${includedir}/xorg' - --SUBDIRS = src include man -+SUBDIRS = src include man test - MAINTAINERCLEANFILES = ChangeLog INSTALL - - pkgconfigdir = $(libdir)/pkgconfig -diff --git a/configure.ac b/configure.ac -index c149a1b..26e0e70 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -71,5 +71,6 @@ AC_CONFIG_FILES([Makefile - include/Makefile - src/Makefile - man/Makefile -+ test/Makefile - xorg-libinput.pc]) - AC_OUTPUT -diff --git a/include/libinput-properties.h b/include/libinput-properties.h -index f54cee7..ed009d5 100644 ---- a/include/libinput-properties.h -+++ b/include/libinput-properties.h -@@ -114,4 +114,10 @@ - /* Disable while typing: BOOL, 1 value, read-only */ - #define LIBINPUT_PROP_DISABLE_WHILE_TYPING_DEFAULT "libinput Disable While Typing Enabled Default" - -+/* Drag lock buttons, either: -+ CARD8, one value, the meta lock button, or -+ CARD8, n * 2 values, the drag lock pairs with n being the button and n+1 -+ the target button number */ -+#define LIBINPUT_PROP_DRAG_LOCK_BUTTONS "libinput Drag Lock Buttons" -+ - #endif /* _LIBINPUT_PROPERTIES_H_ */ -diff --git a/man/libinput.man b/man/libinput.man -index ac546e6..ff7a411 100644 ---- a/man/libinput.man -+++ b/man/libinput.man -@@ -123,6 +123,27 @@ continues. - .BI "Option \*qDisableWhileTyping\*q \*q" bool \*q - Indicates if the touchpad should be disabled while typing on the keyboard - (this does not apply to modifier keys such as Ctrl or Alt). -+.TP 7 -+.BI "Option \*qDragLockButtons\*q \*q" "L1 B1 L2 B2 ..." \*q -+Sets "drag lock buttons" that simulate a button logically down even when it has -+been physically released. To logically release a locked button, a second click -+of the same button is required. -+.IP -+If the option is a single button number, that button acts as the -+"meta" locking button for the next button number. See section -+.B BUTTON DRAG LOCK -+for details. -+.IP -+If the option is a list of button number pairs, the first number of each -+number pair is the lock button, the second number the logical button number -+to be locked. See section -+.B BUTTON DRAG LOCK -+for details. -+.IP -+For both meta and button pair configuration, the button numbers are -+device button numbers, i.e. the -+.B ButtonMapping -+applies after drag lock. - .PP - For all options, the options are only parsed if the device supports that - configuration option. For all options, the default value is the one used by -@@ -195,11 +216,16 @@ disabled. - .BI "libinput Disable While Typing Enabled" - 1 boolean value (8 bit, 0 or 1). Indicates if disable while typing is - enabled or disabled. --.TP7 - .PP - The above properties have a - .BI "libinput Default" - equivalent that indicates the default value for this setting on this device. -+.TP 7 -+.BI "libinput Drag Lock Buttons" -+Either one 8-bit value specifying the meta drag lock button, or a list of -+button pairs. See section -+.B BUTTON DRAG LOCK -+for details. - - .SH BUTTON MAPPING - X clients receive events with logical button numbers, where 1, 2, 3 -@@ -226,6 +252,24 @@ __xservername__ input driver does not use the button mapping after setup. - Use XSetPointerMapping(__libmansuffix__) to modify the button mapping at - runtime. - -+.SH BUTTON DRAG LOCK -+Button drag lock holds a button logically down even when the button itself -+has been physically released since. Button drag lock comes in two modes. -+.PP -+If in "meta" mode, a meta button click activates drag lock for the next -+button press of any other button. A button click in the future will keep -+that button held logically down until a subsequent click of that same -+button. The meta button events themselves are discarded. A separate meta -+button click is required each time a drag lock should be activated for a -+button in the future. -+.PP -+If in "pairs" mode, each button can be assigned a target locking button. -+On button click, the target lock button is held logically down until the -+next click of the same button. The button events themselves are discarded -+and only the target button events are sent. -+.TP -+This feature is provided by this driver, not by libinput. -+ - .SH AUTHORS - Peter Hutterer - .SH "SEE ALSO" -diff --git a/src/Makefile.am b/src/Makefile.am -index 1f49893..df02aca 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -30,8 +30,10 @@ AM_CPPFLAGS =-I$(top_srcdir)/include $(LIBINPUT_CFLAGS) - - @DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la - @DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version --@DRIVER_NAME@_drv_la_LIBADD = $(LIBINPUT_LIBS) -+@DRIVER_NAME@_drv_la_LIBADD = $(LIBINPUT_LIBS) libdraglock.la - @DRIVER_NAME@_drv_ladir = @inputdir@ - - @DRIVER_NAME@_drv_la_SOURCES = @DRIVER_NAME@.c - -+noinst_LTLIBRARIES = libdraglock.la -+libdraglock_la_SOURCES = draglock.c draglock.h -diff --git a/src/draglock.c b/src/draglock.c -new file mode 100644 -index 0000000..b0bcac3 ---- /dev/null -+++ b/src/draglock.c -@@ -0,0 +1,282 @@ -+/* -+ * Copyright © 2015 Red Hat, Inc. -+ * -+ * Permission to use, copy, modify, distribute, and sell this software -+ * and its documentation for any purpose is hereby granted without -+ * fee, provided that the above copyright notice appear in all copies -+ * and that both that copyright notice and this permission notice -+ * appear in supporting documentation, and that the name of Red Hat -+ * not be used in advertising or publicity pertaining to distribution -+ * of the software without specific, written prior permission. Red -+ * Hat makes no representations about the suitability of this software -+ * for any purpose. It is provided "as is" without express or implied -+ * warranty. -+ * -+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN -+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR -+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#include "draglock.h" -+ -+#include -+#include -+ -+#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) -+ -+static int -+draglock_parse_config(struct draglock *dl, const char *config) -+{ -+ int button = 0, target = 0; -+ const char *str = NULL; -+ char *end_str = NULL; -+ int pairs[DRAGLOCK_MAX_BUTTONS] = {0}; -+ -+ if (!config) -+ return 0; -+ -+ /* empty string disables drag lock */ -+ if (*config == '\0') { -+ dl->mode = DRAGLOCK_DISABLED; -+ return 0; -+ } -+ -+ /* check for a single-number string first, config is "" */ -+ button = strtol(config, &end_str, 10); -+ if (*end_str == '\0') { -+ if (button < 0 || button >= DRAGLOCK_MAX_BUTTONS) -+ return 1; -+ /* we allow for button 0 so stacked xorg.conf.d snippets can -+ * disable the config again */ -+ if (button == 0) { -+ dl->mode = DRAGLOCK_DISABLED; -+ return 0; -+ } -+ -+ return draglock_set_meta(dl, button); -+ } -+ -+ dl->mode = DRAGLOCK_DISABLED; -+ -+ /* check for a set of button pairs, config is -+ * " ..." */ -+ str = config; -+ while (*str != '\0') { -+ button = strtol(str, &end_str, 10); -+ if (*end_str == '\0') -+ return 1; -+ -+ str = end_str; -+ target = strtol(str, &end_str, 10); -+ if (end_str == str) -+ return 1; -+ if (button <= 0 || button >= DRAGLOCK_MAX_BUTTONS || target >= DRAGLOCK_MAX_BUTTONS) -+ return 1; -+ -+ pairs[button] = target; -+ str = end_str; -+ } -+ -+ return draglock_set_pairs(dl, pairs, ARRAY_SIZE(pairs)); -+} -+ -+int -+draglock_init_from_string(struct draglock *dl, const char *config) -+{ -+ dl->mode = DRAGLOCK_DISABLED; -+ -+ dl->meta_button = 0; -+ dl->meta_state = false; -+ memset(dl->lock_pair, 0, sizeof(dl->lock_pair)); -+ memset(dl->lock_state, 0, sizeof(dl->lock_state)); -+ -+ return draglock_parse_config(dl, config); -+} -+ -+enum draglock_mode -+draglock_get_mode(const struct draglock *dl) -+{ -+ return dl->mode; -+} -+ -+int -+draglock_get_meta(const struct draglock *dl) -+{ -+ if (dl->mode == DRAGLOCK_META) -+ return dl->meta_button; -+ return 0; -+} -+ -+size_t -+draglock_get_pairs(const struct draglock *dl, int *array, size_t sz) -+{ -+ unsigned int i; -+ size_t last = 0; -+ -+ if (dl->mode != DRAGLOCK_PAIRS) -+ return 0; -+ -+ /* size 1 array with the meta button */ -+ if (dl->meta_button) { -+ *array = dl->meta_button; -+ return 1; -+ } -+ -+ /* size N array with a[0] == 0, the rest ordered by button number */ -+ memset(array, 0, sz * sizeof(array[0])); -+ for (i = 0; i < sz && i < ARRAY_SIZE(dl->lock_pair); i++) { -+ array[i] = dl->lock_pair[i]; -+ if (array[i] != 0 && i > last) -+ last = i; -+ } -+ return last; -+} -+ -+int -+draglock_set_meta(struct draglock *dl, int meta_button) -+{ -+ if (meta_button < 0 || meta_button >= DRAGLOCK_MAX_BUTTONS) -+ return 1; -+ -+ dl->meta_button = meta_button; -+ dl->mode = meta_button ? DRAGLOCK_META : DRAGLOCK_DISABLED; -+ -+ return 0; -+} -+ -+int -+draglock_set_pairs(struct draglock *dl, const int *array, size_t sz) -+{ -+ unsigned int i; -+ -+ if (sz == 0 || array[0] != 0) -+ return 1; -+ -+ for (i = 0; i < sz; i++) { -+ if (array[i] < 0 || array[i] >= DRAGLOCK_MAX_BUTTONS) -+ return 1; -+ } -+ -+ dl->mode = DRAGLOCK_DISABLED; -+ for (i = 0; i < sz; i++) { -+ dl->lock_pair[i] = array[i]; -+ if (dl->lock_pair[i]) -+ dl->mode = DRAGLOCK_PAIRS; -+ } -+ -+ return 0; -+} -+ -+static int -+draglock_filter_meta(struct draglock *dl, int *button, int *press) -+{ -+ int b = *button, -+ is_press = *press; -+ -+ if (b == dl->meta_button) { -+ if (is_press) -+ dl->meta_state = true; -+ *button = 0; -+ return 0; -+ } -+ -+ switch (dl->lock_state[b]) { -+ case DRAGLOCK_BUTTON_STATE_NONE: -+ if (dl->meta_state && is_press) { -+ dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_DOWN_1; -+ dl->meta_state = false; -+ } -+ break; -+ case DRAGLOCK_BUTTON_STATE_DOWN_1: -+ if (!is_press) { -+ dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_UP_1; -+ b = 0; -+ } -+ break; -+ case DRAGLOCK_BUTTON_STATE_UP_1: -+ if (is_press) { -+ dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_DOWN_2; -+ b = 0; -+ } -+ break; -+ case DRAGLOCK_BUTTON_STATE_DOWN_2: -+ if (!is_press) { -+ dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_NONE; -+ } -+ break; -+ } -+ -+ *button = b; -+ -+ return 0; -+} -+ -+static int -+draglock_filter_pair(struct draglock *dl, int *button, int *press) -+{ -+ int b = *button, -+ is_press = *press; -+ -+ if (dl->lock_pair[b] == 0) -+ return 0; -+ -+ switch (dl->lock_state[b]) { -+ case DRAGLOCK_BUTTON_STATE_NONE: -+ if (is_press) { -+ dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_DOWN_1; -+ b = dl->lock_pair[b]; -+ } -+ break; -+ case DRAGLOCK_BUTTON_STATE_DOWN_1: -+ if (!is_press) { -+ dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_UP_1; -+ b = 0; -+ } -+ break; -+ case DRAGLOCK_BUTTON_STATE_UP_1: -+ if (is_press) { -+ dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_DOWN_2; -+ b = 0; -+ } -+ break; -+ case DRAGLOCK_BUTTON_STATE_DOWN_2: -+ if (!is_press) { -+ dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_NONE; -+ b = dl->lock_pair[b]; -+ } -+ break; -+ } -+ -+ *button = b; -+ -+ return 0; -+} -+ -+int -+draglock_filter_button(struct draglock *dl, int *button, int *is_press) -+{ -+ if (*button == 0) -+ return 0; -+ -+ switch(dl->mode) { -+ case DRAGLOCK_DISABLED: -+ return 0; -+ case DRAGLOCK_META: -+ return draglock_filter_meta(dl, button, is_press); -+ case DRAGLOCK_PAIRS: -+ return draglock_filter_pair(dl, button, is_press); -+ default: -+ abort(); -+ break; -+ } -+ -+ return 0; -+} -diff --git a/src/draglock.h b/src/draglock.h -new file mode 100644 -index 0000000..acc1314 ---- /dev/null -+++ b/src/draglock.h -@@ -0,0 +1,159 @@ -+/* -+ * Copyright © 2015 Red Hat, Inc. -+ * -+ * Permission to use, copy, modify, distribute, and sell this software -+ * and its documentation for any purpose is hereby granted without -+ * fee, provided that the above copyright notice appear in all copies -+ * and that both that copyright notice and this permission notice -+ * appear in supporting documentation, and that the name of Red Hat -+ * not be used in advertising or publicity pertaining to distribution -+ * of the software without specific, written prior permission. Red -+ * Hat makes no representations about the suitability of this software -+ * for any purpose. It is provided "as is" without express or implied -+ * warranty. -+ * -+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN -+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR -+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#ifndef DRAGLOCK_H -+#define DRAGLOCK_H 1 -+ -+#include -+#include -+ -+/* 32 buttons are enough for everybody™ -+ * Note that this is the limit of physical buttons as well as the highest -+ * allowed target button. -+ */ -+#define DRAGLOCK_MAX_BUTTONS 32 -+ -+enum draglock_mode -+{ -+ DRAGLOCK_DISABLED, -+ DRAGLOCK_META, -+ DRAGLOCK_PAIRS -+}; -+ -+enum draglock_button_state -+{ -+ DRAGLOCK_BUTTON_STATE_NONE, -+ DRAGLOCK_BUTTON_STATE_DOWN_1, -+ DRAGLOCK_BUTTON_STATE_UP_1, -+ DRAGLOCK_BUTTON_STATE_DOWN_2, -+}; -+ -+struct draglock -+{ -+ enum draglock_mode mode; -+ int meta_button; /* meta key to lock any button */ -+ bool meta_state; /* meta_button state */ -+ unsigned int lock_pair[DRAGLOCK_MAX_BUTTONS + 1];/* specify a meta/lock pair */ -+ enum draglock_button_state lock_state[DRAGLOCK_MAX_BUTTONS + 1]; /* state of any locked buttons */ -+}; -+ -+/** -+ * Initialize the draglock struct based on the config string. The string is -+ * either a single number to configure DRAGLOCK_META mode or a list of -+ * number pairs, with pair[0] as button and pair[1] as target lock number to -+ * configure DRAGLOCK_PAIRS mode. -+ * -+ * If config is NULL, the empty string, "0" or an even-numbered list of 0, -+ * the drag lock mode is DRAGLOCK_DISABLED. -+ * -+ * @return 0 on success or nonzero on error -+ */ -+int -+draglock_init_from_string(struct draglock *dl, const char *config); -+ -+/** -+ * Get the current drag lock mode. -+ * -+ * If the mode is DRAGLOCK_META, a meta button click will cause the next -+ * subsequent button click to be held logically down until the release of -+ * the second button click of that same button. Events from the meta button -+ * are always discarded. -+ * -+ * If the mode is DRAGLOCK_PAIRS, any button may be configured with a -+ * 'target' button number. A click of that button causes the target button -+ * to be held logically down until the release of the second button click. -+ */ -+enum draglock_mode -+draglock_get_mode(const struct draglock *dl); -+ -+/** -+ * @return the meta button number or 0 if the current mode is not -+ * DRAGLOCK_META. -+ */ -+int -+draglock_get_meta(const struct draglock *dl); -+ -+/** -+ * Get the drag lock button mapping pairs. The array is filled with the -+ * button number as index and the mapped target button number as value, i.e. -+ * array[3] == 8 means button 3 will draglock button 8. -+ * -+ * A value of 0 indicates draglock is disabled for that button. -+ * -+ * @note Button numbers start at 1, array[0] is always 0. -+ * -+ * @param[in|out] array Caller-allocated array to hold the button mappings. -+ * @param[in] sz Maximum number of elements in array -+ * -+ * @return The number of valid elements in array or 0 if the current mode is -+ * not DRAGLOCK_PAIRS -+ */ -+size_t -+draglock_get_pairs(const struct draglock *dl, int *array, size_t sz); -+ -+/** -+ * Set the drag lock config to the DRAGLOCK_META mode, with the given -+ * button as meta button. -+ * -+ * If the button is 0 the mode becomes DRAGLOCK_DISABLED. -+ * -+ * @return 0 on success, nonzero otherwise -+ */ -+int -+draglock_set_meta(struct draglock *dl, int meta_button); -+ -+/** -+ * Set the drag lock config to the DRAGLOCK_PAIRS mode. The array -+ * must be filled with the button number as index and the mapped target -+ * button number as value, i.e. -+ * array[3] == 8 means button 3 will draglock button 8. -+ * -+ * A value of 0 indicates draglock is disabled for that button. If all -+ * buttons are 0, the mode becomes DRAGLOCK_DISABLED. -+ * -+ * @note Button numbers start at 1, array[0] is always 0. -+ * -+ * @return 0 on successor nonzero otherwise -+ */ -+int -+draglock_set_pairs(struct draglock *dl, const int *array, size_t sz); -+ -+/** -+ * Process the given button event through the drag lock state machine. -+ * If the event is to be discarded by the caller, button is set to 0. -+ * Otherwise, button is set to the button event to process and is_press is -+ * set to the button state to process. -+ * -+ * @param[in|out] button The button number to process -+ * @param[in|out] is_press nonzero for press, zero for release -+ * -+ * @return 0 on success or 1 on error -+ */ -+int -+draglock_filter_button(struct draglock *dl, int *button, int *is_press); -+ -+#endif /* DRAGLOCK_H */ -diff --git a/src/libinput.c b/src/libinput.c -index 49f73c9..10b9b1d 100644 ---- a/src/libinput.c -+++ b/src/libinput.c -@@ -1,5 +1,5 @@ - /* -- * Copyright © 2013 Red Hat, Inc. -+ * Copyright © 2013-2015 Red Hat, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without -@@ -41,6 +41,7 @@ - - #include - -+#include "draglock.h" - #include "libinput-properties.h" - - #ifndef XI86_SERVER_FD -@@ -112,6 +113,8 @@ struct xf86libinput { - - unsigned char btnmap[MAX_BUTTONS + 1]; - } options; -+ -+ struct draglock draglock; - }; - - /* -@@ -770,12 +773,18 @@ static void - xf86libinput_handle_button(InputInfoPtr pInfo, struct libinput_event_pointer *event) - { - DeviceIntPtr dev = pInfo->dev; -+ struct xf86libinput *driver_data = pInfo->private; - int button; - int is_press; - - button = btn_linux2xorg(libinput_event_pointer_get_button(event)); - is_press = (libinput_event_pointer_get_button_state(event) == LIBINPUT_BUTTON_STATE_PRESSED); -- xf86PostButtonEvent(dev, Relative, button, is_press, 0, 0); -+ -+ if (draglock_get_mode(&driver_data->draglock) != DRAGLOCK_DISABLED) -+ draglock_filter_button(&driver_data->draglock, &button, &is_press); -+ -+ if (button) -+ xf86PostButtonEvent(dev, Relative, button, is_press, 0, 0); - } - - static void -@@ -1403,6 +1412,20 @@ xf86libinput_parse_buttonmap_option(InputInfoPtr pInfo, - free(mapping); - } - -+static inline void -+xf86libinput_parse_draglock_option(InputInfoPtr pInfo, -+ struct xf86libinput *driver_data) -+{ -+ char *str; -+ -+ str = xf86CheckStrOption(pInfo->options, "DragLockButtons",NULL); -+ if (draglock_init_from_string(&driver_data->draglock, str) != 0) -+ xf86IDrvMsg(pInfo, X_ERROR, -+ "Invalid DragLockButtons option: \"%s\"\n", -+ str); -+ free(str); -+} -+ - static void - xf86libinput_parse_options(InputInfoPtr pInfo, - struct xf86libinput *driver_data, -@@ -1428,6 +1451,8 @@ xf86libinput_parse_options(InputInfoPtr pInfo, - xf86libinput_parse_buttonmap_option(pInfo, - options->btnmap, - sizeof(options->btnmap)); -+ if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER)) -+ xf86libinput_parse_draglock_option(pInfo, driver_data); - } - - static int -@@ -1621,6 +1646,9 @@ static Atom prop_middle_emulation_default; - static Atom prop_disable_while_typing; - static Atom prop_disable_while_typing_default; - -+/* driver properties */ -+static Atom prop_draglock; -+ - /* general properties */ - static Atom prop_float; - static Atom prop_device; -@@ -2060,6 +2088,85 @@ LibinputSetPropertyDisableWhileTyping(DeviceIntPtr dev, - return Success; - } - -+static inline int -+prop_draglock_set_meta(struct xf86libinput *driver_data, -+ const BYTE *values, -+ int len, -+ BOOL checkonly) -+{ -+ struct draglock *dl, -+ dummy; /* for checkonly */ -+ int meta; -+ -+ if (len > 1) -+ return BadImplementation; /* should not happen */ -+ -+ dl = (checkonly) ? &dummy : &driver_data->draglock; -+ meta = len > 0 ? values[0] : 0; -+ -+ return draglock_set_meta(dl, meta) == 0 ? Success: BadValue; -+} -+ -+static inline int -+prop_draglock_set_pairs(struct xf86libinput *driver_data, -+ const BYTE* pairs, -+ int len, -+ BOOL checkonly) -+{ -+ struct draglock *dl, -+ dummy; /* for checkonly */ -+ int data[MAX_BUTTONS + 1] = {0}; -+ int i; -+ int highest = 0; -+ -+ if (len >= ARRAY_SIZE(data)) -+ return BadMatch; -+ -+ if (len < 2 || len % 2) -+ return BadImplementation; /* should not happen */ -+ -+ dl = (checkonly) ? &dummy : &driver_data->draglock; -+ -+ for (i = 0; i < len; i += 2) { -+ if (pairs[i] > MAX_BUTTONS) -+ return BadValue; -+ -+ data[pairs[i]] = pairs[i+1]; -+ highest = max(highest, pairs[i]); -+ } -+ -+ return draglock_set_pairs(dl, data, highest + 1) == 0 ? Success : BadValue; -+} -+ -+static inline int -+LibinputSetPropertyDragLockButtons(DeviceIntPtr dev, -+ Atom atom, -+ XIPropertyValuePtr val, -+ BOOL checkonly) -+{ -+ InputInfoPtr pInfo = dev->public.devicePrivate; -+ struct xf86libinput *driver_data = pInfo->private; -+ -+ if (val->format != 8 || val->type != XA_INTEGER) -+ return BadMatch; -+ -+ /* either a single value, or pairs of values */ -+ if (val->size > 1 && val->size % 2) -+ return BadMatch; -+ -+ if (!xf86libinput_check_device(dev, atom)) -+ return BadMatch; -+ -+ if (val->size <= 1) -+ return prop_draglock_set_meta(driver_data, -+ (BYTE*)val->data, -+ val->size, checkonly); -+ else -+ return prop_draglock_set_pairs(driver_data, -+ (BYTE*)val->data, -+ val->size, checkonly); -+} -+ - static int - LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, - BOOL checkonly) -@@ -2097,6 +2204,8 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, - rc = LibinputSetPropertyMiddleEmulation(dev, atom, val, checkonly); - else if (atom == prop_disable_while_typing) - rc = LibinputSetPropertyDisableWhileTyping(dev, atom, val, checkonly); -+ else if (atom == prop_draglock) -+ rc = LibinputSetPropertyDragLockButtons(dev, atom, val, checkonly); - else if (atom == prop_device || atom == prop_product_id || - atom == prop_tap_default || - atom == prop_tap_drag_lock_default || -@@ -2565,6 +2674,37 @@ LibinputInitDisableWhileTypingProperty(DeviceIntPtr dev, - } - - static void -+LibinputInitDragLockProperty(DeviceIntPtr dev, -+ struct xf86libinput *driver_data) -+{ -+ size_t sz; -+ int dl_values[MAX_BUTTONS + 1]; -+ -+ if (!libinput_device_has_capability(driver_data->device, -+ LIBINPUT_DEVICE_CAP_POINTER)) -+ return; -+ -+ switch (draglock_get_mode(&driver_data->draglock)) { -+ case DRAGLOCK_DISABLED: -+ sz = 0; /* will be an empty property */ -+ break; -+ case DRAGLOCK_META: -+ dl_values[0] = draglock_get_meta(&driver_data->draglock); -+ sz = 1; -+ break; -+ case DRAGLOCK_PAIRS: -+ sz = draglock_get_pairs(&driver_data->draglock, -+ dl_values, sizeof(dl_values)); -+ break; -+ } -+ -+ prop_draglock = LibinputMakeProperty(dev, -+ LIBINPUT_PROP_DRAG_LOCK_BUTTONS, -+ XA_INTEGER, 8, -+ sz, dl_values); -+} -+ -+static void - LibinputInitProperty(DeviceIntPtr dev) - { - InputInfoPtr pInfo = dev->public.devicePrivate; -@@ -2613,4 +2753,6 @@ LibinputInitProperty(DeviceIntPtr dev) - return; - - XISetDevicePropertyDeletable(dev, prop_product_id, FALSE); -+ -+ LibinputInitDragLockProperty(dev, driver_data); - } -diff --git a/test/.gitignore b/test/.gitignore -new file mode 100644 -index 0000000..48a46e3 ---- /dev/null -+++ b/test/.gitignore -@@ -0,0 +1 @@ -+test-draglock -diff --git a/test/Makefile.am b/test/Makefile.am -new file mode 100644 -index 0000000..6f94abe ---- /dev/null -+++ b/test/Makefile.am -@@ -0,0 +1,13 @@ -+AM_CPPFLAGS = $(XORG_CFLAGS) \ -+ $(CWARNFLAGS) \ -+ -I$(top_srcdir)/include \ -+ -I$(top_srcdir)/src -+ -+tests = test-draglock -+ -+noinst_PROGRAMS = $(tests) -+ -+test_draglock_SOURCES = test-draglock.c -+test_draglock_LDADD = ../src/libdraglock.la -+ -+TESTS = $(tests) -diff --git a/test/test-draglock.c b/test/test-draglock.c -new file mode 100644 -index 0000000..96ef5bb ---- /dev/null -+++ b/test/test-draglock.c -@@ -0,0 +1,540 @@ -+/* -+ * Copyright © 2013-2015 Red Hat, Inc. -+ * -+ * Permission to use, copy, modify, distribute, and sell this software -+ * and its documentation for any purpose is hereby granted without -+ * fee, provided that the above copyright notice appear in all copies -+ * and that both that copyright notice and this permission notice -+ * appear in supporting documentation, and that the name of Red Hat -+ * not be used in advertising or publicity pertaining to distribution -+ * of the software without specific, written prior permission. Red -+ * Hat makes no representations about the suitability of this software -+ * for any purpose. It is provided "as is" without express or implied -+ * warranty. -+ * -+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN -+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR -+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include "draglock.h" -+ -+#include -+#include -+ -+static void -+test_config_empty(void) -+{ -+ struct draglock dl; -+ int rc; -+ -+ rc = draglock_init_from_string(&dl, NULL); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+ assert(rc == 0); -+} -+ -+static void -+test_config_invalid(void) -+{ -+ struct draglock dl; -+ int rc; -+ -+ /* no trailing space */ -+ rc = draglock_init_from_string(&dl, "1 "); -+ assert(rc != 0); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+ -+ rc = draglock_init_from_string(&dl, "256"); -+ assert(rc != 0); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+ -+ rc = draglock_init_from_string(&dl, "-1"); -+ assert(rc != 0); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+ -+ rc = draglock_init_from_string(&dl, "1 2 3"); -+ assert(rc != 0); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+ -+ rc = draglock_init_from_string(&dl, "0 2"); -+ assert(rc != 0); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+ -+ rc = draglock_init_from_string(&dl, "0 0"); -+ assert(rc != 0); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+} -+ -+static void -+test_config_disable(void) -+{ -+ struct draglock dl; -+ int rc; -+ -+ rc = draglock_init_from_string(&dl, ""); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+ -+ rc = draglock_init_from_string(&dl, "0"); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+} -+ -+static void -+test_config_meta_button(void) -+{ -+ struct draglock dl; -+ int rc; -+ -+ rc = draglock_init_from_string(&dl, "1"); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_META); -+ assert(dl.meta_button == 1); -+ -+ rc = draglock_init_from_string(&dl, "2"); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_META); -+ assert(dl.meta_button == 2); -+ -+ rc = draglock_init_from_string(&dl, "10"); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_META); -+ assert(dl.meta_button == 10); -+} -+ -+static void -+test_config_button_pairs(void) -+{ -+ struct draglock dl; -+ int rc; -+ -+ rc = draglock_init_from_string(&dl, "1 1"); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_PAIRS); -+ -+ rc = draglock_init_from_string(&dl, "1 2 3 4 5 6 7 8"); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_PAIRS); -+ -+ rc = draglock_init_from_string(&dl, "1 2 3 4 5 0 7 8"); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_PAIRS); -+ -+ /* all disabled */ -+ rc = draglock_init_from_string(&dl, "1 0 3 0 5 0 7 0"); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+} -+ -+static void -+test_config_get(void) -+{ -+ struct draglock dl; -+ int rc; -+ const int sz = 32; -+ int map[sz]; -+ -+ draglock_init_from_string(&dl, ""); -+ rc = draglock_get_meta(&dl); -+ assert(rc == 0); -+ rc = draglock_get_pairs(&dl, map, sz); -+ assert(rc == 0); -+ -+ draglock_init_from_string(&dl, "8"); -+ rc = draglock_get_meta(&dl); -+ assert(rc == 8); -+ rc = draglock_get_pairs(&dl, map, sz); -+ assert(rc == 0); -+ -+ draglock_init_from_string(&dl, "1 2 3 4 5 6"); -+ rc = draglock_get_meta(&dl); -+ assert(rc == 0); -+ rc = draglock_get_pairs(&dl, map, sz); -+ assert(rc == 5); -+ assert(map[0] == 0); -+ assert(map[1] == 2); -+ assert(map[2] == 0); -+ assert(map[3] == 4); -+ assert(map[4] == 0); -+ assert(map[5] == 6); -+} -+ -+static void -+test_set_meta(void) -+{ -+ struct draglock dl; -+ int rc; -+ -+ draglock_init_from_string(&dl, ""); -+ -+ rc = draglock_set_meta(&dl, 0); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+ -+ rc = draglock_set_meta(&dl, 1); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_META); -+ -+ rc = draglock_set_meta(&dl, -1); -+ assert(rc == 1); -+ rc = draglock_set_meta(&dl, 32); -+ assert(rc == 1); -+} -+ -+static void -+test_set_pairs(void) -+{ -+ struct draglock dl; -+ int rc; -+ const int sz = 32; -+ int map[sz]; -+ -+ draglock_init_from_string(&dl, ""); -+ memset(map, 0, sizeof(map)); -+ -+ rc = draglock_set_pairs(&dl, map, sz); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+ -+ rc = draglock_set_pairs(&dl, map, 1); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_DISABLED); -+ -+ map[0] = 1; -+ rc = draglock_set_pairs(&dl, map, 1); -+ assert(rc == 1); -+ -+ map[0] = 0; -+ map[1] = 2; -+ rc = draglock_set_pairs(&dl, map, sz); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_PAIRS); -+ -+ map[0] = 0; -+ map[1] = 0; -+ map[10] = 8; -+ rc = draglock_set_pairs(&dl, map, sz); -+ assert(rc == 0); -+ assert(dl.mode == DRAGLOCK_PAIRS); -+} -+ -+static void -+test_filter_meta_passthrough(void) -+{ -+ struct draglock dl; -+ int rc; -+ int button, press; -+ int i; -+ -+ rc = draglock_init_from_string(&dl, "10"); -+ -+ for (i = 0; i < 10; i++) { -+ button = i; -+ press = 1; -+ -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == i); -+ assert(press == 1); -+ -+ press = 1; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == i); -+ assert(press == 1); -+ } -+} -+ -+static void -+test_filter_meta_click_meta_only(void) -+{ -+ struct draglock dl; -+ int rc; -+ int button, press; -+ -+ rc = draglock_init_from_string(&dl, "10"); -+ -+ button = 10; -+ press = 1; -+ -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ button = 10; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+} -+ -+static void -+test_filter_meta(void) -+{ -+ struct draglock dl; -+ int rc; -+ int button, press; -+ int i; -+ -+ rc = draglock_init_from_string(&dl, "10"); -+ -+ for (i = 1; i < 10; i++) { -+ /* meta down */ -+ button = 10; -+ press = 1; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* meta up */ -+ button = 10; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* button down -> passthrough */ -+ button = i; -+ press = 1; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == i); -+ -+ /* button up -> eaten */ -+ button = i; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* button down -> eaten */ -+ button = i; -+ press = 1; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* button up -> passthrough */ -+ button = i; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == i); -+ assert(press == 0); -+ } -+} -+ -+static void -+test_filter_meta_extra_click(void) -+{ -+ struct draglock dl; -+ int rc; -+ int button, press; -+ int i; -+ -+ rc = draglock_init_from_string(&dl, "10"); -+ -+ for (i = 1; i < 10; i++) { -+ /* meta down */ -+ button = 10; -+ press = 1; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* meta up */ -+ button = 10; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* button down -> passthrough */ -+ button = i; -+ press = 1; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == i); -+ -+ /* button up -> eaten */ -+ button = i; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* meta down */ -+ button = 10; -+ press = 1; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* meta up */ -+ button = 10; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* button down -> eaten */ -+ button = i; -+ press = 1; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* button up -> passthrough */ -+ button = i; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == i); -+ assert(press == 0); -+ } -+} -+ -+static void -+test_filter_meta_interleaved(void) -+{ -+ struct draglock dl; -+ int rc; -+ int button, press; -+ int i; -+ -+ rc = draglock_init_from_string(&dl, "10"); -+ -+ for (i = 1; i < 10; i++) { -+ /* meta down */ -+ button = 10; -+ press = 1; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* meta up */ -+ button = 10; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* button down -> passthrough */ -+ button = i; -+ press = 1; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == i); -+ -+ /* button up -> eaten */ -+ button = i; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ } -+ -+ for (i = 0; i < 10; i++) { -+ /* button down -> eaten */ -+ button = i; -+ press = 1; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == 0); -+ -+ /* button up -> passthrough */ -+ button = i; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ assert(button == i); -+ assert(press == 0); -+ } -+} -+ -+static void -+test_filter_pairs(void) -+{ -+ struct draglock dl; -+ int rc; -+ int button, press; -+ int i; -+ -+ rc = draglock_init_from_string(&dl, "1 11 2 0 3 13 4 0 5 15 6 0 7 17 8 0 9 19"); -+ -+ for (i = 1; i < 10; i++) { -+ button = i; -+ press = 1; -+ -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ if (i % 2) -+ assert(button == i + 10); -+ else -+ assert(button == i); -+ assert(press == 1); -+ -+ button = i; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ if (i % 2) { -+ assert(button == 0); -+ } else { -+ assert(button == i); -+ assert(press == 0); -+ } -+ } -+ -+ for (i = 1; i < 10; i++) { -+ button = i; -+ press = 1; -+ -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ if (i % 2) { -+ assert(button == 0); -+ } else { -+ assert(button == i); -+ assert(press == 1); -+ } -+ -+ button = i; -+ press = 0; -+ rc = draglock_filter_button(&dl, &button, &press); -+ assert(rc == 0); -+ if (i % 2) -+ assert(button == i + 10); -+ else -+ assert(button == i); -+ assert(press == 0); -+ } -+} -+ -+int -+main(int argc, char **argv) -+{ -+ test_config_empty(); -+ test_config_invalid(); -+ test_config_disable(); -+ test_config_meta_button(); -+ test_config_button_pairs(); -+ -+ test_config_get(); -+ test_set_meta(); -+ test_set_pairs(); -+ -+ test_filter_meta_passthrough(); -+ test_filter_meta_click_meta_only(); -+ test_filter_meta(); -+ test_filter_meta_extra_click(); -+ test_filter_meta_interleaved(); -+ -+ test_filter_pairs(); -+ -+ return 0; -+} --- -2.4.3 - diff --git a/0001-Fedora-use-unaccelerated-vmask-on-input-ABI-21.patch b/0001-Fedora-use-unaccelerated-vmask-on-input-ABI-21.patch index 5a33866..52242e8 100644 --- a/0001-Fedora-use-unaccelerated-vmask-on-input-ABI-21.patch +++ b/0001-Fedora-use-unaccelerated-vmask-on-input-ABI-21.patch @@ -11,8 +11,8 @@ Signed-off-by: Peter Hutterer diff --git a/src/libinput.c b/src/libinput.c index a06e44f..5eb5adf 100644 ---- a/src/libinput.c -+++ b/src/libinput.c +--- a/src/xf86libinput.c ++++ b/src/xf86libinput.c @@ -47,7 +47,7 @@ #define XI86_SERVER_FD 0x20 #endif diff --git a/sources b/sources index e19aa2d..c0d927b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -6881879dacf4db34db6ca2113dbef949 xf86-input-libinput-0.13.0.tar.bz2 +10c06d3dd626dfdad3174d1f4e856a2a xf86-input-libinput-0.14.0.tar.bz2 diff --git a/xorg-x11-drv-libinput.spec b/xorg-x11-drv-libinput.spec index 12ffbe0..2862599 100644 --- a/xorg-x11-drv-libinput.spec +++ b/xorg-x11-drv-libinput.spec @@ -4,8 +4,8 @@ Summary: Xorg X11 libinput input driver Name: xorg-x11-drv-libinput -Version: 0.13.0 -Release: 2%{?dist} +Version: 0.14.0 +Release: 1%{?dist} URL: http://www.x.org License: MIT @@ -15,8 +15,6 @@ Source1: 90-libinput.conf # Fedora-specific unless merged into 1.7.3 at least Patch00: 0001-Fedora-use-unaccelerated-vmask-on-input-ABI-21.patch -Patch01: 0001-Add-drag-lock-support.patch - ExcludeArch: s390 s390x BuildRequires: autoconf automake libtool @@ -39,7 +37,6 @@ supporting all devices. %prep %setup -q -n %{tarball}-%{version} %patch00 -p1 -%patch01 -p1 %build autoreconf --force -v --install || exit 1 @@ -75,6 +72,9 @@ Xorg X11 libinput input driver development files. %{_includedir}/xorg/libinput-properties.h %changelog +* Mon Aug 31 2015 Peter Hutterer 0.14.0-1 +- xf86-input-libinput 0.14.0 + * Mon Aug 17 2015 Peter Hutterer 0.13.0-2 - Add drag lock support (#1249309)