|
|
|
|
@@ -1,5 +1,5 @@
|
|
|
|
|
/*
|
|
|
|
|
* Copyright © 2013-2015 Red Hat, Inc.
|
|
|
|
|
* Copyright © 2013-2017 Red Hat, Inc.
|
|
|
|
|
*
|
|
|
|
|
* Permission to use, copy, modify, distribute, and sell this software
|
|
|
|
|
* and its documentation for any purpose is hereby granted without
|
|
|
|
|
@@ -65,6 +65,9 @@
|
|
|
|
|
#define TOUCH_MAX_SLOTS 15
|
|
|
|
|
#define XORG_KEYCODE_OFFSET 8
|
|
|
|
|
|
|
|
|
|
#define streq(a, b) (strcmp(a, b) == 0)
|
|
|
|
|
#define strneq(a, b, n) (strncmp(a, b, n) == 0)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
libinput does not provide axis information for absolute devices, instead
|
|
|
|
|
it scales into the screen dimensions provided. So we set up the axes with
|
|
|
|
|
@@ -209,6 +212,10 @@ update_mode_prop(InputInfoPtr pInfo,
|
|
|
|
|
static enum event_handling
|
|
|
|
|
xf86libinput_handle_event(struct libinput_event *event);
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xf86libinput_post_tablet_motion(InputInfoPtr pInfo,
|
|
|
|
|
struct libinput_event_tablet_tool *event);
|
|
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
|
use_server_fd(const InputInfoPtr pInfo) {
|
|
|
|
|
return pInfo->fd > -1 && (pInfo->flags & XI86_SERVER_FD);
|
|
|
|
|
@@ -259,7 +266,7 @@ xf86libinput_is_subdevice(InputInfoPtr pInfo)
|
|
|
|
|
BOOL is_subdevice;
|
|
|
|
|
|
|
|
|
|
source = xf86SetStrOption(pInfo->options, "_source", "");
|
|
|
|
|
is_subdevice = strcmp(source, "_driver/libinput") == 0;
|
|
|
|
|
is_subdevice = streq(source, "_driver/libinput");
|
|
|
|
|
free(source);
|
|
|
|
|
|
|
|
|
|
return is_subdevice;
|
|
|
|
|
@@ -454,19 +461,34 @@ xf86libinput_set_area_ratio(struct xf86libinput *driver_data,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* returns true if the device has one or more of the given capabilities or
|
|
|
|
|
* if the device isn't a subdevice
|
|
|
|
|
*/
|
|
|
|
|
static inline bool
|
|
|
|
|
subdevice_has_capabilities(DeviceIntPtr dev, uint32_t capabilities)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
struct xf86libinput *driver_data = pInfo->private;
|
|
|
|
|
|
|
|
|
|
if (!xf86libinput_is_subdevice(pInfo))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return !!(driver_data->capabilities & capabilities);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
|
|
|
|
|
BOOL checkonly);
|
|
|
|
|
static void
|
|
|
|
|
LibinputInitProperty(DeviceIntPtr dev);
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
LibinputApplyConfig(DeviceIntPtr dev)
|
|
|
|
|
static void
|
|
|
|
|
LibinputApplyConfigSendEvents(DeviceIntPtr dev,
|
|
|
|
|
struct xf86libinput *driver_data,
|
|
|
|
|
struct libinput_device *device)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
struct xf86libinput *driver_data = pInfo->private;
|
|
|
|
|
struct libinput_device *device = driver_data->shared_device->device;
|
|
|
|
|
unsigned int scroll_button;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_send_events_get_modes(device) != LIBINPUT_CONFIG_SEND_EVENTS_ENABLED &&
|
|
|
|
|
libinput_device_config_send_events_set_mode(device,
|
|
|
|
|
@@ -474,6 +496,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
|
|
|
|
xf86IDrvMsg(pInfo, X_ERROR,
|
|
|
|
|
"Failed to set SendEventsMode %u\n",
|
|
|
|
|
driver_data->options.sendevents);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
LibinputApplyConfigNaturalScroll(DeviceIntPtr dev,
|
|
|
|
|
struct xf86libinput *driver_data,
|
|
|
|
|
struct libinput_device *device)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_scroll_has_natural_scroll(device) &&
|
|
|
|
|
libinput_device_config_scroll_set_natural_scroll_enabled(device,
|
|
|
|
|
@@ -481,6 +514,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
|
|
|
|
xf86IDrvMsg(pInfo, X_ERROR,
|
|
|
|
|
"Failed to set NaturalScrolling to %d\n",
|
|
|
|
|
driver_data->options.natural_scrolling);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
LibinputApplyConfigAccel(DeviceIntPtr dev,
|
|
|
|
|
struct xf86libinput *driver_data,
|
|
|
|
|
struct libinput_device *device)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_accel_is_available(device) &&
|
|
|
|
|
libinput_device_config_accel_set_speed(device,
|
|
|
|
|
@@ -509,6 +553,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
|
|
|
|
}
|
|
|
|
|
xf86IDrvMsg(pInfo, X_ERROR, "Failed to set profile %s\n", profile);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
LibinputApplyConfigTap(DeviceIntPtr dev,
|
|
|
|
|
struct xf86libinput *driver_data,
|
|
|
|
|
struct libinput_device *device)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_tap_get_finger_count(device) > 0 &&
|
|
|
|
|
libinput_device_config_tap_set_enabled(device,
|
|
|
|
|
@@ -545,6 +600,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
|
|
|
|
xf86IDrvMsg(pInfo, X_ERROR,
|
|
|
|
|
"Failed to set Tapping Drag to %d\n",
|
|
|
|
|
driver_data->options.tap_drag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
LibinputApplyConfigCalibration(DeviceIntPtr dev,
|
|
|
|
|
struct xf86libinput *driver_data,
|
|
|
|
|
struct libinput_device *device)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_TOUCH|CAP_TABLET))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_calibration_has_matrix(device) &&
|
|
|
|
|
libinput_device_config_calibration_set_matrix(device,
|
|
|
|
|
@@ -557,6 +623,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
|
|
|
|
driver_data->options.matrix[4], driver_data->options.matrix[5],
|
|
|
|
|
driver_data->options.matrix[6], driver_data->options.matrix[7],
|
|
|
|
|
driver_data->options.matrix[8]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
LibinputApplyConfigLeftHanded(DeviceIntPtr dev,
|
|
|
|
|
struct xf86libinput *driver_data,
|
|
|
|
|
struct libinput_device *device)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER|CAP_TABLET))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_left_handed_is_available(device) &&
|
|
|
|
|
libinput_device_config_left_handed_set(device,
|
|
|
|
|
@@ -564,6 +641,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
|
|
|
|
xf86IDrvMsg(pInfo, X_ERROR,
|
|
|
|
|
"Failed to set LeftHanded to %d\n",
|
|
|
|
|
driver_data->options.left_handed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
LibinputApplyConfigScrollMethod(DeviceIntPtr dev,
|
|
|
|
|
struct xf86libinput *driver_data,
|
|
|
|
|
struct libinput_device *device)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_scroll_set_method(device,
|
|
|
|
|
driver_data->options.scroll_method) != LIBINPUT_CONFIG_STATUS_SUCCESS) {
|
|
|
|
|
@@ -584,12 +672,25 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_scroll_get_methods(device) & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) {
|
|
|
|
|
unsigned int scroll_button;
|
|
|
|
|
|
|
|
|
|
scroll_button = btn_xorg2linux(driver_data->options.scroll_button);
|
|
|
|
|
if (libinput_device_config_scroll_set_button(device, scroll_button) != LIBINPUT_CONFIG_STATUS_SUCCESS)
|
|
|
|
|
xf86IDrvMsg(pInfo, X_ERROR,
|
|
|
|
|
"Failed to set ScrollButton to %u\n",
|
|
|
|
|
driver_data->options.scroll_button);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
LibinputApplyConfigClickMethod(DeviceIntPtr dev,
|
|
|
|
|
struct xf86libinput *driver_data,
|
|
|
|
|
struct libinput_device *device)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_click_set_method(device,
|
|
|
|
|
driver_data->options.click_method) != LIBINPUT_CONFIG_STATUS_SUCCESS) {
|
|
|
|
|
@@ -607,6 +708,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
|
|
|
|
"Failed to set click method to %s\n",
|
|
|
|
|
method);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
LibinputApplyConfigMiddleEmulation(DeviceIntPtr dev,
|
|
|
|
|
struct xf86libinput *driver_data,
|
|
|
|
|
struct libinput_device *device)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_middle_emulation_is_available(device) &&
|
|
|
|
|
libinput_device_config_middle_emulation_set_enabled(device,
|
|
|
|
|
@@ -614,6 +726,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
|
|
|
|
xf86IDrvMsg(pInfo, X_ERROR,
|
|
|
|
|
"Failed to set MiddleEmulation to %d\n",
|
|
|
|
|
driver_data->options.middle_emulation);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
LibinputApplyConfigDisableWhileTyping(DeviceIntPtr dev,
|
|
|
|
|
struct xf86libinput *driver_data,
|
|
|
|
|
struct libinput_device *device)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_dwt_is_available(device) &&
|
|
|
|
|
libinput_device_config_dwt_set_enabled(device,
|
|
|
|
|
@@ -621,13 +744,43 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
|
|
|
|
xf86IDrvMsg(pInfo, X_ERROR,
|
|
|
|
|
"Failed to set DisableWhileTyping to %d\n",
|
|
|
|
|
driver_data->options.disable_while_typing);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
LibinputApplyConfigRotation(DeviceIntPtr dev,
|
|
|
|
|
struct xf86libinput *driver_data,
|
|
|
|
|
struct libinput_device *device)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_rotation_is_available(device) &&
|
|
|
|
|
libinput_device_config_rotation_set_angle(device, driver_data->options.rotation_angle) != LIBINPUT_CONFIG_STATUS_SUCCESS)
|
|
|
|
|
xf86IDrvMsg(pInfo, X_ERROR,
|
|
|
|
|
"Failed to set RotationAngle to %.2f\n",
|
|
|
|
|
driver_data->options.rotation_angle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
LibinputApplyConfig(DeviceIntPtr dev)
|
|
|
|
|
{
|
|
|
|
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
|
|
|
struct xf86libinput *driver_data = pInfo->private;
|
|
|
|
|
struct libinput_device *device = driver_data->shared_device->device;
|
|
|
|
|
|
|
|
|
|
LibinputApplyConfigSendEvents(dev, driver_data, device);
|
|
|
|
|
LibinputApplyConfigNaturalScroll(dev, driver_data, device);
|
|
|
|
|
LibinputApplyConfigAccel(dev, driver_data, device);
|
|
|
|
|
LibinputApplyConfigTap(dev, driver_data, device);
|
|
|
|
|
LibinputApplyConfigCalibration(dev, driver_data, device);
|
|
|
|
|
LibinputApplyConfigLeftHanded(dev, driver_data, device);
|
|
|
|
|
LibinputApplyConfigScrollMethod(dev, driver_data, device);
|
|
|
|
|
LibinputApplyConfigClickMethod(dev, driver_data, device);
|
|
|
|
|
LibinputApplyConfigMiddleEmulation(dev, driver_data, device);
|
|
|
|
|
LibinputApplyConfigDisableWhileTyping(dev, driver_data, device);
|
|
|
|
|
LibinputApplyConfigRotation(dev, driver_data, device);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
@@ -1213,7 +1366,7 @@ is_libinput_device(InputInfoPtr pInfo)
|
|
|
|
|
BOOL rc;
|
|
|
|
|
|
|
|
|
|
driver = xf86CheckStrOption(pInfo->options, "driver", "");
|
|
|
|
|
rc = strcmp(driver, "libinput") == 0;
|
|
|
|
|
rc = streq(driver, "libinput");
|
|
|
|
|
free(driver);
|
|
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
|
@@ -1713,12 +1866,15 @@ static enum event_handling
|
|
|
|
|
xf86libinput_handle_tablet_tip(InputInfoPtr pInfo,
|
|
|
|
|
struct libinput_event_tablet_tool *event)
|
|
|
|
|
{
|
|
|
|
|
DeviceIntPtr pDev = pInfo->dev;
|
|
|
|
|
enum libinput_tablet_tool_tip_state state;
|
|
|
|
|
const BOOL is_absolute = TRUE;
|
|
|
|
|
|
|
|
|
|
if (xf86libinput_tool_queue_event(event))
|
|
|
|
|
return EVENT_QUEUED;
|
|
|
|
|
|
|
|
|
|
xf86libinput_post_tablet_motion(pDev->public.devicePrivate, event);
|
|
|
|
|
|
|
|
|
|
state = libinput_event_tablet_tool_get_tip_state(event);
|
|
|
|
|
|
|
|
|
|
xf86PostButtonEventP(pInfo->dev,
|
|
|
|
|
@@ -1773,8 +1929,8 @@ xf86libinput_apply_area(InputInfoPtr pInfo, double *x, double *y)
|
|
|
|
|
*y = sy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static enum event_handling
|
|
|
|
|
xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
|
|
|
|
|
static void
|
|
|
|
|
xf86libinput_post_tablet_motion(InputInfoPtr pInfo,
|
|
|
|
|
struct libinput_event_tablet_tool *event)
|
|
|
|
|
{
|
|
|
|
|
DeviceIntPtr dev = pInfo->dev;
|
|
|
|
|
@@ -1784,9 +1940,6 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
|
|
|
|
|
double value;
|
|
|
|
|
double x, y;
|
|
|
|
|
|
|
|
|
|
if (xf86libinput_tool_queue_event(event))
|
|
|
|
|
return EVENT_QUEUED;
|
|
|
|
|
|
|
|
|
|
x = libinput_event_tablet_tool_get_x_transformed(event,
|
|
|
|
|
TABLET_AXIS_MAX);
|
|
|
|
|
y = libinput_event_tablet_tool_get_y_transformed(event,
|
|
|
|
|
@@ -1836,13 +1989,23 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
|
|
|
|
|
default:
|
|
|
|
|
xf86IDrvMsg(pInfo, X_ERROR,
|
|
|
|
|
"Invalid rotation axis on tool\n");
|
|
|
|
|
return EVENT_HANDLED;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
valuator_mask_set_double(mask, valuator, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xf86PostMotionEventM(dev, Absolute, mask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static enum event_handling
|
|
|
|
|
xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
|
|
|
|
|
struct libinput_event_tablet_tool *event)
|
|
|
|
|
{
|
|
|
|
|
if (xf86libinput_tool_queue_event(event))
|
|
|
|
|
return EVENT_QUEUED;
|
|
|
|
|
|
|
|
|
|
xf86libinput_post_tablet_motion(pInfo, event);
|
|
|
|
|
|
|
|
|
|
return EVENT_HANDLED;
|
|
|
|
|
}
|
|
|
|
|
@@ -1974,6 +2137,13 @@ xf86libinput_handle_tablet_proximity(InputInfoPtr pInfo,
|
|
|
|
|
|
|
|
|
|
xf86PostProximityEventM(pDev, in_prox, mask);
|
|
|
|
|
|
|
|
|
|
/* We have to send an extra motion event after proximity to make
|
|
|
|
|
* sure the client got the updated x/y coordinates, especially if
|
|
|
|
|
* they don't handle proximity events (XI2).
|
|
|
|
|
*/
|
|
|
|
|
if (in_prox)
|
|
|
|
|
xf86libinput_post_tablet_motion(pDev->public.devicePrivate, event);
|
|
|
|
|
|
|
|
|
|
return EVENT_HANDLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2184,10 +2354,16 @@ open_restricted(const char *path, int flags, void *data)
|
|
|
|
|
InputInfoPtr pInfo;
|
|
|
|
|
int fd = -1;
|
|
|
|
|
|
|
|
|
|
/* Special handling for sysfs files (used for pad LEDs) */
|
|
|
|
|
if (strneq(path, "/sys/", 5)) {
|
|
|
|
|
fd = open(path, flags);
|
|
|
|
|
return fd < 0 ? -errno : fd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nt_list_for_each_entry(pInfo, xf86FirstLocalDevice(), next) {
|
|
|
|
|
char *device = xf86CheckStrOption(pInfo->options, "Device", NULL);
|
|
|
|
|
|
|
|
|
|
if (device != NULL && strcmp(path, device) == 0) {
|
|
|
|
|
if (device != NULL && streq(path, device)) {
|
|
|
|
|
free(device);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -2353,9 +2529,9 @@ xf86libinput_parse_tap_buttonmap_option(InputInfoPtr pInfo,
|
|
|
|
|
"TappingButtonMap",
|
|
|
|
|
NULL);
|
|
|
|
|
if (str) {
|
|
|
|
|
if (strcmp(str, "lmr") == 0)
|
|
|
|
|
if (streq(str, "lmr"))
|
|
|
|
|
map = LIBINPUT_CONFIG_TAP_MAP_LMR;
|
|
|
|
|
else if (strcmp(str, "lrm") == 0)
|
|
|
|
|
else if (streq(str, "lrm"))
|
|
|
|
|
map = LIBINPUT_CONFIG_TAP_MAP_LRM;
|
|
|
|
|
else
|
|
|
|
|
xf86IDrvMsg(pInfo, X_ERROR,
|
|
|
|
|
@@ -2468,11 +2644,11 @@ xf86libinput_parse_sendevents_option(InputInfoPtr pInfo,
|
|
|
|
|
"SendEventsMode",
|
|
|
|
|
NULL);
|
|
|
|
|
if (modestr) {
|
|
|
|
|
if (strcmp(modestr, "enabled") == 0)
|
|
|
|
|
if (streq(modestr, "enabled"))
|
|
|
|
|
mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
|
|
|
|
else if (strcmp(modestr, "disabled") == 0)
|
|
|
|
|
else if (streq(modestr, "disabled"))
|
|
|
|
|
mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
|
|
|
|
|
else if (strcmp(modestr, "disabled-on-external-mouse") == 0)
|
|
|
|
|
else if (streq(modestr, "disabled-on-external-mouse"))
|
|
|
|
|
mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
|
|
|
|
|
else
|
|
|
|
|
xf86IDrvMsg(pInfo, X_ERROR,
|
|
|
|
|
@@ -2866,7 +3042,7 @@ xf86libinput_parse_tablet_area_option(InputInfoPtr pInfo,
|
|
|
|
|
str = xf86SetStrOption(pInfo->options,
|
|
|
|
|
"TabletToolAreaRatio",
|
|
|
|
|
NULL);
|
|
|
|
|
if (!str || strcmp(str, "default") == 0)
|
|
|
|
|
if (!str || streq(str, "default"))
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
rc = sscanf(str, "%d:%d", &area.x, &area.y);
|
|
|
|
|
@@ -3386,17 +3562,43 @@ static Atom prop_float;
|
|
|
|
|
static Atom prop_device;
|
|
|
|
|
static Atom prop_product_id;
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
update_mode_prop(InputInfoPtr pInfo,
|
|
|
|
|
struct libinput_event_tablet_pad *event)
|
|
|
|
|
{
|
|
|
|
|
struct xf86libinput *driver_data = pInfo->private;
|
|
|
|
|
struct mode_prop_state {
|
|
|
|
|
int deviceid;
|
|
|
|
|
InputInfoPtr pInfo;
|
|
|
|
|
|
|
|
|
|
struct libinput_tablet_pad_mode_group *group;
|
|
|
|
|
unsigned int mode;
|
|
|
|
|
unsigned int idx;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
|
update_mode_prop_cb(ClientPtr client, pointer closure)
|
|
|
|
|
{
|
|
|
|
|
struct mode_prop_state *state = closure;
|
|
|
|
|
InputInfoPtr pInfo = state->pInfo, tmp;
|
|
|
|
|
struct xf86libinput *driver_data = pInfo->private;
|
|
|
|
|
BOOL found = FALSE;
|
|
|
|
|
XIPropertyValuePtr val;
|
|
|
|
|
int rc;
|
|
|
|
|
unsigned char groups[4] = {0};
|
|
|
|
|
struct libinput_tablet_pad_mode_group *group = state->group;
|
|
|
|
|
unsigned int mode = state->mode;
|
|
|
|
|
unsigned int idx = state->idx;
|
|
|
|
|
|
|
|
|
|
if (idx >= ARRAY_SIZE(groups))
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
/* The device may have gotten removed before the WorkProc was
|
|
|
|
|
* scheduled. X reuses deviceids, but if the pointer value and
|
|
|
|
|
* device ID are what we had before, we're good */
|
|
|
|
|
nt_list_for_each_entry(tmp, xf86FirstLocalDevice(), next) {
|
|
|
|
|
if (tmp->dev->id == state->deviceid && tmp == pInfo) {
|
|
|
|
|
found = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!found)
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
rc = XIGetDeviceProperty(pInfo->dev,
|
|
|
|
|
prop_mode_groups,
|
|
|
|
|
@@ -3404,18 +3606,12 @@ update_mode_prop(InputInfoPtr pInfo,
|
|
|
|
|
if (rc != Success ||
|
|
|
|
|
val->format != 8 ||
|
|
|
|
|
val->size <= 0)
|
|
|
|
|
return;
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
memcpy(groups, (unsigned char*)val->data, val->size);
|
|
|
|
|
|
|
|
|
|
group = libinput_event_tablet_pad_get_mode_group(event);
|
|
|
|
|
mode = libinput_event_tablet_pad_get_mode(event);
|
|
|
|
|
idx = libinput_tablet_pad_mode_group_get_index(group);
|
|
|
|
|
if (idx >= ARRAY_SIZE(groups))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (groups[idx] == mode)
|
|
|
|
|
return;
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
groups[idx] = mode;
|
|
|
|
|
|
|
|
|
|
@@ -3428,8 +3624,36 @@ update_mode_prop(InputInfoPtr pInfo,
|
|
|
|
|
groups,
|
|
|
|
|
TRUE);
|
|
|
|
|
driver_data->allow_mode_group_updates = false;
|
|
|
|
|
if (rc != Success)
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
libinput_tablet_pad_mode_group_unref(group);
|
|
|
|
|
free(state);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
update_mode_prop(InputInfoPtr pInfo,
|
|
|
|
|
struct libinput_event_tablet_pad *event)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_tablet_pad_mode_group *group;
|
|
|
|
|
struct mode_prop_state *state;
|
|
|
|
|
|
|
|
|
|
state = calloc(1, sizeof(*state));
|
|
|
|
|
if (!state)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
state->deviceid = pInfo->dev->id;
|
|
|
|
|
state->pInfo = pInfo;
|
|
|
|
|
|
|
|
|
|
group = libinput_event_tablet_pad_get_mode_group(event);
|
|
|
|
|
|
|
|
|
|
state->group = libinput_tablet_pad_mode_group_ref(group);
|
|
|
|
|
state->mode = libinput_event_tablet_pad_get_mode(event);
|
|
|
|
|
state->idx = libinput_tablet_pad_mode_group_get_index(group);
|
|
|
|
|
|
|
|
|
|
/* Schedule a WorkProc so we don't update from within the input
|
|
|
|
|
thread */
|
|
|
|
|
QueueWorkProc(update_mode_prop_cb, serverClient, state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline BOOL
|
|
|
|
|
@@ -4351,6 +4575,9 @@ LibinputInitTapProperty(DeviceIntPtr dev,
|
|
|
|
|
{
|
|
|
|
|
BOOL tap = driver_data->options.tapping;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_tap_get_finger_count(device) == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -4377,6 +4604,9 @@ LibinputInitTapDragProperty(DeviceIntPtr dev,
|
|
|
|
|
{
|
|
|
|
|
BOOL drag = driver_data->options.tap_drag;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_tap_get_finger_count(device) == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -4401,6 +4631,9 @@ LibinputInitTapDragLockProperty(DeviceIntPtr dev,
|
|
|
|
|
{
|
|
|
|
|
BOOL drag_lock = driver_data->options.tap_drag_lock;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_tap_get_finger_count(device) == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -4426,6 +4659,9 @@ LibinputInitTapButtonmapProperty(DeviceIntPtr dev,
|
|
|
|
|
enum libinput_config_tap_button_map map;
|
|
|
|
|
BOOL data[2] = {0};
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
map = driver_data->options.tap_button_map;
|
|
|
|
|
|
|
|
|
|
if (libinput_device_config_tap_get_finger_count(device) == 0)
|
|
|
|
|
@@ -4476,6 +4712,9 @@ LibinputInitCalibrationProperty(DeviceIntPtr dev,
|
|
|
|
|
{
|
|
|
|
|
float calibration[9];
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER|CAP_TOUCH|CAP_TABLET))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!libinput_device_config_calibration_has_matrix(device))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -4513,6 +4752,9 @@ LibinputInitAccelProperty(DeviceIntPtr dev,
|
|
|
|
|
enum libinput_config_accel_profile profile;
|
|
|
|
|
BOOL profiles[2] = {FALSE};
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!libinput_device_config_accel_is_available(device) ||
|
|
|
|
|
driver_data->capabilities & CAP_TABLET)
|
|
|
|
|
return;
|
|
|
|
|
@@ -4600,6 +4842,9 @@ LibinputInitNaturalScrollProperty(DeviceIntPtr dev,
|
|
|
|
|
{
|
|
|
|
|
BOOL natural_scroll = driver_data->options.natural_scrolling;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!libinput_device_config_scroll_has_natural_scroll(device))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -4682,6 +4927,9 @@ LibinputInitLeftHandedProperty(DeviceIntPtr dev,
|
|
|
|
|
{
|
|
|
|
|
BOOL left_handed = driver_data->options.left_handed;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER|CAP_TABLET))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!libinput_device_config_left_handed_is_available(device) ||
|
|
|
|
|
driver_data->capabilities & CAP_TABLET)
|
|
|
|
|
return;
|
|
|
|
|
@@ -4709,6 +4957,9 @@ LibinputInitScrollMethodsProperty(DeviceIntPtr dev,
|
|
|
|
|
enum libinput_config_scroll_method method;
|
|
|
|
|
BOOL methods[3] = {FALSE};
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
scroll_methods = libinput_device_config_scroll_get_methods(device);
|
|
|
|
|
if (scroll_methods == LIBINPUT_CONFIG_SCROLL_NO_SCROLL)
|
|
|
|
|
return;
|
|
|
|
|
@@ -4796,6 +5047,9 @@ LibinputInitClickMethodsProperty(DeviceIntPtr dev,
|
|
|
|
|
enum libinput_config_click_method method;
|
|
|
|
|
BOOL methods[2] = {FALSE};
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
click_methods = libinput_device_config_click_get_methods(device);
|
|
|
|
|
if (click_methods == LIBINPUT_CONFIG_CLICK_METHOD_NONE)
|
|
|
|
|
return;
|
|
|
|
|
@@ -4864,6 +5118,9 @@ LibinputInitMiddleEmulationProperty(DeviceIntPtr dev,
|
|
|
|
|
{
|
|
|
|
|
BOOL middle = driver_data->options.middle_emulation;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!libinput_device_config_middle_emulation_is_available(device))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -4890,6 +5147,9 @@ LibinputInitDisableWhileTypingProperty(DeviceIntPtr dev,
|
|
|
|
|
{
|
|
|
|
|
BOOL dwt = driver_data->options.disable_while_typing;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_POINTER))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!libinput_device_config_dwt_is_available(device))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -4922,6 +5182,9 @@ LibinputInitModeGroupProperties(DeviceIntPtr dev,
|
|
|
|
|
associations[MAX_BUTTONS] = {0};
|
|
|
|
|
int g, b, r, s;
|
|
|
|
|
|
|
|
|
|
if (!subdevice_has_capabilities(dev, CAP_TABLET_PAD))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_PAD))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -5176,17 +5439,17 @@ LibinputInitProperty(DeviceIntPtr dev)
|
|
|
|
|
LibinputInitTapDragProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitTapDragLockProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitTapButtonmapProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitCalibrationProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitAccelProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitNaturalScrollProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitSendEventsProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitLeftHandedProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitDisableWhileTypingProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitScrollMethodsProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitClickMethodsProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitMiddleEmulationProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitDisableWhileTypingProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitModeGroupProperties(dev, driver_data, device);
|
|
|
|
|
LibinputInitRotationAngleProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitAccelProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitCalibrationProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitLeftHandedProperty(dev, driver_data, device);
|
|
|
|
|
LibinputInitModeGroupProperties(dev, driver_data, device);
|
|
|
|
|
LibinputInitSendEventsProperty(dev, driver_data, device);
|
|
|
|
|
|
|
|
|
|
/* Device node property, read-only */
|
|
|
|
|
device_node = driver_data->path;
|
|
|
|
|
|