mirror of
https://github.com/X11Libre/xf86-input-libinput.git
synced 2026-03-24 17:44:05 +00:00
Compare commits
15 Commits
xf86-input
...
xf86-input
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
efb5cacb25 | ||
|
|
2348a6812a | ||
|
|
0c4eaf5480 | ||
|
|
bc7bcca342 | ||
|
|
e5079cd98e | ||
|
|
200be95ac9 | ||
|
|
8b5dbd4c01 | ||
|
|
fb5c5b6f85 | ||
|
|
182363d674 | ||
|
|
f0b14c6ccc | ||
|
|
e92c9f0bad | ||
|
|
dda952fafe | ||
|
|
17302c3352 | ||
|
|
7e3926f2b7 | ||
|
|
9ad23dd1cb |
@@ -23,7 +23,7 @@
|
||||
# Initialize Autoconf
|
||||
AC_PREREQ([2.60])
|
||||
AC_INIT([xf86-input-libinput],
|
||||
[0.3.0],
|
||||
[0.5.0],
|
||||
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
|
||||
[xf86-input-libinput])
|
||||
AC_CONFIG_SRCDIR([Makefile.am])
|
||||
@@ -45,7 +45,7 @@ XORG_DEFAULT_OPTIONS
|
||||
|
||||
# Obtain compiler/linker options from server and required extensions
|
||||
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.10] xproto [inputproto >= 2.2])
|
||||
PKG_CHECK_MODULES(LIBINPUT, [libinput >= 0.6.0])
|
||||
PKG_CHECK_MODULES(LIBINPUT, [libinput >= 0.8.0])
|
||||
|
||||
# Define a configure option for an alternate input module directory
|
||||
AC_ARG_WITH(xorg-module-dir,
|
||||
|
||||
@@ -48,7 +48,7 @@ The mapping from device node to hardware is system-dependent. Property:
|
||||
.BI "Option \*qAccelSpeed\*q \*q" float \*q
|
||||
Sets the pointer acceleration speed within the range [-1, 1]
|
||||
.TP 7
|
||||
.BI "Option \*qCalibration\*q \*q" string \*q
|
||||
.BI "Option \*qCalibrationMatrix\*q \*q" string \*q
|
||||
A string of 9 space-separated floating point numbers.
|
||||
Sets the calibration matrix to the 3x3 matrix where the first row is (abc),
|
||||
the second row is (def) and the third row is (ghi).
|
||||
|
||||
582
src/libinput.c
582
src/libinput.c
@@ -31,6 +31,7 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <xorg-server.h>
|
||||
#include <list.h>
|
||||
#include <exevents.h>
|
||||
#include <xkbsrv.h>
|
||||
#include <xf86Xinput.h>
|
||||
@@ -40,6 +41,10 @@
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#ifndef XI86_SERVER_FD
|
||||
#define XI86_SERVER_FD 0x20
|
||||
#endif
|
||||
|
||||
#define TOUCHPAD_NUM_AXES 4 /* x, y, hscroll, vscroll */
|
||||
#define TOUCH_MAX_SLOTS 15
|
||||
#define XORG_KEYCODE_OFFSET 8
|
||||
@@ -54,13 +59,14 @@
|
||||
|
||||
/*
|
||||
libinput scales wheel events by DEFAULT_AXIS_STEP_DISTANCE, which is
|
||||
currently 10.
|
||||
currently 15.
|
||||
*/
|
||||
#define DEFAULT_LIBINPUT_AXIS_STEP_DISTANCE 10
|
||||
#define DEFAULT_LIBINPUT_AXIS_STEP_DISTANCE 15
|
||||
|
||||
struct xf86libinput_driver {
|
||||
struct libinput *libinput;
|
||||
int device_enabled_count;
|
||||
struct xorg_list server_fds;
|
||||
};
|
||||
|
||||
static struct xf86libinput_driver driver_context;
|
||||
@@ -95,6 +101,80 @@ struct xf86libinput {
|
||||
} options;
|
||||
};
|
||||
|
||||
/*
|
||||
libinput provides a userdata for the context, but not per path device. so
|
||||
the open_restricted call has the libinput context, but no reference to
|
||||
the pInfo->fd that we actually need to return.
|
||||
To avoid this, we store each path/fd combination during pre_init in the
|
||||
context, then return that during open_restricted. If a device is added
|
||||
twice with two different fds this may give us the wrong fd but why are
|
||||
you doing that anyway.
|
||||
*/
|
||||
struct serverfd {
|
||||
struct xorg_list node;
|
||||
int fd;
|
||||
char *path;
|
||||
};
|
||||
|
||||
static inline int
|
||||
use_server_fd(const InputInfoPtr pInfo) {
|
||||
return pInfo->fd > -1 && (pInfo->flags & XI86_SERVER_FD);
|
||||
}
|
||||
|
||||
static inline void
|
||||
fd_push(struct xf86libinput_driver *context,
|
||||
int fd,
|
||||
const char *path)
|
||||
{
|
||||
struct serverfd *sfd = xnfcalloc(1, sizeof(*sfd));
|
||||
|
||||
sfd->fd = fd;
|
||||
sfd->path = xnfstrdup(path);
|
||||
xorg_list_add(&sfd->node, &context->server_fds);
|
||||
}
|
||||
|
||||
static inline int
|
||||
fd_get(struct xf86libinput_driver *context,
|
||||
const char *path)
|
||||
{
|
||||
struct serverfd *sfd;
|
||||
|
||||
xorg_list_for_each_entry(sfd, &context->server_fds, node) {
|
||||
if (strcmp(path, sfd->path) == 0)
|
||||
return sfd->fd;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
fd_pop(struct xf86libinput_driver *context, int fd)
|
||||
{
|
||||
struct serverfd *sfd;
|
||||
|
||||
xorg_list_for_each_entry(sfd, &context->server_fds, node) {
|
||||
if (fd != sfd->fd)
|
||||
continue;
|
||||
|
||||
xorg_list_del(&sfd->node);
|
||||
free(sfd->path);
|
||||
free(sfd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
fd_find(struct xf86libinput_driver *context, int fd)
|
||||
{
|
||||
struct serverfd *sfd;
|
||||
|
||||
xorg_list_for_each_entry(sfd, &context->server_fds, node) {
|
||||
if (fd == sfd->fd)
|
||||
return fd;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
btn_linux2xorg(unsigned int b)
|
||||
{
|
||||
@@ -142,6 +222,7 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
struct libinput_device *device = driver_data->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,
|
||||
@@ -182,8 +263,8 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
||||
driver_data->options.matrix[6], driver_data->options.matrix[7],
|
||||
driver_data->options.matrix[8]);
|
||||
|
||||
if (libinput_device_config_buttons_set_left_handed(device,
|
||||
driver_data->options.left_handed) != LIBINPUT_CONFIG_STATUS_SUCCESS)
|
||||
if (libinput_device_config_left_handed_set(device,
|
||||
driver_data->options.left_handed) != LIBINPUT_CONFIG_STATUS_SUCCESS)
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Failed to set LeftHanded to %d\n",
|
||||
driver_data->options.left_handed);
|
||||
@@ -206,8 +287,8 @@ LibinputApplyConfig(DeviceIntPtr dev)
|
||||
method);
|
||||
}
|
||||
|
||||
if (libinput_device_config_scroll_set_button(device,
|
||||
btn_xorg2linux(driver_data->options.scroll_button)) != LIBINPUT_CONFIG_STATUS_SUCCESS)
|
||||
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 %d\n",
|
||||
driver_data->options.scroll_button);
|
||||
@@ -221,13 +302,24 @@ xf86libinput_on(DeviceIntPtr dev)
|
||||
struct libinput *libinput = driver_context.libinput;
|
||||
struct libinput_device *device = driver_data->device;
|
||||
|
||||
if (use_server_fd(pInfo)) {
|
||||
char *path = xf86SetStrOption(pInfo->options, "Device", NULL);
|
||||
fd_push(&driver_context, pInfo->fd, path);
|
||||
free(path);
|
||||
}
|
||||
|
||||
device = libinput_path_add_device(libinput, driver_data->path);
|
||||
if (!device)
|
||||
return !Success;
|
||||
|
||||
libinput_device_ref(device);
|
||||
libinput_device_set_user_data(device, pInfo);
|
||||
driver_data->device = device;
|
||||
|
||||
/* if we use server fds, overwrite the fd with the one from
|
||||
libinput nonetheless, otherwise the server won't call ReadInput
|
||||
for our device. This must be swapped back to the real fd in
|
||||
DEVICE_OFF so systemd-logind closes the right fd */
|
||||
pInfo->fd = libinput_get_fd(libinput);
|
||||
|
||||
if (driver_context.device_enabled_count == 0) {
|
||||
@@ -251,7 +343,13 @@ xf86libinput_off(DeviceIntPtr dev)
|
||||
RemoveEnabledDevice(pInfo->fd);
|
||||
}
|
||||
|
||||
pInfo->fd = -1;
|
||||
if (use_server_fd(pInfo)) {
|
||||
fd_pop(&driver_context, pInfo->fd);
|
||||
pInfo->fd = xf86SetIntOption(pInfo->options, "fd", -1);
|
||||
} else {
|
||||
pInfo->fd = -1;
|
||||
}
|
||||
|
||||
dev->public.on = FALSE;
|
||||
|
||||
libinput_device_set_user_data(driver_data->device, NULL);
|
||||
@@ -354,6 +452,53 @@ xf86libinput_init_pointer(InputInfoPtr pInfo)
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
xf86libinput_init_pointer_absolute(InputInfoPtr pInfo)
|
||||
{
|
||||
DeviceIntPtr dev= pInfo->dev;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
int min, max, res;
|
||||
int nbuttons = 7;
|
||||
int i;
|
||||
|
||||
unsigned char btnmap[MAX_BUTTONS + 1];
|
||||
Atom btnlabels[MAX_BUTTONS];
|
||||
Atom axislabels[TOUCHPAD_NUM_AXES];
|
||||
|
||||
for (i = BTN_BACK; i >= BTN_SIDE; i--) {
|
||||
if (libinput_device_has_button(driver_data->device, i)) {
|
||||
nbuttons += i - BTN_SIDE + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
init_button_map(btnmap, ARRAY_SIZE(btnmap));
|
||||
init_button_labels(btnlabels, ARRAY_SIZE(btnlabels));
|
||||
init_axis_labels(axislabels, ARRAY_SIZE(axislabels));
|
||||
|
||||
InitPointerDeviceStruct((DevicePtr)dev, btnmap,
|
||||
nbuttons,
|
||||
btnlabels,
|
||||
xf86libinput_ptr_ctl,
|
||||
GetMotionHistorySize(),
|
||||
TOUCHPAD_NUM_AXES,
|
||||
axislabels);
|
||||
min = 0;
|
||||
max = TOUCH_AXIS_MAX;
|
||||
res = 0;
|
||||
|
||||
xf86InitValuatorAxisStruct(dev, 0,
|
||||
XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X),
|
||||
min, max, res * 1000, 0, res * 1000, Absolute);
|
||||
xf86InitValuatorAxisStruct(dev, 1,
|
||||
XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y),
|
||||
min, max, res * 1000, 0, res * 1000, Absolute);
|
||||
|
||||
SetScrollValuator(dev, 2, SCROLL_TYPE_HORIZONTAL, driver_data->scroll_hdist, 0);
|
||||
SetScrollValuator(dev, 3, SCROLL_TYPE_VERTICAL, driver_data->scroll_vdist, 0);
|
||||
|
||||
return Success;
|
||||
}
|
||||
static void
|
||||
xf86libinput_kbd_ctrl(DeviceIntPtr device, KeybdCtrl *ctrl)
|
||||
{
|
||||
@@ -387,16 +532,30 @@ xf86libinput_init_keyboard(InputInfoPtr pInfo)
|
||||
{
|
||||
DeviceIntPtr dev= pInfo->dev;
|
||||
XkbRMLVOSet rmlvo = {0};
|
||||
XkbRMLVOSet defaults = {0};
|
||||
|
||||
rmlvo.rules = xf86SetStrOption(pInfo->options, "xkb_rules", "evdev");
|
||||
rmlvo.model = xf86SetStrOption(pInfo->options, "xkb_model", "pc104");
|
||||
rmlvo.layout = xf86SetStrOption(pInfo->options, "xkb_layout", "us");
|
||||
rmlvo.variant = xf86SetStrOption(pInfo->options, "xkb_variant", NULL);
|
||||
rmlvo.options = xf86SetStrOption(pInfo->options, "xkb_options", NULL);
|
||||
XkbGetRulesDflts(&defaults);
|
||||
|
||||
rmlvo.rules = xf86SetStrOption(pInfo->options,
|
||||
"xkb_rules",
|
||||
defaults.rules);
|
||||
rmlvo.model = xf86SetStrOption(pInfo->options,
|
||||
"xkb_model",
|
||||
defaults.model);
|
||||
rmlvo.layout = xf86SetStrOption(pInfo->options,
|
||||
"xkb_layout",
|
||||
defaults.layout);
|
||||
rmlvo.variant = xf86SetStrOption(pInfo->options,
|
||||
"xkb_variant",
|
||||
defaults.variant);
|
||||
rmlvo.options = xf86SetStrOption(pInfo->options,
|
||||
"xkb_options",
|
||||
defaults.options);
|
||||
|
||||
InitKeyboardDeviceStruct(dev, &rmlvo, NULL,
|
||||
xf86libinput_kbd_ctrl);
|
||||
XkbFreeRMLVOSet(&rmlvo, FALSE);
|
||||
XkbFreeRMLVOSet(&defaults, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -445,8 +604,12 @@ xf86libinput_init(DeviceIntPtr dev)
|
||||
|
||||
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD))
|
||||
xf86libinput_init_keyboard(pInfo);
|
||||
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER))
|
||||
xf86libinput_init_pointer(pInfo);
|
||||
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER)) {
|
||||
if (libinput_device_config_calibration_has_matrix(device))
|
||||
xf86libinput_init_pointer_absolute(pInfo);
|
||||
else
|
||||
xf86libinput_init_pointer(pInfo);
|
||||
}
|
||||
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH))
|
||||
xf86libinput_init_touch(pInfo);
|
||||
|
||||
@@ -506,6 +669,24 @@ xf86libinput_handle_motion(InputInfoPtr pInfo, struct libinput_event_pointer *ev
|
||||
xf86PostMotionEventM(dev, Relative, mask);
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_handle_absmotion(InputInfoPtr pInfo, struct libinput_event_pointer *event)
|
||||
{
|
||||
DeviceIntPtr dev = pInfo->dev;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
ValuatorMask *mask = driver_data->valuators;
|
||||
double x, y;
|
||||
|
||||
x = libinput_event_pointer_get_absolute_x_transformed(event, TOUCH_AXIS_MAX);
|
||||
y = libinput_event_pointer_get_absolute_y_transformed(event, TOUCH_AXIS_MAX);
|
||||
|
||||
valuator_mask_zero(mask);
|
||||
valuator_mask_set_double(mask, 0, x);
|
||||
valuator_mask_set_double(mask, 1, y);
|
||||
|
||||
xf86PostMotionEventM(dev, Absolute, mask);
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_handle_button(InputInfoPtr pInfo, struct libinput_event_pointer *event)
|
||||
{
|
||||
@@ -537,19 +718,38 @@ xf86libinput_handle_axis(InputInfoPtr pInfo, struct libinput_event_pointer *even
|
||||
DeviceIntPtr dev = pInfo->dev;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
ValuatorMask *mask = driver_data->valuators;
|
||||
int axis;
|
||||
double value;
|
||||
|
||||
if (libinput_event_pointer_get_axis(event) ==
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)
|
||||
axis = 3;
|
||||
else
|
||||
axis = 2;
|
||||
|
||||
value = libinput_event_pointer_get_axis_value(event) / DEFAULT_LIBINPUT_AXIS_STEP_DISTANCE;
|
||||
enum libinput_pointer_axis axis;
|
||||
enum libinput_pointer_axis_source source;
|
||||
|
||||
valuator_mask_zero(mask);
|
||||
valuator_mask_set_double(mask, axis, value);
|
||||
|
||||
source = libinput_event_pointer_get_axis_source(event);
|
||||
switch(source) {
|
||||
case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
|
||||
case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
|
||||
case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
|
||||
if (libinput_event_pointer_has_axis(event, axis)) {
|
||||
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL)
|
||||
value = libinput_event_pointer_get_axis_value_discrete(event, axis);
|
||||
else
|
||||
value = libinput_event_pointer_get_axis_value(event, axis);
|
||||
valuator_mask_set_double(mask, 3, value);
|
||||
}
|
||||
axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
|
||||
if (libinput_event_pointer_has_axis(event, axis)) {
|
||||
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL)
|
||||
value = libinput_event_pointer_get_axis_value_discrete(event, axis);
|
||||
else
|
||||
value = libinput_event_pointer_get_axis_value(event, axis);
|
||||
valuator_mask_set_double(mask, 2, value);
|
||||
}
|
||||
|
||||
xf86PostMotionEventM(dev, Relative, mask);
|
||||
}
|
||||
@@ -568,8 +768,8 @@ xf86libinput_handle_touch(InputInfoPtr pInfo,
|
||||
|
||||
/* libinput doesn't give us hw touch ids which X expects, so
|
||||
emulate them here */
|
||||
static int next_touchid;
|
||||
static int touchids[TOUCH_MAX_SLOTS] = {0};
|
||||
static unsigned int next_touchid;
|
||||
static unsigned int touchids[TOUCH_MAX_SLOTS] = {0};
|
||||
|
||||
slot = libinput_event_touch_get_slot(event);
|
||||
|
||||
@@ -619,7 +819,8 @@ xf86libinput_handle_event(struct libinput_event *event)
|
||||
case LIBINPUT_EVENT_DEVICE_REMOVED:
|
||||
break;
|
||||
case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
|
||||
/* FIXME */
|
||||
xf86libinput_handle_absmotion(pInfo,
|
||||
libinput_event_get_pointer_event(event));
|
||||
break;
|
||||
|
||||
case LIBINPUT_EVENT_POINTER_MOTION:
|
||||
@@ -663,7 +864,9 @@ xf86libinput_read_input(InputInfoPtr pInfo)
|
||||
return;
|
||||
|
||||
if (rc < 0) {
|
||||
ErrorFSigSafe("Error reading events: %d\n", -rc);
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Error reading events: %s\n",
|
||||
strerror(-rc));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -676,14 +879,22 @@ xf86libinput_read_input(InputInfoPtr pInfo)
|
||||
static int
|
||||
open_restricted(const char *path, int flags, void *data)
|
||||
{
|
||||
int fd = open(path, flags);
|
||||
struct xf86libinput_driver *context = data;
|
||||
int fd;
|
||||
|
||||
fd = fd_get(context, path);
|
||||
if (fd == -1)
|
||||
fd = open(path, flags);
|
||||
return fd < 0 ? -errno : fd;
|
||||
}
|
||||
|
||||
static void
|
||||
close_restricted(int fd, void *data)
|
||||
{
|
||||
close(fd);
|
||||
struct xf86libinput_driver *context = data;
|
||||
|
||||
if (fd_find(context, fd) == -1)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
const struct libinput_interface interface = {
|
||||
@@ -730,77 +941,13 @@ xf86libinput_log_handler(struct libinput *libinput,
|
||||
LogVMessageVerb(type, verbosity, format, args);
|
||||
}
|
||||
|
||||
static int xf86libinput_pre_init(InputDriverPtr drv,
|
||||
InputInfoPtr pInfo,
|
||||
int flags)
|
||||
static void
|
||||
xf86libinput_parse_options(InputInfoPtr pInfo,
|
||||
struct xf86libinput *driver_data,
|
||||
struct libinput_device *device)
|
||||
{
|
||||
struct xf86libinput *driver_data = NULL;
|
||||
struct libinput *libinput = NULL;
|
||||
struct libinput_device *device;
|
||||
char *path;
|
||||
uint32_t scroll_methods;
|
||||
|
||||
pInfo->fd = -1;
|
||||
pInfo->type_name = 0;
|
||||
pInfo->device_control = xf86libinput_device_control;
|
||||
pInfo->read_input = xf86libinput_read_input;
|
||||
pInfo->control_proc = NULL;
|
||||
pInfo->switch_mode = NULL;
|
||||
|
||||
driver_data = calloc(1, sizeof(*driver_data));
|
||||
if (!driver_data)
|
||||
goto fail;
|
||||
|
||||
driver_data->valuators = valuator_mask_new(2);
|
||||
if (!driver_data->valuators)
|
||||
goto fail;
|
||||
|
||||
driver_data->scroll_vdist = 1;
|
||||
driver_data->scroll_hdist = 1;
|
||||
|
||||
path = xf86SetStrOption(pInfo->options, "Device", NULL);
|
||||
if (!path)
|
||||
goto fail;
|
||||
|
||||
if (!driver_context.libinput) {
|
||||
driver_context.libinput = libinput_path_create_context(&interface, &driver_context);
|
||||
libinput_log_set_handler(driver_context.libinput,
|
||||
xf86libinput_log_handler);
|
||||
/* we want all msgs, let the server filter */
|
||||
libinput_log_set_priority(driver_context.libinput,
|
||||
LIBINPUT_LOG_PRIORITY_DEBUG);
|
||||
} else {
|
||||
libinput_ref(driver_context.libinput);
|
||||
}
|
||||
|
||||
libinput = driver_context.libinput;
|
||||
|
||||
if (libinput == NULL) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR, "Creating a device for %s failed\n", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
device = libinput_path_add_device(libinput, path);
|
||||
if (!device) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR, "Failed to create a device for %s\n", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* We ref the device but remove it afterwards. The hope is that
|
||||
between now and DEVICE_INIT/DEVICE_ON, the device doesn't change.
|
||||
*/
|
||||
libinput_device_ref(device);
|
||||
libinput_path_remove_device(device);
|
||||
|
||||
pInfo->fd = -1;
|
||||
pInfo->private = driver_data;
|
||||
driver_data->path = path;
|
||||
driver_data->device = device;
|
||||
|
||||
/* Disable acceleration in the server, libinput does it for us */
|
||||
pInfo->options = xf86ReplaceIntOption(pInfo->options, "AccelerationProfile", -1);
|
||||
pInfo->options = xf86ReplaceStrOption(pInfo->options, "AccelerationScheme", "none");
|
||||
|
||||
if (libinput_device_config_tap_get_finger_count(device) > 0) {
|
||||
BOOL tap = xf86SetBoolOption(pInfo->options,
|
||||
"Tapping",
|
||||
@@ -908,17 +1055,17 @@ static int xf86libinput_pre_init(InputDriverPtr drv,
|
||||
}
|
||||
}
|
||||
|
||||
if (libinput_device_config_buttons_has_left_handed(device)) {
|
||||
if (libinput_device_config_left_handed_is_available(device)) {
|
||||
BOOL left_handed = xf86SetBoolOption(pInfo->options,
|
||||
"LeftHanded",
|
||||
libinput_device_config_buttons_get_left_handed(device));
|
||||
if (libinput_device_config_buttons_set_left_handed(device,
|
||||
left_handed) !=
|
||||
libinput_device_config_left_handed_get(device));
|
||||
if (libinput_device_config_left_handed_set(device,
|
||||
left_handed) !=
|
||||
LIBINPUT_CONFIG_STATUS_SUCCESS) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Failed to set LeftHanded to %d\n",
|
||||
left_handed);
|
||||
left_handed = libinput_device_config_buttons_get_left_handed(device);
|
||||
left_handed = libinput_device_config_left_handed_get(device);
|
||||
}
|
||||
driver_data->options.left_handed = left_handed;
|
||||
}
|
||||
@@ -970,6 +1117,84 @@ static int xf86libinput_pre_init(InputDriverPtr drv,
|
||||
driver_data->options.scroll_button = scroll_button;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int xf86libinput_pre_init(InputDriverPtr drv,
|
||||
InputInfoPtr pInfo,
|
||||
int flags)
|
||||
{
|
||||
struct xf86libinput *driver_data = NULL;
|
||||
struct libinput *libinput = NULL;
|
||||
struct libinput_device *device;
|
||||
char *path;
|
||||
|
||||
pInfo->type_name = 0;
|
||||
pInfo->device_control = xf86libinput_device_control;
|
||||
pInfo->read_input = xf86libinput_read_input;
|
||||
pInfo->control_proc = NULL;
|
||||
pInfo->switch_mode = NULL;
|
||||
|
||||
driver_data = calloc(1, sizeof(*driver_data));
|
||||
if (!driver_data)
|
||||
goto fail;
|
||||
|
||||
driver_data->valuators = valuator_mask_new(2);
|
||||
if (!driver_data->valuators)
|
||||
goto fail;
|
||||
|
||||
driver_data->scroll_vdist = 1;
|
||||
driver_data->scroll_hdist = 1;
|
||||
|
||||
path = xf86SetStrOption(pInfo->options, "Device", NULL);
|
||||
if (!path)
|
||||
goto fail;
|
||||
|
||||
if (!driver_context.libinput) {
|
||||
driver_context.libinput = libinput_path_create_context(&interface, &driver_context);
|
||||
libinput_log_set_handler(driver_context.libinput,
|
||||
xf86libinput_log_handler);
|
||||
/* we want all msgs, let the server filter */
|
||||
libinput_log_set_priority(driver_context.libinput,
|
||||
LIBINPUT_LOG_PRIORITY_DEBUG);
|
||||
xorg_list_init(&driver_context.server_fds);
|
||||
} else {
|
||||
libinput_ref(driver_context.libinput);
|
||||
}
|
||||
|
||||
libinput = driver_context.libinput;
|
||||
|
||||
if (libinput == NULL) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR, "Creating a device for %s failed\n", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (use_server_fd(pInfo))
|
||||
fd_push(&driver_context, pInfo->fd, path);
|
||||
|
||||
device = libinput_path_add_device(libinput, path);
|
||||
if (!device) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR, "Failed to create a device for %s\n", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* We ref the device but remove it afterwards. The hope is that
|
||||
between now and DEVICE_INIT/DEVICE_ON, the device doesn't change.
|
||||
*/
|
||||
libinput_device_ref(device);
|
||||
libinput_path_remove_device(device);
|
||||
if (use_server_fd(pInfo))
|
||||
fd_pop(&driver_context, pInfo->fd);
|
||||
|
||||
pInfo->private = driver_data;
|
||||
driver_data->path = path;
|
||||
driver_data->device = device;
|
||||
|
||||
/* Disable acceleration in the server, libinput does it for us */
|
||||
pInfo->options = xf86ReplaceIntOption(pInfo->options, "AccelerationProfile", -1);
|
||||
pInfo->options = xf86ReplaceStrOption(pInfo->options, "AccelerationScheme", "none");
|
||||
|
||||
xf86libinput_parse_options(pInfo, driver_data, device);
|
||||
|
||||
/* now pick an actual type */
|
||||
if (libinput_device_config_tap_get_finger_count(device) > 0)
|
||||
pInfo->type_name = XI_TOUCHPAD;
|
||||
@@ -984,6 +1209,8 @@ static int xf86libinput_pre_init(InputDriverPtr drv,
|
||||
|
||||
return Success;
|
||||
fail:
|
||||
if (use_server_fd(pInfo) && driver_context.libinput != NULL)
|
||||
fd_pop(&driver_context, pInfo->fd);
|
||||
if (driver_data->valuators)
|
||||
valuator_mask_free(&driver_data->valuators);
|
||||
free(path);
|
||||
@@ -1012,6 +1239,11 @@ InputDriverRec xf86libinput_driver = {
|
||||
.driverName = "libinput",
|
||||
.PreInit = xf86libinput_pre_init,
|
||||
.UnInit = xf86libinput_uninit,
|
||||
.module = NULL,
|
||||
.default_options= NULL,
|
||||
#ifdef XI86_DRV_CAP_SERVER_FD
|
||||
.capabilities = XI86_DRV_CAP_SERVER_FD
|
||||
#endif
|
||||
};
|
||||
|
||||
static XF86ModuleVersionInfo xf86libinput_version_info = {
|
||||
@@ -1050,13 +1282,20 @@ _X_EXPORT XF86ModuleData libinputModuleData = {
|
||||
#define PROP_ACCEL "libinput Accel Speed"
|
||||
/* Natural scrolling: BOOL, 1 value */
|
||||
#define PROP_NATURAL_SCROLL "libinput Natural Scrolling Enabled"
|
||||
/* Send-events mode: 32-bit int, 1 value */
|
||||
#define PROP_SENDEVENTS "libinput Send Events Mode"
|
||||
/* Send-events mode: BOOL read-only, 2 values in order disabled,
|
||||
disabled-on-external-mouse */
|
||||
#define PROP_SENDEVENTS_AVAILABLE "libinput Send Events Modes Available"
|
||||
/* Send-events mode: BOOL, 2 values in order disabled,
|
||||
disabled-on-external-mouse */
|
||||
#define PROP_SENDEVENTS_ENABLED "libinput Send Events Mode Enabled"
|
||||
/* Left-handed enabled/disabled: BOOL, 1 value */
|
||||
#define PROP_LEFT_HANDED "libinput Left Handed Enabled"
|
||||
/* Scroll method: BOOL read-only, 3 values in order 2fg, edge, button.
|
||||
shows available scroll methods */
|
||||
#define PROP_SCROLL_METHODS_AVAILABLE "libinput Scroll Methods Available"
|
||||
/* Scroll method: BOOL, 3 values in order 2fg, edge, button
|
||||
only one is enabled at a time at max */
|
||||
#define PROP_SCROLL_METHODS "libinput Scroll Methods"
|
||||
#define PROP_SCROLL_METHOD_ENABLED "libinput Scroll Method Enabled"
|
||||
/* Scroll button for button scrolling: 32-bit int, 1 value */
|
||||
#define PROP_SCROLL_BUTTON "libinput Button Scrolling Button"
|
||||
|
||||
@@ -1065,9 +1304,11 @@ static Atom prop_tap;
|
||||
static Atom prop_calibration;
|
||||
static Atom prop_accel;
|
||||
static Atom prop_natural_scroll;
|
||||
static Atom prop_sendevents;
|
||||
static Atom prop_sendevents_available;
|
||||
static Atom prop_sendevents_enabled;
|
||||
static Atom prop_left_handed;
|
||||
static Atom prop_scroll_methods;
|
||||
static Atom prop_scroll_methods_available;
|
||||
static Atom prop_scroll_method_enabled;
|
||||
static Atom prop_scroll_button;
|
||||
|
||||
/* general properties */
|
||||
@@ -1203,25 +1444,28 @@ LibinputSetPropertySendEvents(DeviceIntPtr dev,
|
||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
struct libinput_device *device = driver_data->device;
|
||||
CARD32* data;
|
||||
BOOL* data;
|
||||
uint32_t modes = 0;
|
||||
|
||||
if (val->format != 32 || val->size != 1 || val->type != XA_CARDINAL)
|
||||
if (val->format != 8 || val->size != 2 || val->type != XA_INTEGER)
|
||||
return BadMatch;
|
||||
|
||||
data = (CARD32*)val->data;
|
||||
data = (BOOL*)val->data;
|
||||
|
||||
if (data[0])
|
||||
modes |= LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
|
||||
if (data[1])
|
||||
modes |= LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
|
||||
|
||||
if (checkonly) {
|
||||
uint32_t supported = libinput_device_config_send_events_get_modes(device);
|
||||
uint32_t new_mode = *data;
|
||||
uint32_t supported =
|
||||
libinput_device_config_send_events_get_modes(device);
|
||||
|
||||
if ((new_mode | supported) != supported)
|
||||
if ((modes | supported) != supported)
|
||||
return BadValue;
|
||||
|
||||
/* Only one bit must be set */
|
||||
if (new_mode && ((new_mode & (new_mode - 1)) != 0))
|
||||
return BadValue;
|
||||
} else {
|
||||
driver_data->options.sendevents = *data;
|
||||
driver_data->options.sendevents = modes;
|
||||
}
|
||||
|
||||
return Success;
|
||||
@@ -1244,7 +1488,7 @@ LibinputSetPropertyLeftHanded(DeviceIntPtr dev,
|
||||
data = (BOOL*)val->data;
|
||||
|
||||
if (checkonly) {
|
||||
int supported = libinput_device_config_buttons_has_left_handed(device);
|
||||
int supported = libinput_device_config_left_handed_is_available(device);
|
||||
int left_handed = *data;
|
||||
|
||||
if (!supported && left_handed)
|
||||
@@ -1286,7 +1530,7 @@ LibinputSetPropertyScrollMethods(DeviceIntPtr dev,
|
||||
if (__builtin_popcount(modes) > 1)
|
||||
return BadValue;
|
||||
|
||||
if ((modes & supported) == 0)
|
||||
if (modes && (modes & supported) == 0)
|
||||
return BadValue;
|
||||
} else {
|
||||
driver_data->options.scroll_method = modes;
|
||||
@@ -1340,11 +1584,15 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
|
||||
rc = LibinputSetPropertyAccel(dev, atom, val, checkonly);
|
||||
else if (atom == prop_natural_scroll)
|
||||
rc = LibinputSetPropertyNaturalScroll(dev, atom, val, checkonly);
|
||||
else if (atom == prop_sendevents)
|
||||
else if (atom == prop_sendevents_available)
|
||||
return BadAccess; /* read-only */
|
||||
else if (atom == prop_sendevents_enabled)
|
||||
rc = LibinputSetPropertySendEvents(dev, atom, val, checkonly);
|
||||
else if (atom == prop_left_handed)
|
||||
rc = LibinputSetPropertyLeftHanded(dev, atom, val, checkonly);
|
||||
else if (atom == prop_scroll_methods)
|
||||
else if (atom == prop_scroll_methods_available)
|
||||
return BadAccess; /* read-only */
|
||||
else if (atom == prop_scroll_method_enabled)
|
||||
rc = LibinputSetPropertyScrollMethods(dev, atom, val, checkonly);
|
||||
else if (atom == prop_scroll_button)
|
||||
rc = LibinputSetPropertyScrollButton(dev, atom, val, checkonly);
|
||||
@@ -1368,6 +1616,7 @@ LibinputInitProperty(DeviceIntPtr dev)
|
||||
const char *device_node;
|
||||
CARD32 product[2];
|
||||
uint32_t scroll_methods;
|
||||
uint32_t sendevent_modes;
|
||||
int rc;
|
||||
|
||||
prop_float = XIGetKnownProperty("FLOAT");
|
||||
@@ -1428,23 +1677,51 @@ LibinputInitProperty(DeviceIntPtr dev)
|
||||
XISetDevicePropertyDeletable(dev, prop_natural_scroll, FALSE);
|
||||
}
|
||||
|
||||
if (libinput_device_config_send_events_get_modes(device) !=
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED) {
|
||||
uint32_t sendevents = driver_data->options.sendevents;
|
||||
sendevent_modes = libinput_device_config_send_events_get_modes(device);
|
||||
if (sendevent_modes != LIBINPUT_CONFIG_SEND_EVENTS_ENABLED) {
|
||||
uint32_t sendevents;
|
||||
BOOL modes[2] = {FALSE};
|
||||
|
||||
prop_sendevents = MakeAtom(PROP_SENDEVENTS,
|
||||
strlen(PROP_SENDEVENTS),
|
||||
TRUE);
|
||||
rc = XIChangeDeviceProperty(dev, prop_sendevents,
|
||||
XA_CARDINAL, 32,
|
||||
PropModeReplace, 1, &sendevents, FALSE);
|
||||
if (sendevent_modes & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED)
|
||||
modes[0] = TRUE;
|
||||
if (sendevent_modes & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
|
||||
modes[1] = TRUE;
|
||||
|
||||
prop_sendevents_available = MakeAtom(PROP_SENDEVENTS_AVAILABLE,
|
||||
strlen(PROP_SENDEVENTS_AVAILABLE),
|
||||
TRUE);
|
||||
rc = XIChangeDeviceProperty(dev, prop_sendevents_available,
|
||||
XA_INTEGER, 8,
|
||||
PropModeReplace, 2, modes, FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
XISetDevicePropertyDeletable(dev, prop_sendevents, FALSE);
|
||||
XISetDevicePropertyDeletable(dev, prop_sendevents_available, FALSE);
|
||||
|
||||
memset(modes, 0, sizeof(modes));
|
||||
sendevents = driver_data->options.sendevents;
|
||||
|
||||
switch(sendevents) {
|
||||
case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
|
||||
modes[0] = TRUE;
|
||||
break;
|
||||
case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
|
||||
modes[1] = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
prop_sendevents_enabled = MakeAtom(PROP_SENDEVENTS_ENABLED,
|
||||
strlen(PROP_SENDEVENTS_ENABLED),
|
||||
TRUE);
|
||||
rc = XIChangeDeviceProperty(dev, prop_sendevents_enabled,
|
||||
XA_INTEGER, 8,
|
||||
PropModeReplace, 2, modes, FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
XISetDevicePropertyDeletable(dev, prop_sendevents_enabled, FALSE);
|
||||
|
||||
}
|
||||
|
||||
if (libinput_device_config_buttons_has_left_handed(device)) {
|
||||
if (libinput_device_config_left_handed_is_available(device)) {
|
||||
BOOL left_handed = driver_data->options.left_handed;
|
||||
|
||||
prop_left_handed = MakeAtom(PROP_LEFT_HANDED,
|
||||
@@ -1463,6 +1740,31 @@ LibinputInitProperty(DeviceIntPtr dev)
|
||||
enum libinput_config_scroll_method method;
|
||||
BOOL methods[3] = {FALSE};
|
||||
|
||||
if (scroll_methods & LIBINPUT_CONFIG_SCROLL_2FG)
|
||||
methods[0] = TRUE;
|
||||
if (scroll_methods & LIBINPUT_CONFIG_SCROLL_EDGE)
|
||||
methods[1] = TRUE;
|
||||
if (scroll_methods & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN)
|
||||
methods[2] = TRUE;
|
||||
|
||||
prop_scroll_methods_available =
|
||||
MakeAtom(PROP_SCROLL_METHODS_AVAILABLE,
|
||||
strlen(PROP_SCROLL_METHODS_AVAILABLE),
|
||||
TRUE);
|
||||
rc = XIChangeDeviceProperty(dev,
|
||||
prop_scroll_methods_available,
|
||||
XA_INTEGER, 8,
|
||||
PropModeReplace,
|
||||
ARRAY_SIZE(methods),
|
||||
&methods, FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
XISetDevicePropertyDeletable(dev,
|
||||
prop_scroll_methods_available,
|
||||
FALSE);
|
||||
|
||||
memset(methods, 0, sizeof(methods));
|
||||
|
||||
method = libinput_device_config_scroll_get_method(device);
|
||||
switch(method) {
|
||||
case LIBINPUT_CONFIG_SCROLL_2FG:
|
||||
@@ -1478,18 +1780,22 @@ LibinputInitProperty(DeviceIntPtr dev)
|
||||
break;
|
||||
}
|
||||
|
||||
prop_scroll_methods = MakeAtom(PROP_SCROLL_METHODS,
|
||||
strlen(PROP_SCROLL_METHODS),
|
||||
TRUE);
|
||||
prop_scroll_method_enabled =
|
||||
MakeAtom(PROP_SCROLL_METHOD_ENABLED,
|
||||
strlen(PROP_SCROLL_METHOD_ENABLED),
|
||||
TRUE);
|
||||
rc = XIChangeDeviceProperty(dev,
|
||||
prop_scroll_methods,
|
||||
prop_scroll_method_enabled,
|
||||
XA_INTEGER, 8,
|
||||
PropModeReplace,
|
||||
ARRAY_SIZE(methods),
|
||||
&methods, FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
XISetDevicePropertyDeletable(dev, prop_scroll_methods, FALSE);
|
||||
|
||||
XISetDevicePropertyDeletable(dev,
|
||||
prop_scroll_method_enabled,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
if (libinput_device_config_scroll_get_methods(device) &
|
||||
|
||||
Reference in New Issue
Block a user