mirror of
https://github.com/X11Libre/xf86-input-libinput.git
synced 2026-03-24 17:44:05 +00:00
Compare commits
28 Commits
xf86-input
...
xf86-input
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef948537e1 | ||
|
|
576da9db26 | ||
|
|
2eb01498bd | ||
|
|
a4fb161c3e | ||
|
|
15291e53b7 | ||
|
|
d9c212d266 | ||
|
|
d48f437aa9 | ||
|
|
84f301f7e3 | ||
|
|
6f06b1dd1d | ||
|
|
fdbf7eaf4b | ||
|
|
2b6c485117 | ||
|
|
246200cbdc | ||
|
|
fb41458a93 | ||
|
|
d9d2e9a501 | ||
|
|
0a58edd3f6 | ||
|
|
8d6019c786 | ||
|
|
532fe35522 | ||
|
|
65a40e2cfc | ||
|
|
7522884a9e | ||
|
|
ef5f0295e7 | ||
|
|
adb4963109 | ||
|
|
e8c4bbceee | ||
|
|
e1a9c82dbc | ||
|
|
fe81ad3ae2 | ||
|
|
6a69462359 | ||
|
|
2f03f67426 | ||
|
|
6d634262fd | ||
|
|
6f91b84fd3 |
20
COPYING
Normal file
20
COPYING
Normal file
@@ -0,0 +1,20 @@
|
||||
Copyright © 2014 Red Hat, Inc.
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software
|
||||
and its documentation for any purpose is hereby granted without
|
||||
fee, provided that the above copyright notice appear in all copies
|
||||
and that both that copyright notice and this permission notice
|
||||
appear in supporting documentation, and that the name of the authors
|
||||
not be used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission. The authors make 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.
|
||||
@@ -19,16 +19,11 @@
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
# Provide an sdk location that is writable by the evdev module
|
||||
DISTCHECK_CONFIGURE_FLAGS = --with-sdkdir='$${includedir}/xorg'
|
||||
|
||||
SUBDIRS = src
|
||||
SUBDIRS = src man
|
||||
MAINTAINERCLEANFILES = ChangeLog INSTALL
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = xorg-libinput.pc
|
||||
|
||||
|
||||
.PHONY: ChangeLog INSTALL
|
||||
|
||||
INSTALL:
|
||||
@@ -38,3 +33,5 @@ ChangeLog:
|
||||
$(CHANGELOG_CMD)
|
||||
|
||||
dist-hook: ChangeLog INSTALL
|
||||
|
||||
EXTRA_DIST = conf/99-libinput.conf README.md
|
||||
|
||||
55
README.md
Normal file
55
README.md
Normal file
@@ -0,0 +1,55 @@
|
||||
xf86-input-libinput - a libinput-based X driver
|
||||
===============================================
|
||||
|
||||
The official repository for this driver is
|
||||
http://cgit.freedesktop.org/xorg/driver/xf86-input-libinput/
|
||||
|
||||
This is an X driver based on libinput. It is a thin wrapper around libinput,
|
||||
so while it does provide all features that libinput supports it does little
|
||||
beyond.
|
||||
|
||||
***WARNING: misconfiguration of an X input driver may leave you without
|
||||
usable input devices in your X session. Use with caution.***
|
||||
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
To build, you'll need the X.Org X server SDK (check your distribution for a
|
||||
xorg-x11-server-devel package or similar) and libinput (check your
|
||||
distribution for libinput-devel or similar).
|
||||
|
||||
To get libinput from source, see:
|
||||
http://www.freedesktop.org/wiki/Software/libinput/
|
||||
|
||||
To build the X server from source:
|
||||
http://www.x.org/wiki/Building_the_X_Window_System/
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
To build this driver:
|
||||
|
||||
autoreconf -vif
|
||||
./configure --prefix=$HOME/build
|
||||
make && make install
|
||||
|
||||
Note that this assumes the same prefix as used in "Building the X Window
|
||||
System" above, adjust as required. If you want a system install, use a
|
||||
prefix of */usr*.
|
||||
|
||||
Install the default configuration file:
|
||||
|
||||
cp conf/99-libinput.conf /etc/X11/xorg.conf.d/
|
||||
|
||||
This will assign this driver to *all* devices. Use with caution.
|
||||
|
||||
|
||||
Bugs
|
||||
----
|
||||
|
||||
Bugs in libinput go to the "libinput" component of wayland:
|
||||
https://bugs.freedesktop.org/enter_bug.cgi?product=Wayland
|
||||
|
||||
Bugs in this driver go to the "Input/libinput" component of xorg:
|
||||
https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
|
||||
6
conf/99-libinput.conf
Normal file
6
conf/99-libinput.conf
Normal file
@@ -0,0 +1,6 @@
|
||||
# Use the libinput driver for all event devices
|
||||
Section "InputClass"
|
||||
Identifier "libinput"
|
||||
Driver "libinput"
|
||||
MatchDevicePath "/dev/input/event*"
|
||||
EndSection
|
||||
13
configure.ac
13
configure.ac
@@ -23,7 +23,7 @@
|
||||
# Initialize Autoconf
|
||||
AC_PREREQ([2.60])
|
||||
AC_INIT([xf86-input-libinput],
|
||||
[0.1.0],
|
||||
[0.2.0],
|
||||
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
|
||||
[xf86-input-libinput])
|
||||
AC_CONFIG_SRCDIR([Makefile.am])
|
||||
@@ -35,7 +35,7 @@ AM_INIT_AUTOMAKE([foreign dist-bzip2])
|
||||
|
||||
# Initialize libtool
|
||||
AC_DISABLE_STATIC
|
||||
AC_PROG_LIBTOOL
|
||||
LT_INIT
|
||||
|
||||
# Initialize X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS
|
||||
m4_ifndef([XORG_MACROS_VERSION],
|
||||
@@ -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.4.0])
|
||||
PKG_CHECK_MODULES(LIBINPUT, [libinput >= 0.6.0])
|
||||
|
||||
# Define a configure option for an alternate input module directory
|
||||
AC_ARG_WITH(xorg-module-dir,
|
||||
@@ -56,8 +56,7 @@ AC_ARG_WITH(xorg-module-dir,
|
||||
inputdir=${moduledir}/input
|
||||
AC_SUBST(inputdir)
|
||||
|
||||
# X Server SDK location is required to install evdev header files
|
||||
# This location is also relayed in the xorg-evdev.pc file
|
||||
# X Server SDK location is required to install header files
|
||||
sdkdir=`$PKG_CONFIG --variable=sdkdir xorg-server`
|
||||
|
||||
# Workaround overriding sdkdir to be able to create a tarball when user has no
|
||||
@@ -69,6 +68,6 @@ DRIVER_NAME=libinput
|
||||
AC_SUBST([DRIVER_NAME])
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
src/Makefile
|
||||
xorg-libinput.pc])
|
||||
src/Makefile
|
||||
man/Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
37
man/Makefile.am
Normal file
37
man/Makefile.am
Normal file
@@ -0,0 +1,37 @@
|
||||
# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
drivermandir = $(DRIVER_MAN_DIR)
|
||||
|
||||
driverman_PRE = $(DRIVER_NAME).man
|
||||
|
||||
driverman_DATA = $(driverman_PRE:man=$(DRIVER_MAN_SUFFIX))
|
||||
|
||||
EXTRA_DIST = $(DRIVER_NAME).man
|
||||
|
||||
CLEANFILES = $(driverman_DATA)
|
||||
|
||||
SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man
|
||||
|
||||
# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure
|
||||
.man.$(DRIVER_MAN_SUFFIX):
|
||||
$(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@
|
||||
95
man/libinput.man
Normal file
95
man/libinput.man
Normal file
@@ -0,0 +1,95 @@
|
||||
.\" shorthand for double quote that works everywhere.
|
||||
.ds q \N'34'
|
||||
.TH LIBINPUT __drivermansuffix__ __vendorversion__
|
||||
.SH NAME
|
||||
libinput \- libinput-based X.Org input driver
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B "Section \*qInputDevice\*q"
|
||||
.BI " Identifier \*q" devname \*q
|
||||
.B " Driver \*qlibinput\*q"
|
||||
.BI " Option \*qDevice\*q \*q" devpath \*q
|
||||
\ \ ...
|
||||
.B EndSection
|
||||
.fi
|
||||
.SH NOTE
|
||||
This is the man page for the X input driver. If you are looking for the
|
||||
library documentation, go to
|
||||
.BI http://wayland.freedesktop.org/libinput/doc/
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B libinput
|
||||
is an __xservername__ input driver based on libinput. It
|
||||
therefore supports all input devices that libinput can handle, including
|
||||
most mice, keyboards, tablets and touchscreens.
|
||||
.PP
|
||||
It is recommended that
|
||||
.B libinput
|
||||
devices are configured through the
|
||||
.B InputClass
|
||||
directive (refer to __xconfigfile__(__filemansuffix__)) instead of manual
|
||||
per-device configuration. Devices configured in the
|
||||
__xconfigfile__(__filemansuffix__) are not hot-plug capable.
|
||||
.SH CONFIGURATION DETAILS
|
||||
Please refer to __xconfigfile__(__filemansuffix__) for general configuration
|
||||
details and for options that can be used with all input drivers. This
|
||||
section only covers configuration details specific to this driver.
|
||||
.PP
|
||||
The following driver
|
||||
.B Options
|
||||
are supported:
|
||||
.TP 7
|
||||
.BI "Option \*qDevice\*q \*q" string \*q
|
||||
Specifies the device through which the device can be accessed. This will
|
||||
generally be of the form \*q/dev/input/eventX\*q, where X is some integer.
|
||||
The mapping from device node to hardware is system-dependent. Property:
|
||||
"Device Node" (read-only).
|
||||
.TP 7
|
||||
.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
|
||||
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).
|
||||
.TP 7
|
||||
.BI "Option \*qNaturalScrolling\*q \*q" bool \*q
|
||||
Enables or disables natural scrolling behavior.
|
||||
.TP 7
|
||||
.BI "Option \*qSendEventsMode\*q \*q" (disabled|enabled|disabled-on-external-mouse) \*q
|
||||
Sets the send events mode to disabled, enabled, or "disable when an external
|
||||
mouse is connected".
|
||||
.TP 7
|
||||
.BI "Option \*qTapping\*q \*q" bool \*q
|
||||
Enables or disables tap-to-click behavior.
|
||||
.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
|
||||
libinput. On configuration failure, the default value is applied.
|
||||
|
||||
.SH SUPPORTED PROPERTIES
|
||||
The following properties are provided by the
|
||||
.B libinput
|
||||
driver.
|
||||
.TP 7
|
||||
.BI "libinput Tapping Enabled"
|
||||
1 boolean value (8 bit, 0 or 1). 1 enables tapping
|
||||
.TP 7
|
||||
.BI "libinput Calibration Matrix"
|
||||
9 32-bit float values, representing a 3x3 calibration matrix, order is row
|
||||
1, row 2, row 3
|
||||
.TP 7
|
||||
.BI "libinput Accel Speed"
|
||||
1 32-bit float value, defines the pointer speed. Value range -1, 1
|
||||
.TP 7
|
||||
.BI "libinput Natural Scrolling Enabled"
|
||||
1 boolean value (8 bit, 0 or 1). 1 enables natural scrolling
|
||||
.TP 7
|
||||
.BI "libinput Send Events Mode"
|
||||
1 32-bit value, defines the sendevent mode. See the libinput documentation
|
||||
for the allowed values.
|
||||
|
||||
.SH AUTHORS
|
||||
Peter Hutterer
|
||||
.SH "SEE ALSO"
|
||||
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
|
||||
@@ -33,6 +33,5 @@ AM_CPPFLAGS =-I$(top_srcdir)/include $(LIBINPUT_CFLAGS)
|
||||
@DRIVER_NAME@_drv_la_LIBADD = $(LIBINPUT_LIBS)
|
||||
@DRIVER_NAME@_drv_ladir = @inputdir@
|
||||
|
||||
@DRIVER_NAME@_drv_la_SOURCES = @DRIVER_NAME@.c \
|
||||
@DRIVER_NAME@.h
|
||||
@DRIVER_NAME@_drv_la_SOURCES = @DRIVER_NAME@.c
|
||||
|
||||
|
||||
590
src/libinput.c
590
src/libinput.c
@@ -38,7 +38,8 @@
|
||||
#include <libinput.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#define TOUCHPAD_MAX_BUTTONS 7 /* three buttons, 4 scroll buttons */
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#define TOUCHPAD_NUM_AXES 4 /* x, y, hscroll, vscroll */
|
||||
#define TOUCH_MAX_SLOTS 15
|
||||
#define XORG_KEYCODE_OFFSET 8
|
||||
@@ -81,8 +82,69 @@ struct xf86libinput {
|
||||
} scale;
|
||||
|
||||
ValuatorMask *valuators;
|
||||
|
||||
struct {
|
||||
BOOL tapping;
|
||||
BOOL natural_scrolling;
|
||||
CARD32 sendevents;
|
||||
float speed;
|
||||
float matrix[9];
|
||||
} options;
|
||||
};
|
||||
|
||||
static int
|
||||
LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
|
||||
BOOL checkonly);
|
||||
static void
|
||||
LibinputInitProperty(DeviceIntPtr dev);
|
||||
|
||||
static inline void
|
||||
LibinputApplyConfig(DeviceIntPtr dev)
|
||||
{
|
||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
struct libinput_device *device = driver_data->device;
|
||||
|
||||
if (libinput_device_config_send_events_get_modes(device) != LIBINPUT_CONFIG_SEND_EVENTS_ENABLED &&
|
||||
libinput_device_config_send_events_set_mode(device,
|
||||
driver_data->options.sendevents) != LIBINPUT_CONFIG_STATUS_SUCCESS)
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Failed to set SendEventsMode %d\n",
|
||||
driver_data->options.sendevents);
|
||||
|
||||
if (libinput_device_config_scroll_has_natural_scroll(device) &&
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled(device,
|
||||
driver_data->options.natural_scrolling) != LIBINPUT_CONFIG_STATUS_SUCCESS)
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Failed to set NaturalScrolling to %d\n",
|
||||
driver_data->options.natural_scrolling);
|
||||
|
||||
if (libinput_device_config_accel_is_available(device) &&
|
||||
libinput_device_config_accel_set_speed(device,
|
||||
driver_data->options.speed) != LIBINPUT_CONFIG_STATUS_SUCCESS)
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Failed to set speed %.2f\n",
|
||||
driver_data->options.speed);
|
||||
if (libinput_device_config_tap_get_finger_count(device) > 0 &&
|
||||
libinput_device_config_tap_set_enabled(device,
|
||||
driver_data->options.tapping) != LIBINPUT_CONFIG_STATUS_SUCCESS)
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Failed to set Tapping to %d\n",
|
||||
driver_data->options.tapping);
|
||||
|
||||
if (libinput_device_config_calibration_has_matrix(device) &&
|
||||
libinput_device_config_calibration_set_matrix(device,
|
||||
driver_data->options.matrix) != LIBINPUT_CONFIG_STATUS_SUCCESS)
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Failed to apply matrix: "
|
||||
"%.2f %.2f %.2f %2.f %.2f %.2f %.2f %.2f %.2f\n",
|
||||
driver_data->options.matrix[0], driver_data->options.matrix[1],
|
||||
driver_data->options.matrix[2], driver_data->options.matrix[3],
|
||||
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 int
|
||||
xf86libinput_on(DeviceIntPtr dev)
|
||||
{
|
||||
@@ -144,13 +206,15 @@ init_button_map(unsigned char *btnmap, size_t size)
|
||||
int i;
|
||||
|
||||
memset(btnmap, 0, size);
|
||||
for (i = 0; i <= TOUCHPAD_MAX_BUTTONS; i++)
|
||||
for (i = 0; i <= size; i++)
|
||||
btnmap[i] = i;
|
||||
}
|
||||
|
||||
static void
|
||||
init_button_labels(Atom *labels, size_t size)
|
||||
{
|
||||
assert(size > 10);
|
||||
|
||||
memset(labels, 0, size * sizeof(Atom));
|
||||
labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
|
||||
labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
|
||||
@@ -159,6 +223,10 @@ init_button_labels(Atom *labels, size_t size)
|
||||
labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
|
||||
labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
|
||||
labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
|
||||
labels[7] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_SIDE);
|
||||
labels[8] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_EXTRA);
|
||||
labels[9] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_BACK);
|
||||
labels[10] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_FORWARD);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -177,17 +245,27 @@ xf86libinput_init_pointer(InputInfoPtr pInfo)
|
||||
DeviceIntPtr dev= pInfo->dev;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
int min, max, res;
|
||||
int nbuttons = 7;
|
||||
int i;
|
||||
|
||||
unsigned char btnmap[TOUCHPAD_MAX_BUTTONS + 1];
|
||||
Atom btnlabels[TOUCHPAD_MAX_BUTTONS];
|
||||
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,
|
||||
TOUCHPAD_MAX_BUTTONS,
|
||||
nbuttons,
|
||||
btnlabels,
|
||||
xf86libinput_ptr_ctl,
|
||||
GetMotionHistorySize(),
|
||||
@@ -260,16 +338,17 @@ xf86libinput_init_touch(InputInfoPtr pInfo)
|
||||
{
|
||||
DeviceIntPtr dev = pInfo->dev;
|
||||
int min, max, res;
|
||||
unsigned char btnmap[TOUCHPAD_MAX_BUTTONS + 1];
|
||||
Atom btnlabels[TOUCHPAD_MAX_BUTTONS];
|
||||
unsigned char btnmap[MAX_BUTTONS + 1];
|
||||
Atom btnlabels[MAX_BUTTONS];
|
||||
Atom axislabels[TOUCHPAD_NUM_AXES];
|
||||
int nbuttons = 7;
|
||||
|
||||
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,
|
||||
TOUCHPAD_MAX_BUTTONS,
|
||||
nbuttons,
|
||||
btnlabels,
|
||||
xf86libinput_ptr_ctl,
|
||||
GetMotionHistorySize(),
|
||||
@@ -309,6 +388,9 @@ xf86libinput_init(DeviceIntPtr dev)
|
||||
DEVICE_ON */
|
||||
libinput_device_unref(device);
|
||||
|
||||
LibinputInitProperty(dev);
|
||||
XIRegisterPropertyHandler(dev, LibinputSetProperty, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -550,6 +632,45 @@ const struct libinput_interface interface = {
|
||||
.close_restricted = close_restricted,
|
||||
};
|
||||
|
||||
static void
|
||||
xf86libinput_log_handler(struct libinput *libinput,
|
||||
enum libinput_log_priority priority,
|
||||
const char *format,
|
||||
va_list args)
|
||||
_X_ATTRIBUTE_PRINTF(3, 0);
|
||||
|
||||
static void
|
||||
xf86libinput_log_handler(struct libinput *libinput,
|
||||
enum libinput_log_priority priority,
|
||||
const char *format,
|
||||
va_list args)
|
||||
{
|
||||
MessageType type;
|
||||
int verbosity;
|
||||
|
||||
switch(priority) {
|
||||
case LIBINPUT_LOG_PRIORITY_DEBUG:
|
||||
type = X_DEBUG;
|
||||
verbosity = 10;
|
||||
break;
|
||||
case LIBINPUT_LOG_PRIORITY_ERROR:
|
||||
type = X_ERROR;
|
||||
verbosity = -1;
|
||||
break;
|
||||
case LIBINPUT_LOG_PRIORITY_INFO:
|
||||
type = X_INFO;
|
||||
verbosity = 3;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* log messages in libinput are per-context, not per device, so we
|
||||
can't use xf86IDrvMsg here, and the server has no xf86VMsg or
|
||||
similar */
|
||||
LogVMessageVerb(type, verbosity, format, args);
|
||||
}
|
||||
|
||||
static int xf86libinput_pre_init(InputDriverPtr drv,
|
||||
InputInfoPtr pInfo,
|
||||
int flags)
|
||||
@@ -560,7 +681,7 @@ static int xf86libinput_pre_init(InputDriverPtr drv,
|
||||
char *path;
|
||||
|
||||
pInfo->fd = -1;
|
||||
pInfo->type_name = XI_TOUCHPAD;
|
||||
pInfo->type_name = 0;
|
||||
pInfo->device_control = xf86libinput_device_control;
|
||||
pInfo->read_input = xf86libinput_read_input;
|
||||
pInfo->control_proc = NULL;
|
||||
@@ -581,10 +702,16 @@ static int xf86libinput_pre_init(InputDriverPtr drv,
|
||||
if (!path)
|
||||
goto fail;
|
||||
|
||||
if (!driver_context.libinput)
|
||||
if (!driver_context.libinput) {
|
||||
driver_context.libinput = libinput_path_create_context(&interface, &driver_context);
|
||||
else
|
||||
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;
|
||||
|
||||
@@ -610,8 +737,130 @@ static int xf86libinput_pre_init(InputDriverPtr drv,
|
||||
driver_data->path = path;
|
||||
driver_data->device = device;
|
||||
|
||||
return Success;
|
||||
/* 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",
|
||||
libinput_device_config_tap_get_enabled(device));
|
||||
if (libinput_device_config_tap_set_enabled(device, tap) !=
|
||||
LIBINPUT_CONFIG_STATUS_SUCCESS) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Failed to set Tapping to %d\n",
|
||||
tap);
|
||||
tap = libinput_device_config_tap_get_enabled(device);
|
||||
}
|
||||
driver_data->options.tapping = tap;
|
||||
}
|
||||
|
||||
if (libinput_device_config_accel_is_available(device)) {
|
||||
double speed = xf86SetRealOption(pInfo->options,
|
||||
"AccelSpeed",
|
||||
libinput_device_config_accel_get_speed(device));
|
||||
if (libinput_device_config_accel_set_speed(device, speed) !=
|
||||
LIBINPUT_CONFIG_STATUS_SUCCESS) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Invalid speed %.2f, using 0 instead\n",
|
||||
speed);
|
||||
driver_data->options.speed = libinput_device_config_accel_get_speed(device);
|
||||
}
|
||||
driver_data->options.speed = speed;
|
||||
}
|
||||
|
||||
if (libinput_device_config_scroll_has_natural_scroll(device)) {
|
||||
BOOL natural_scroll = xf86SetBoolOption(pInfo->options,
|
||||
"NaturalScrolling",
|
||||
libinput_device_config_scroll_get_natural_scroll_enabled(device));
|
||||
if (libinput_device_config_scroll_set_natural_scroll_enabled(device,
|
||||
natural_scroll) !=
|
||||
LIBINPUT_CONFIG_STATUS_SUCCESS) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Failed to set NaturalScrolling to %d\n",
|
||||
natural_scroll);
|
||||
|
||||
natural_scroll = libinput_device_config_scroll_get_natural_scroll_enabled(device);
|
||||
}
|
||||
driver_data->options.natural_scrolling = natural_scroll;
|
||||
}
|
||||
|
||||
if (libinput_device_config_send_events_get_modes(device) != LIBINPUT_CONFIG_SEND_EVENTS_ENABLED) {
|
||||
char *strmode;
|
||||
enum libinput_config_send_events_mode mode =
|
||||
libinput_device_config_send_events_get_mode(device);
|
||||
|
||||
strmode = xf86SetStrOption(pInfo->options,
|
||||
"SendEventsMode",
|
||||
NULL);
|
||||
if (strmode) {
|
||||
if (strcmp(strmode, "enabled") == 0)
|
||||
mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
else if (strcmp(strmode, "disabled") == 0)
|
||||
mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
|
||||
else if (strcmp(strmode, "disabled-on-external-mouse") == 0)
|
||||
mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
|
||||
else
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Invalid SendeventsMode: %s\n",
|
||||
strmode);
|
||||
}
|
||||
|
||||
if (libinput_device_config_send_events_set_mode(device, mode) !=
|
||||
LIBINPUT_CONFIG_STATUS_SUCCESS) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Failed to set SendEventsMode %d\n", mode);
|
||||
mode = libinput_device_config_send_events_get_mode(device);
|
||||
}
|
||||
driver_data->options.sendevents = mode;
|
||||
free(strmode);
|
||||
}
|
||||
|
||||
if (libinput_device_config_calibration_has_matrix(device)) {
|
||||
char *str;
|
||||
float matrix[9] = { 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
|
||||
|
||||
libinput_device_config_calibration_get_matrix(device,
|
||||
matrix);
|
||||
memcpy(driver_data->options.matrix, matrix, sizeof(matrix));
|
||||
|
||||
if ((str = xf86CheckStrOption(pInfo->options,
|
||||
"CalibrationMatrix",
|
||||
NULL))) {
|
||||
int num_calibration = sscanf(str, "%f %f %f %f %f %f %f %f %f ",
|
||||
&matrix[0], &matrix[1],
|
||||
&matrix[2], &matrix[3],
|
||||
&matrix[4], &matrix[5],
|
||||
&matrix[6], &matrix[7],
|
||||
&matrix[8]);
|
||||
if (num_calibration != 9) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Invalid matrix: %s, using default\n", str);
|
||||
} else if (libinput_device_config_calibration_set_matrix(device,
|
||||
matrix) ==
|
||||
LIBINPUT_CONFIG_STATUS_SUCCESS) {
|
||||
memcpy(driver_data->options.matrix, matrix, sizeof(matrix));
|
||||
} else
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"Failed to apply matrix: %s, using default\n", str);
|
||||
|
||||
free(str);
|
||||
}
|
||||
}
|
||||
|
||||
/* now pick an actual type */
|
||||
if (libinput_device_config_tap_get_finger_count(device) > 0)
|
||||
pInfo->type_name = XI_TOUCHPAD;
|
||||
else if (libinput_device_has_capability(device,
|
||||
LIBINPUT_DEVICE_CAP_TOUCH))
|
||||
pInfo->type_name = XI_TOUCHSCREEN;
|
||||
else if (libinput_device_has_capability(device,
|
||||
LIBINPUT_DEVICE_CAP_POINTER))
|
||||
pInfo->type_name = XI_MOUSE;
|
||||
else
|
||||
pInfo->type_name = XI_KEYBOARD;
|
||||
|
||||
return Success;
|
||||
fail:
|
||||
if (driver_data->valuators)
|
||||
valuator_mask_free(&driver_data->valuators);
|
||||
@@ -670,3 +919,320 @@ _X_EXPORT XF86ModuleData libinputModuleData = {
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Property support */
|
||||
|
||||
/* Tapping enabled/disabled: BOOL, 1 value */
|
||||
#define PROP_TAP "libinput Tapping Enabled"
|
||||
/* Calibration matrix: FLOAT, 9 values of a 3x3 matrix, in rows */
|
||||
#define PROP_CALIBRATION "libinput Calibration Matrix"
|
||||
/* Pointer accel speed: FLOAT, 1 value, 32 bit */
|
||||
#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"
|
||||
|
||||
/* libinput-specific properties */
|
||||
static Atom prop_tap;
|
||||
static Atom prop_calibration;
|
||||
static Atom prop_accel;
|
||||
static Atom prop_natural_scroll;
|
||||
static Atom prop_sendevents;
|
||||
|
||||
/* general properties */
|
||||
static Atom prop_float;
|
||||
static Atom prop_device;
|
||||
static Atom prop_product_id;
|
||||
|
||||
static inline int
|
||||
LibinputSetPropertyTap(DeviceIntPtr dev,
|
||||
Atom atom,
|
||||
XIPropertyValuePtr val,
|
||||
BOOL checkonly)
|
||||
{
|
||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
struct libinput_device *device = driver_data->device;
|
||||
BOOL* data;
|
||||
|
||||
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
|
||||
return BadMatch;
|
||||
|
||||
data = (BOOL*)val->data;
|
||||
if (checkonly) {
|
||||
if (*data != 0 && *data != 1)
|
||||
return BadValue;
|
||||
|
||||
if (libinput_device_config_tap_get_finger_count(device) == 0)
|
||||
return BadMatch;
|
||||
} else {
|
||||
driver_data->options.tapping = *data;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static inline int
|
||||
LibinputSetPropertyCalibration(DeviceIntPtr dev,
|
||||
Atom atom,
|
||||
XIPropertyValuePtr val,
|
||||
BOOL checkonly)
|
||||
{
|
||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
struct libinput_device *device = driver_data->device;
|
||||
float* data;
|
||||
|
||||
if (val->format != 32 || val->size != 9 || val->type != prop_float)
|
||||
return BadMatch;
|
||||
|
||||
data = (float*)val->data;
|
||||
|
||||
if (checkonly) {
|
||||
if (data[6] != 0 ||
|
||||
data[7] != 0 ||
|
||||
data[8] != 1)
|
||||
return BadValue;
|
||||
|
||||
if (!libinput_device_config_calibration_has_matrix(device))
|
||||
return BadMatch;
|
||||
} else {
|
||||
memcpy(driver_data->options.matrix,
|
||||
data,
|
||||
sizeof(driver_data->options.matrix));
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static inline int
|
||||
LibinputSetPropertyAccel(DeviceIntPtr dev,
|
||||
Atom atom,
|
||||
XIPropertyValuePtr val,
|
||||
BOOL checkonly)
|
||||
{
|
||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
struct libinput_device *device = driver_data->device;
|
||||
float* data;
|
||||
|
||||
if (val->format != 32 || val->size != 1 || val->type != prop_float)
|
||||
return BadMatch;
|
||||
|
||||
data = (float*)val->data;
|
||||
|
||||
if (checkonly) {
|
||||
if (*data < -1 || *data > 1)
|
||||
return BadValue;
|
||||
|
||||
if (libinput_device_config_accel_is_available(device) == 0)
|
||||
return BadMatch;
|
||||
} else {
|
||||
driver_data->options.speed = *data;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static inline int
|
||||
LibinputSetPropertyNaturalScroll(DeviceIntPtr dev,
|
||||
Atom atom,
|
||||
XIPropertyValuePtr val,
|
||||
BOOL checkonly)
|
||||
{
|
||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
struct libinput_device *device = driver_data->device;
|
||||
BOOL* data;
|
||||
|
||||
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
|
||||
return BadMatch;
|
||||
|
||||
data = (BOOL*)val->data;
|
||||
|
||||
if (checkonly) {
|
||||
if (*data != 0 && *data != 1)
|
||||
return BadValue;
|
||||
|
||||
if (libinput_device_config_scroll_has_natural_scroll(device) == 0)
|
||||
return BadMatch;
|
||||
} else {
|
||||
driver_data->options.natural_scrolling = *data;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static inline int
|
||||
LibinputSetPropertySendEvents(DeviceIntPtr dev,
|
||||
Atom atom,
|
||||
XIPropertyValuePtr val,
|
||||
BOOL checkonly)
|
||||
{
|
||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
struct libinput_device *device = driver_data->device;
|
||||
CARD32* data;
|
||||
|
||||
if (val->format != 32 || val->size != 1 || val->type != XA_CARDINAL)
|
||||
return BadMatch;
|
||||
|
||||
data = (CARD32*)val->data;
|
||||
|
||||
if (checkonly) {
|
||||
uint32_t supported = libinput_device_config_send_events_get_modes(device);
|
||||
uint32_t new_mode = *data;
|
||||
|
||||
if ((new_mode | 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;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
|
||||
BOOL checkonly)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (atom == prop_tap)
|
||||
rc = LibinputSetPropertyTap(dev, atom, val, checkonly);
|
||||
else if (atom == prop_calibration)
|
||||
rc = LibinputSetPropertyCalibration(dev, atom, val,
|
||||
checkonly);
|
||||
else if (atom == prop_accel)
|
||||
rc = LibinputSetPropertyAccel(dev, atom, val, checkonly);
|
||||
else if (atom == prop_natural_scroll)
|
||||
rc = LibinputSetPropertyNaturalScroll(dev, atom, val, checkonly);
|
||||
else if (atom == prop_sendevents)
|
||||
rc = LibinputSetPropertySendEvents(dev, atom, val, checkonly);
|
||||
else if (atom == prop_device || atom == prop_product_id)
|
||||
return BadAccess; /* read-only */
|
||||
else
|
||||
return Success;
|
||||
|
||||
if (!checkonly && rc == Success)
|
||||
LibinputApplyConfig(dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
LibinputInitProperty(DeviceIntPtr dev)
|
||||
{
|
||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
struct libinput_device *device = driver_data->device;
|
||||
const char *device_node;
|
||||
CARD32 product[2];
|
||||
int rc;
|
||||
|
||||
prop_float = XIGetKnownProperty("FLOAT");
|
||||
|
||||
if (libinput_device_config_tap_get_finger_count(device) > 0) {
|
||||
BOOL tap = driver_data->options.tapping;
|
||||
|
||||
prop_tap = MakeAtom(PROP_TAP, strlen(PROP_TAP), TRUE);
|
||||
rc = XIChangeDeviceProperty(dev, prop_tap, XA_INTEGER, 8,
|
||||
PropModeReplace, 1, &tap, FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
XISetDevicePropertyDeletable(dev, prop_tap, FALSE);
|
||||
}
|
||||
|
||||
/* We use a 9-element matrix just to be closer to the X server's
|
||||
transformation matrix which also has the full matrix */
|
||||
if (libinput_device_config_calibration_has_matrix(device)) {
|
||||
float calibration[9];
|
||||
|
||||
libinput_device_config_calibration_get_matrix(device, calibration);
|
||||
calibration[6] = 0;
|
||||
calibration[7] = 0;
|
||||
calibration[8] = 1;
|
||||
|
||||
prop_calibration = MakeAtom(PROP_CALIBRATION,
|
||||
strlen(PROP_CALIBRATION),
|
||||
TRUE);
|
||||
|
||||
rc = XIChangeDeviceProperty(dev, prop_calibration, prop_float, 32,
|
||||
PropModeReplace, 9, calibration, FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
|
||||
}
|
||||
|
||||
if (libinput_device_config_accel_is_available(device)) {
|
||||
float speed = driver_data->options.speed;
|
||||
|
||||
prop_accel = MakeAtom(PROP_ACCEL, strlen(PROP_ACCEL), TRUE);
|
||||
rc = XIChangeDeviceProperty(dev, prop_accel, prop_float, 32,
|
||||
PropModeReplace, 1, &speed, FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
XISetDevicePropertyDeletable(dev, prop_accel, FALSE);
|
||||
}
|
||||
|
||||
if (libinput_device_config_scroll_has_natural_scroll(device)) {
|
||||
BOOL natural_scroll = driver_data->options.natural_scrolling;
|
||||
|
||||
prop_natural_scroll = MakeAtom(PROP_NATURAL_SCROLL,
|
||||
strlen(PROP_NATURAL_SCROLL),
|
||||
TRUE);
|
||||
rc = XIChangeDeviceProperty(dev, prop_natural_scroll, XA_INTEGER, 8,
|
||||
PropModeReplace, 1, &natural_scroll, FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
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;
|
||||
|
||||
prop_sendevents = MakeAtom(PROP_SENDEVENTS,
|
||||
strlen(PROP_SENDEVENTS),
|
||||
TRUE);
|
||||
rc = XIChangeDeviceProperty(dev, prop_sendevents,
|
||||
XA_CARDINAL, 32,
|
||||
PropModeReplace, 1, &sendevents, FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
XISetDevicePropertyDeletable(dev, prop_sendevents, FALSE);
|
||||
|
||||
}
|
||||
|
||||
/* Device node property, read-only */
|
||||
device_node = driver_data->path;
|
||||
prop_device = MakeAtom(XI_PROP_DEVICE_NODE,
|
||||
strlen(XI_PROP_DEVICE_NODE),
|
||||
TRUE);
|
||||
rc = XIChangeDeviceProperty(dev, prop_device, XA_STRING, 8,
|
||||
PropModeReplace,
|
||||
strlen(device_node), device_node,
|
||||
FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
|
||||
XISetDevicePropertyDeletable(dev, prop_device, FALSE);
|
||||
|
||||
|
||||
prop_product_id = MakeAtom(XI_PROP_PRODUCT_ID,
|
||||
strlen(XI_PROP_PRODUCT_ID),
|
||||
TRUE);
|
||||
product[0] = libinput_device_get_id_vendor(device);
|
||||
product[1] = libinput_device_get_id_product(device);
|
||||
rc = XIChangeDeviceProperty(dev, prop_product_id, XA_INTEGER, 32,
|
||||
PropModeReplace, 2, product, FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
|
||||
XISetDevicePropertyDeletable(dev, prop_product_id, FALSE);
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
sdkdir=@sdkdir@
|
||||
|
||||
Name: xorg-libinput
|
||||
Description: X.Org libinput input driver.
|
||||
Version: @PACKAGE_VERSION@
|
||||
Cflags: -I${sdkdir}
|
||||
Reference in New Issue
Block a user