src_libinput = src_libfilter + [
'src/libinput.c',
'src/libinput.h',
+ 'src/libinput-private-config.c',
+ 'src/libinput-private-config.h',
'src/libinput-private.h',
'src/evdev.c',
'src/evdev.h',
config_h.set10('HAVE_LIBSYSTEMD', dep_libsystemd.found())
litest_sources = [
+ 'src/libinput-private-config.c',
+ 'src/libinput-private-config.h',
'test/litest.h',
'test/litest-int.h',
'test/litest-device-absinfo-override.c',
return (!tp->semi_mt && tp->num_slots > 1);
}
+static enum libinput_config_status
+tp_gesture_set_hold_enabled(struct libinput_device *device,
+ enum libinput_config_hold_state enabled)
+{
+ struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
+ struct tp_dispatch *tp = tp_dispatch(dispatch);
+
+ if (!tp_gesture_are_gestures_enabled(tp))
+ return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
+
+ tp->gesture.hold_enabled = (enabled == LIBINPUT_CONFIG_HOLD_ENABLED);
+
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+}
+
+static enum libinput_config_hold_state
+tp_gesture_is_hold_enabled(struct libinput_device *device)
+{
+ struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
+ struct tp_dispatch *tp = tp_dispatch(dispatch);
+
+ return tp->gesture.hold_enabled ? LIBINPUT_CONFIG_HOLD_ENABLED :
+ LIBINPUT_CONFIG_HOLD_DISABLED;
+}
+
+static enum libinput_config_hold_state
+tp_gesture_get_hold_default(struct libinput_device *device)
+{
+ struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
+ struct tp_dispatch *tp = tp_dispatch(dispatch);
+
+ return tp_gesture_are_gestures_enabled(tp) ?
+ LIBINPUT_CONFIG_HOLD_ENABLED :
+ LIBINPUT_CONFIG_HOLD_DISABLED;
+}
+
void
tp_init_gesture(struct tp_dispatch *tp)
{
char timer_name[64];
+ tp->gesture.config.set_hold_enabled = tp_gesture_set_hold_enabled;
+ tp->gesture.config.get_hold_enabled = tp_gesture_is_hold_enabled;
+ tp->gesture.config.get_hold_default = tp_gesture_get_hold_default;
+ tp->device->base.config.gesture = &tp->gesture.config;
+
/* two-finger scrolling is always enabled, this flag just
* decides whether we detect pinch. semi-mt devices are too
* unreliable to do pinch gestures. */
tp->gesture.enabled = tp_gesture_are_gestures_enabled(tp);
tp->gesture.state = GESTURE_STATE_NONE;
+ tp->gesture.hold_enabled = tp_gesture_are_gestures_enabled(tp);
snprintf(timer_name,
sizeof(timer_name),
} accel;
struct {
+ struct libinput_device_config_gesture config;
bool enabled;
bool started;
unsigned int finger_count;
double prev_scale;
double angle;
struct device_float_coords center;
+ bool hold_enabled;
} gesture;
struct {
--- /dev/null
+/*
+ * Copyright © 2021 Red Hat, Inc.
+ * Copyright © 2021 José Expósito
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#include "libinput-private-config.h"
+#include "libinput-private.h"
+
+int
+libinput_device_config_gesture_hold_is_available(struct libinput_device *device)
+{
+ if (!libinput_device_has_capability(device,
+ LIBINPUT_DEVICE_CAP_GESTURE))
+ return 0;
+
+ if (!device->config.gesture->get_hold_default(device))
+ return 0;
+
+ return 1;
+}
+
+enum libinput_config_status
+libinput_device_config_gesture_set_hold_enabled(struct libinput_device *device,
+ enum libinput_config_hold_state enable)
+{
+ if (enable != LIBINPUT_CONFIG_HOLD_ENABLED &&
+ enable != LIBINPUT_CONFIG_HOLD_DISABLED)
+ return LIBINPUT_CONFIG_STATUS_INVALID;
+
+ if (!libinput_device_config_gesture_hold_is_available(device)) {
+ return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED :
+ LIBINPUT_CONFIG_STATUS_SUCCESS;
+ }
+
+ return device->config.gesture->set_hold_enabled(device, enable);
+}
+
+enum libinput_config_hold_state
+libinput_device_config_gesture_get_hold_enabled(struct libinput_device *device)
+{
+ if (!libinput_device_config_gesture_hold_is_available(device))
+ return LIBINPUT_CONFIG_HOLD_DISABLED;
+
+ return device->config.gesture->get_hold_enabled(device);
+}
+
+enum libinput_config_hold_state
+libinput_device_config_gesture_get_hold_default_enabled(struct libinput_device *device)
+{
+ if (!libinput_device_config_gesture_hold_is_available(device))
+ return LIBINPUT_CONFIG_HOLD_DISABLED;
+
+ return device->config.gesture->get_hold_default(device);
+}
--- /dev/null
+/*
+ * Copyright © 2021 Red Hat, Inc.
+ * Copyright © 2021 José Expósito
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef LIBINPUT_PRIVATE_CONFIG_H
+#define LIBINPUT_PRIVATE_CONFIG_H
+
+#include "config.h"
+
+#include "libinput.h"
+
+enum libinput_config_hold_state {
+ /** Hold gestures are to be disabled, or are currently disabled */
+ LIBINPUT_CONFIG_HOLD_DISABLED,
+ /** Hold gestures are to be enabled, or are currently disabled */
+ LIBINPUT_CONFIG_HOLD_ENABLED,
+};
+
+/**
+ * @ingroup config
+ *
+ * Check whether a device can perform hold gestures.
+ *
+ * @param device The device to configure
+ * @return Non-zero if a device can perform hold gestures, zero otherwise.
+ *
+ * @see libinput_device_config_gesture_set_hold_enabled
+ * @see libinput_device_config_gesture_get_hold_enabled
+ * @see libinput_device_config_gesture_get_hold_default_enabled
+ */
+int
+libinput_device_config_gesture_hold_is_available(struct libinput_device *device);
+
+/**
+ * @ingroup config
+ *
+ * Enable or disable hold gestures on this device.
+ *
+ * @param device The device to configure
+ * @param enable @ref LIBINPUT_CONFIG_HOLD_ENABLED to enable hold gestures or
+ * @ref LIBINPUT_CONFIG_HOLD_DISABLED to disable them
+ *
+ * @return A config status code. Disabling hold gestures on a device that does
+ * not support them always succeeds.
+ *
+ * @see libinput_device_config_gesture_hold_is_available
+ * @see libinput_device_config_gesture_get_hold_enabled
+ * @see libinput_device_config_gesture_get_hold_default_enabled
+ */
+enum libinput_config_status
+libinput_device_config_gesture_set_hold_enabled(struct libinput_device *device,
+ enum libinput_config_hold_state enable);
+
+/**
+ * @ingroup config
+ *
+ * Check if hold gestures are enabled on this device. If the device does not
+ * support hold gestures, this function always returns @ref
+ * LIBINPUT_CONFIG_HOLD_DISABLED.
+ *
+ * @param device The device to configure
+ *
+ * @retval LIBINPUT_CONFIG_HOLD_ENABLED If hold gestures are currently enabled
+ * @retval LIBINPUT_CONFIG_HOLD_DISABLED If hold gestures are currently disabled
+ *
+ * @see libinput_device_config_gesture_hold_is_available
+ * @see libinput_device_config_gesture_set_hold_enabled
+ * @see libinput_device_config_gesture_get_hold_default_enabled
+ */
+enum libinput_config_hold_state
+libinput_device_config_gesture_get_hold_enabled(struct libinput_device *device);
+
+/**
+ * @ingroup config
+ *
+ * Return the default setting for whether hold gestures are enabled on this
+ * device.
+ *
+ * @param device The device to configure
+ * @retval LIBINPUT_CONFIG_HOLD_ENABLED If hold gestures are enabled by default
+ * @retval LIBINPUT_CONFIG_HOLD_DISABLED If hold gestures are disabled by
+ * default
+ *
+ * @see libinput_device_config_gesture_hold_is_available
+ * @see libinput_device_config_gesture_set_hold_enabled
+ * @see libinput_device_config_gesture_get_hold_enabled
+ */
+enum libinput_config_hold_state
+libinput_device_config_gesture_get_hold_default_enabled(struct libinput_device *device);
+
+#endif /* LIBINPUT_PRIVATE_CONFIG_H */
#include "linux/input.h"
#include "libinput.h"
+#include "libinput-private-config.h"
#include "libinput-util.h"
#include "libinput-version.h"
unsigned int (*get_default_angle)(struct libinput_device *device);
};
+struct libinput_device_config_gesture {
+ enum libinput_config_status (*set_hold_enabled)(struct libinput_device *device,
+ enum libinput_config_hold_state enabled);
+ enum libinput_config_hold_state (*get_hold_enabled)(struct libinput_device *device);
+ enum libinput_config_hold_state (*get_hold_default)(struct libinput_device *device);
+};
+
struct libinput_device_config {
struct libinput_device_config_tap *tap;
struct libinput_device_config_calibration *calibration;
struct libinput_device_config_middle_emulation *middle_emulation;
struct libinput_device_config_dwt *dwt;
struct libinput_device_config_rotation *rotation;
+ struct libinput_device_config_gesture *gesture;
};
struct libinput_device_group {
#include "check-double-macros.h"
+#include "libinput-private-config.h"
#include "libinput-util.h"
#include "quirks.h"
litest_assert_int_eq(status, expected);
}
+static inline void
+litest_enable_hold_gestures(struct libinput_device *device)
+{
+ enum libinput_config_status status, expected;
+
+ expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
+ status = libinput_device_config_gesture_set_hold_enabled(device,
+ LIBINPUT_CONFIG_HOLD_ENABLED);
+
+ litest_assert_int_eq(status, expected);
+}
+
+static inline void
+litest_disable_hold_gestures(struct libinput_device *device)
+{
+ enum libinput_config_status status, expected;
+
+ expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
+ status = libinput_device_config_gesture_set_hold_enabled(device,
+ LIBINPUT_CONFIG_HOLD_DISABLED);
+
+ litest_assert_int_eq(status, expected);
+}
+
static inline bool
litest_touchpad_is_external(struct litest_device *dev)
{
}
END_TEST
+START_TEST(gestures_hold_config_default_disabled)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+
+ ck_assert_int_eq(libinput_device_config_gesture_hold_is_available(device),
+ 0);
+ ck_assert_int_eq(libinput_device_config_gesture_get_hold_default_enabled(device),
+ LIBINPUT_CONFIG_HOLD_DISABLED);
+ ck_assert_int_eq(libinput_device_config_gesture_get_hold_default_enabled(device),
+ LIBINPUT_CONFIG_HOLD_DISABLED);
+}
+END_TEST
+
+START_TEST(gestures_hold_config_default_enabled)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+
+ ck_assert_int_eq(libinput_device_config_gesture_hold_is_available(device),
+ 1);
+ ck_assert_int_eq(libinput_device_config_gesture_get_hold_default_enabled(device),
+ LIBINPUT_CONFIG_HOLD_ENABLED);
+ ck_assert_int_eq(libinput_device_config_gesture_get_hold_enabled(device),
+ LIBINPUT_CONFIG_HOLD_ENABLED);
+}
+END_TEST
+
+START_TEST(gestures_hold_config_set_invalid)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+
+ ck_assert_int_eq(libinput_device_config_gesture_set_hold_enabled(device, -1),
+ LIBINPUT_CONFIG_STATUS_INVALID);
+ ck_assert_int_eq(libinput_device_config_gesture_set_hold_enabled(device, 2),
+ LIBINPUT_CONFIG_STATUS_INVALID);
+}
+END_TEST
+
+START_TEST(gestures_hold_config_is_available)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+
+ ck_assert_int_eq(libinput_device_config_gesture_hold_is_available(device),
+ 1);
+ ck_assert_int_eq(libinput_device_config_gesture_get_hold_enabled(device),
+ LIBINPUT_CONFIG_HOLD_ENABLED);
+ ck_assert_int_eq(libinput_device_config_gesture_set_hold_enabled(device, LIBINPUT_CONFIG_HOLD_DISABLED),
+ LIBINPUT_CONFIG_STATUS_SUCCESS);
+ ck_assert_int_eq(libinput_device_config_gesture_get_hold_enabled(device),
+ LIBINPUT_CONFIG_HOLD_DISABLED);
+}
+END_TEST
+
+START_TEST(gestures_hold_config_is_not_available)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+
+ ck_assert_int_eq(libinput_device_config_gesture_hold_is_available(device),
+ 0);
+ ck_assert_int_eq(libinput_device_config_gesture_get_hold_enabled(device),
+ LIBINPUT_CONFIG_HOLD_DISABLED);
+ ck_assert_int_eq(libinput_device_config_gesture_set_hold_enabled(device, LIBINPUT_CONFIG_HOLD_ENABLED),
+ LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
+ ck_assert_int_eq(libinput_device_config_gesture_set_hold_enabled(device, LIBINPUT_CONFIG_HOLD_DISABLED),
+ LIBINPUT_CONFIG_STATUS_SUCCESS);
+}
+END_TEST
+
TEST_COLLECTION(gestures)
{
struct range cardinals = { N, N + NCARDINALS };
litest_add(gestures_time_usec, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
+ litest_add(gestures_hold_config_default_disabled, LITEST_TOUCHPAD|LITEST_SEMI_MT, LITEST_ANY);
+ litest_add(gestures_hold_config_default_enabled, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
+ litest_add(gestures_hold_config_set_invalid, LITEST_TOUCHPAD, LITEST_ANY);
+ litest_add(gestures_hold_config_is_available, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
+ litest_add(gestures_hold_config_is_not_available, LITEST_TOUCHPAD|LITEST_SEMI_MT, LITEST_ANY);
+
/* Timing-sensitive test, valgrind is too slow */
if (!RUNNING_ON_VALGRIND)
litest_add(gestures_swipe_3fg_unaccel, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);