Compare commits

...

17 Commits

Author SHA1 Message Date
Peter Hutterer
c712930ef4 xf86-input-libinput 1.5.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-10-15 14:06:00 +10:00
Peter Hutterer
db7cfbe5c2 test: fix some scan-build warnings
e.g.
../../../test/test-draglock.c:262:2: warning: Value stored to 'rc' is never read [deadcode.DeadStores]
  262 |         rc = draglock_init_from_string(&dl, "10");
2024-10-15 13:58:18 +10:00
Peter Hutterer
cb80d7f82d Map some specific high keycodes into the FK20-23 range
These mappings have been part of xkeyboard-config for over a decade and
the likely reason they were introduced is that the corresponding evdev
keycode is > 255.

Let's forcibly remap those in the driver here so the rest of the system
can switch to the real keycodes instead of having to map them to the
whatever X expects.

See https://github.com/systemd/systemd/pull/34325/

Part-of: <https://gitlab.freedesktop.org/xorg/driver/xf86-input-libinput/-/merge_requests/62>
2024-10-09 23:25:17 +00:00
Peter Hutterer
7c5635cd6f Silence a compiler warning
../src/xf86libinput.c: In function ‘prop_draglock_set_pairs’:
../src/xf86libinput.c:5153:30: warning: comparison is always false due to limited range of data type [-Wtype-limits]
 5153 |                 if (pairs[i] > MAX_BUTTONS)

MAX_BUTTONS is defined by the server so let's use a temporary local
variable to silence the compiler.

Part-of: <https://gitlab.freedesktop.org/xorg/driver/xf86-input-libinput/-/merge_requests/61>
2024-10-09 14:02:44 +10:00
Peter Hutterer
b396ba3697 Prevent theoretical null-pointer dereference
Cannot happen since we don't enter this function if the atom isn't one
of the three checked above but the static analyzer doesn't know that.

Part-of: <https://gitlab.freedesktop.org/xorg/driver/xf86-input-libinput/-/merge_requests/60>
2024-09-13 03:06:20 +00:00
Martin Rys
0bcb60e744 Add support for LIBINPUT_LED_COMPOSE/LIBINPUT_LED_KANA
Added in libinput 1.26

Part-of: <https://gitlab.freedesktop.org/xorg/driver/xf86-input-libinput/-/merge_requests/58>
2024-09-12 09:31:01 +10:00
Peter Hutterer
3a33984cce Fix a bunch of whitespace issues
xf86libinput_kbd_ctrl() in particular was a copy/paste with 4-space
indentation, the rest is mostly space->tab replacement.

As pointed out in !58

Part-of: <https://gitlab.freedesktop.org/xorg/driver/xf86-input-libinput/-/merge_requests/59>
2024-09-06 10:14:31 +10:00
Peter Hutterer
bb41cc730c Add support for clickfinger button maps 2024-07-19 11:44:49 +10:00
Peter Hutterer
72c8eb25f8 Implement tablet tool pressure range support 2024-06-10 09:27:57 +00:00
Peter Hutterer
74335c6fd6 Revert "fix int type mismatches in printf()-like calls"
This now warns on 64-bit machines:
../src/xf86libinput.c:542:61: warning: format ‘%lu’ expects argument
of type ‘long unsigned int’, but argument 4 has type ‘CARD32’ {aka ‘unsigned int’} [-Wformat=]

Given they vastly outnumber 32-bit machines now, let's go back to the
old one that only warns on 32 bit until we fix the actual source types
to use uint32_t and similar.

This reverts commit a7d2994256.
2024-06-07 11:14:17 +10:00
Enrico Weigelt, metux IT consult
b791b30b1f update .gitignore
"test/test-bezier" was yet missing

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-02-21 13:21:09 +01:00
Enrico Weigelt, metux IT consult
a7d2994256 fix int type mismatches in printf()-like calls
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-02-21 13:21:09 +01:00
Enrico Weigelt, metux IT consult
c6b4d2732f replace BUG_() macros by xf86IDrvMsg() calls
Latest master moved the BUG_() macros out of os.h, and it's more appropriate
to use xf86IDrvMsg() in those cases (like we're already doing in other places)
anyways.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-02-21 13:19:47 +01:00
Peter Hutterer
6ed6814489 gitlab CI: update to latest templates and current fedora 2024-02-20 08:24:15 +10:00
Peter Hutterer
a24f467576 Add editorconfig file 2024-02-20 08:22:16 +10:00
Peter Hutterer
b254d491e2 Add a property for the tablet tool serial and hw ID
The driver encodes the serial in the device name but that's not reliable
enough. Expose both serial and tool id (optional) as a property so
clients can read them and adjust their behavior accordingly.

Fixes #16
2023-11-10 08:17:46 +10:00
Peter Hutterer
0dc42f0e4e Sort the read-only properties 2023-11-10 08:16:59 +10:00
9 changed files with 560 additions and 65 deletions

17
.editorconfig Normal file
View File

@@ -0,0 +1,17 @@
# https://editorconfig.org/
root = true
[*]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
[*.{c,h}]
indent_size = 8
indent_style = tab
[{meson.build,meson_options.txt}]
indent_size = 8
indent_style = tab

1
.gitignore vendored
View File

@@ -84,3 +84,4 @@ core
test-driver
tags
.vimdir
test/test-bezier

View File

@@ -4,7 +4,7 @@
# Please see the ci-templates documentation for details:
# https://freedesktop.pages.freedesktop.org/ci-templates/
.templates_sha: &template_sha c5626190ec14b475271288dda7a7dae8dbe0cd76 # see https://docs.gitlab.com/ee/ci/yaml/#includefile
.templates_sha: &template_sha 84052757dacc5fd65f5ace92b7fe63c60f6c8558 # see https://docs.gitlab.com/ee/ci/yaml/#includefile
include:
- project: 'freedesktop/ci-templates'
@@ -26,10 +26,10 @@ stages:
.fedora:
variables:
FDO_DISTRIBUTION_VERSION: 33
FDO_DISTRIBUTION_VERSION: 39
FDO_DISTRIBUTION_PACKAGES: 'git autoconf automake libtool make xorg-x11-server-devel libudev-devel libevdev-devel libinput-devel xorg-x11-util-macros'
FDO_DISTRIBUTION_EXEC: 'env FDO_CI_CONCURRENT=${FDO_CI_CONCURRENT} bash .gitlab-ci/fedora-install.sh'
FDO_DISTRIBUTION_TAG: '2021-09-15.0'
FDO_DISTRIBUTION_TAG: '2024-02-20.0'
fedora@container_build:
@@ -58,7 +58,7 @@ fedora@container_build:
- _builddir/config.log
fedora:33@default-build:
fedora@default-build:
extends:
- .fedora
- .fdo.distribution-image@fedora

View File

@@ -23,7 +23,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-input-libinput],
[1.4.0],
[1.5.0],
[https://gitlab.freedesktop.org/xorg/driver/xf86-input-libinput/issues],
[xf86-input-libinput])
AC_CONFIG_SRCDIR([Makefile.am])
@@ -89,6 +89,28 @@ AC_LINK_IFELSE(
[AC_MSG_RESULT([no])
[libinput_have_custom_accel=no]])
AC_MSG_CHECKING([if libinput_tablet_tool_config_pressure_range_set is available])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[#include <libinput.h>]],
[[libinput_tablet_tool_config_pressure_range_set(0)]])],
[AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_LIBINPUT_PRESURE_RANGE, [1],
[libinput_tablet_tool_config_pressure_range_set() is available])
[libinput_have_pressure_range=yes]],
[AC_MSG_RESULT([no])
[libinput_have_pressure_range=no]])
AC_MSG_CHECKING([if libinput_device_config_click_set_clickfinger_button_map is available])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[#include <libinput.h>]],
[[libinput_device_config_click_set_clickfinger_button_map(NULL, 0)]])],
[AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_LIBINPUT_CLICKFINGER_BUTTON_MAP, [1],
[libinput_device_config_click_set_clickfinger_button_map() is available])
[libinput_have_clickfinger_button_map=yes]],
[AC_MSG_RESULT([no])
[libinput_have_clickfinger_button_map=no]])
LIBS=$OLD_LIBS
CFLAGS=$OLD_CFLAGS

View File

@@ -51,6 +51,13 @@
/* Tap button default order: BOOL, 2 values in order LRM, LMR, read-only */
#define LIBINPUT_PROP_TAP_BUTTONMAP_DEFAULT "libinput Tapping Button Mapping Default"
/* Clickfinger button order: BOOL, 2 values in order LRM, LMR, only one may be set
at any time */
#define LIBINPUT_PROP_CLICKFINGER_BUTTONMAP "libinput Clickfinger Button Mapping Enabled"
/* Clickfinger button default order: BOOL, 2 values in order LRM, LMR, read-only */
#define LIBINPUT_PROP_CLICKFINGER_BUTTONMAP_DEFAULT "libinput Clickfinger Button Mapping Default"
/* Calibration matrix: FLOAT, 9 values of a 3x3 matrix, in rows */
#define LIBINPUT_PROP_CALIBRATION "libinput Calibration Matrix"
@@ -222,6 +229,15 @@
*/
#define LIBINPUT_PROP_TABLET_TOOL_PRESSURECURVE "libinput Tablet Tool Pressurecurve"
/* Tablet tool pressure range: float, 2 values, 32 bit
* Value range is [0.0, 1.0] for min and max physical pressure to map to the logical range
* Default value: 0.0 1.0
*/
#define LIBINPUT_PROP_TABLET_TOOL_PRESSURE_RANGE "libinput Tablet Tool Pressure Range"
/* Tablet tool pressure range: float, 2 values, 32 bit, read-only */
#define LIBINPUT_PROP_TABLET_TOOL_PRESSURE_RANGE_DEFAULT "libinput Tablet Tool Pressure Range Default"
/* Tablet tool area ratio: CARD32, 2 values, w and h */
#define LIBINPUT_PROP_TABLET_TOOL_AREA_RATIO "libinput Tablet Tool Area Ratio"
@@ -229,4 +245,19 @@
* If disabled, high-resolution wheel scroll events are discarded */
#define LIBINPUT_PROP_HIRES_WHEEL_SCROLL_ENABLED "libinput High Resolution Wheel Scroll Enabled"
/* The tablet tool unique serial number: CARD32, 1 value, constant for the
* lifetime of the device.
*
* If this property exists and is zero, the tool does not have a unique serial
* number.
*/
#define LIBINPUT_PROP_TABLET_TOOL_SERIAL "libinput Tablet Tool Serial"
/* The tablet tool hardware ID: CARD32, 1 value, constant for the lifetime of the device.
*
* This property only exists if the device has a known tool ID.
* See libinput_tablet_tool_get_tool_id() in the libinput documentation for details.
*/
#define LIBINPUT_PROP_TABLET_TOOL_ID "libinput Tablet Tool ID"
#endif /* _LIBINPUT_PROPERTIES_H_ */

View File

@@ -210,6 +210,14 @@ points. The respective x/y coordinate must be in the [0.0, 1.0] range. For
more information see section
.B TABLET STYLUS PRESSURE CURVE.
.TP 7
.BI "Option \*qTabletToolPressureRange\*q \*q" "min max" \*q
Set the pressure range for a tablet stylus to the given subset of the physical
range. The min/max values must be in the [0.0, 1.0] range. For
example a min of 0.3 means the tablet will send 0 pressure for anything equal
or below 30% of the physical pressure range and a max of 0.7 means
the tablet sends its maximum pressure value for any pressure equal or higher to
70% of the physical pressure range.
.TP 7
.BI "Option \*qTabletToolAreaRatio\*q \*q" "w:h" \*q
Sets the area ratio for a tablet tool. The area always starts at the
origin (0/0) and expands to the largest available area with the specified

View File

@@ -1,5 +1,5 @@
project('xf86-input-libinput', 'c',
version: '1.4.0', # bump version in configure.ac
version: '1.5.0', # bump version in configure.ac
default_options: ['warning_level=2'],
meson_version: '>= 0.50.0')
@@ -57,6 +57,17 @@ if cc.has_function('libinput_config_accel_create',
dependencies: dep_libinput)
config_h.set('HAVE_LIBINPUT_CUSTOM_ACCEL', 1)
endif
if cc.has_function('libinput_tablet_tool_config_pressure_range_set',
dependencies: dep_libinput)
config_h.set('HAVE_LIBINPUT_PRESSURE_RANGE', 1)
endif
if cc.has_function('libinput_device_config_click_set_clickfinger_button_map',
dependencies: dep_libinput)
config_h.set('HAVE_LIBINPUT_CLICKFINGER_BUTTON_MAP', 1)
endif
if cc.has_header_symbol('libinput.h', 'LIBINPUT_LED_COMPOSE')
config_h.set('HAVE_LIBINPUT_COMPOSE_AND_KANA', 1)
endif
dir_headers = get_option('sdkdir')
if dir_headers == ''

View File

@@ -179,6 +179,9 @@ struct xf86libinput {
float matrix[9];
enum libinput_config_scroll_method scroll_method;
enum libinput_config_click_method click_method;
#if HAVE_LIBINPUT_CLICKFINGER_BUTTON_MAP
enum libinput_config_clickfinger_button_map clickfinger_button_map;
#endif
enum libinput_config_accel_profile accel_profile;
#if HAVE_LIBINPUT_CUSTOM_ACCEL
struct accel_points accel_points_fallback;
@@ -192,6 +195,9 @@ struct xf86libinput {
float rotation_angle;
struct bezier_control_point pressurecurve[4];
struct range {
float min, max;
} pressure_range;
struct ratio {
int x, y;
} area;
@@ -455,6 +461,25 @@ xf86libinput_set_pressurecurve(struct xf86libinput *driver_data,
driver_data->pressurecurve.sz);
}
static inline bool
xf86libinput_set_pressure_range(struct xf86libinput *driver_data,
const struct range *range)
{
#if HAVE_LIBINPUT_PRESSURE_RANGE
struct libinput_tablet_tool *tool = driver_data->tablet_tool;
if (!tool)
return FALSE;
return libinput_tablet_tool_config_pressure_range_is_available(tool) &&
libinput_tablet_tool_config_pressure_range_set(tool,
range->min,
range->max) == LIBINPUT_CONFIG_STATUS_SUCCESS;
#else
return FALSE;
#endif
}
static inline void
xf86libinput_set_area_ratio(struct xf86libinput *driver_data,
const struct ratio *ratio)
@@ -501,8 +526,10 @@ subdevice_has_capabilities(DeviceIntPtr dev, uint32_t capabilities)
}
static int
LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly);
LibinputSetProperty(DeviceIntPtr dev, Atom atom,
XIPropertyValuePtr val,
BOOL checkonly);
static void
LibinputInitProperty(DeviceIntPtr dev);
@@ -804,6 +831,7 @@ LibinputApplyConfigClickMethod(DeviceIntPtr dev,
struct libinput_device *device)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
uint32_t click_methods = libinput_device_config_click_get_methods(device);
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
@@ -824,6 +852,24 @@ LibinputApplyConfigClickMethod(DeviceIntPtr dev,
"Failed to set click method to %s\n",
method);
}
#if HAVE_LIBINPUT_CLICKFINGER_BUTTON_MAP
if (click_methods & LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER &&
libinput_device_config_click_set_clickfinger_button_map(device,
driver_data->options.clickfinger_button_map) != LIBINPUT_CONFIG_STATUS_SUCCESS) {
const char *map;
switch (driver_data->options.clickfinger_button_map) {
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM: map = "LRM"; break;
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR: map = "LMR"; break;
default:
map = "unknown"; break;
}
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set clickfinger button map to %s\n",
map);
}
#endif
}
static void
@@ -879,6 +925,27 @@ LibinputApplyConfigRotation(DeviceIntPtr dev,
driver_data->options.rotation_angle);
}
static void
LibinputApplyConfigPressureRange(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
#if HAVE_LIBINPUT_PRESSURE_RANGE
InputInfoPtr pInfo = dev->public.devicePrivate;
struct libinput_tablet_tool *tool = driver_data->tablet_tool;
struct range *range = &driver_data->options.pressure_range;
if (!subdevice_has_capabilities(dev, CAP_TABLET_TOOL))
return;
if (tool && libinput_tablet_tool_config_pressure_range_is_available(tool) &&
libinput_tablet_tool_config_pressure_range_set(tool, range->min, range->max) != LIBINPUT_CONFIG_STATUS_SUCCESS)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set PressureRange to %.2f..%.2f\n",
range->min, range->max);
#endif
}
static inline void
LibinputApplyConfig(DeviceIntPtr dev)
{
@@ -897,6 +964,7 @@ LibinputApplyConfig(DeviceIntPtr dev)
LibinputApplyConfigMiddleEmulation(dev, driver_data, device);
LibinputApplyConfigDisableWhileTyping(dev, driver_data, device);
LibinputApplyConfigRotation(dev, driver_data, device);
LibinputApplyConfigPressureRange(dev, driver_data, device);
}
static int
@@ -1098,35 +1166,41 @@ xf86libinput_init_pointer_absolute(InputInfoPtr pInfo)
return Success;
}
static void
xf86libinput_kbd_ctrl(DeviceIntPtr device, KeybdCtrl *ctrl)
{
#define CAPSFLAG 1
#define NUMFLAG 2
#define SCROLLFLAG 4
#define CAPSFLAG 1
#define NUMFLAG 2
#define SCROLLFLAG 4
#define COMPOSEFLAG 8
#define KANAFLAG 16
static struct { int xbit, code; } bits[] = {
{ CAPSFLAG, LIBINPUT_LED_CAPS_LOCK },
{ NUMFLAG, LIBINPUT_LED_NUM_LOCK },
{ SCROLLFLAG, LIBINPUT_LED_SCROLL_LOCK },
#ifdef HAVE_LIBINPUT_COMPOSE_AND_KANA
{ COMPOSEFLAG, LIBINPUT_LED_COMPOSE },
{ KANAFLAG, LIBINPUT_LED_KANA },
#endif
{ 0, 0 },
};
int i = 0;
enum libinput_led leds = 0;
InputInfoPtr pInfo = device->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
struct libinput_device *ldevice = driver_data->shared_device->device;
static struct { int xbit, code; } bits[] = {
{ CAPSFLAG, LIBINPUT_LED_CAPS_LOCK },
{ NUMFLAG, LIBINPUT_LED_NUM_LOCK },
{ SCROLLFLAG, LIBINPUT_LED_SCROLL_LOCK },
{ 0, 0 },
};
int i = 0;
enum libinput_led leds = 0;
InputInfoPtr pInfo = device->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
struct libinput_device *ldevice = driver_data->shared_device->device;
if (!device->enabled)
return;
if (!device->enabled)
return;
while (bits[i].xbit) {
if (ctrl->leds & bits[i].xbit)
leds |= bits[i].code;
i++;
}
while (bits[i].xbit) {
if (ctrl->leds & bits[i].xbit)
leds |= bits[i].code;
i++;
}
libinput_device_led_update(ldevice, leds);
libinput_device_led_update(ldevice, leds);
}
static void
@@ -1320,7 +1394,10 @@ xf86libinput_init_tablet(InputInfoPtr pInfo)
int nbuttons = TABLET_NUM_BUTTONS;
int naxes = 2;
BUG_RETURN(driver_data->tablet_tool == NULL);
if (driver_data->tablet_tool == NULL) {
xf86IDrvMsg(pInfo, X_WARNING, "BUG: tablet_tool is NULL\n");
return;
}
tool = driver_data->tablet_tool;
@@ -1438,7 +1515,10 @@ xf86libinput_init(DeviceIntPtr dev)
struct xf86libinput_device *shared_device = driver_data->shared_device;
struct libinput_device *device = shared_device->device;
BUG_RETURN_VAL(device == NULL, !Success);
if (device == NULL) {
xf86IDrvMsg(pInfo, X_WARNING, "BUG: xf86libinput_init() device is NULL\n");
return !Success;
}
dev->public.on = FALSE;
@@ -1649,6 +1729,14 @@ xf86libinput_handle_key(InputInfoPtr pInfo, struct libinput_event_keyboard *even
if ((driver_data->capabilities & CAP_KEYBOARD) == 0)
return;
/* keycodes > 256 that have a historical mapping in xkeyboard-config */
switch (key) {
case KEY_TOUCHPAD_TOGGLE: key = KEY_F21; break;
case KEY_TOUCHPAD_ON: key = KEY_F22; break;
case KEY_TOUCHPAD_OFF: key = KEY_F23; break;
case KEY_MICMUTE: key = KEY_F20; break;
}
key += XORG_KEYCODE_OFFSET;
is_press = (libinput_event_keyboard_get_key_state(event) == LIBINPUT_KEY_STATE_PRESSED);
@@ -2410,7 +2498,10 @@ xf86libinput_handle_tablet_proximity(InputInfoPtr pInfo,
if (xf86libinput_tool_queue_event(event))
return EVENT_QUEUED;
BUG_RETURN_VAL(pDev == NULL, EVENT_HANDLED);
if (pDev == NULL) {
xf86IDrvMsg(pInfo, X_WARNING, "BUG: xf86libinput_handle_tablet_proximity() pDev is NULL\n");
return EVENT_HANDLED;
}
x = libinput_event_tablet_tool_get_x_transformed(event, TABLET_AXIS_MAX);
y = libinput_event_tablet_tool_get_y_transformed(event, TABLET_AXIS_MAX);
@@ -2654,7 +2745,7 @@ xf86libinput_read_input(InputInfoPtr pInfo)
int rc;
struct libinput_event *event;
rc = libinput_dispatch(libinput);
rc = libinput_dispatch(libinput);
if (rc == -EAGAIN)
return;
@@ -2882,6 +2973,46 @@ xf86libinput_parse_tap_buttonmap_option(InputInfoPtr pInfo,
return map;
}
#if HAVE_LIBINPUT_CLICKFINGER_BUTTON_MAP
static inline enum libinput_config_clickfinger_button_map
xf86libinput_parse_clickfinger_map_option(InputInfoPtr pInfo,
struct libinput_device *device)
{
uint32_t click_methods = libinput_device_config_click_get_methods(device);
enum libinput_config_clickfinger_button_map map;
char *str;
map = libinput_device_config_click_get_clickfinger_button_map(device);
if ((click_methods & LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) == 0)
return map;
str = xf86SetStrOption(pInfo->options,
"ClickfingerButtonMap",
NULL);
if (str) {
if (streq(str, "lmr"))
map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR;
else if (streq(str, "lrm"))
map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM;
else
xf86IDrvMsg(pInfo, X_ERROR,
"Invalid ClickfingerButtonMap: %s\n",
str);
free(str);
}
if (libinput_device_config_click_set_clickfinger_button_map(device, map) !=
LIBINPUT_CONFIG_STATUS_SUCCESS) {
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set Clickfinger Button Map to %d\n",
map);
map = libinput_device_config_click_get_clickfinger_button_map(device);
}
return map;
}
#endif
static inline double
xf86libinput_parse_accel_option(InputInfoPtr pInfo,
struct libinput_device *device)
@@ -3530,6 +3661,46 @@ out:
xf86libinput_set_pressurecurve(driver_data, controls);
}
static void
xf86libinput_parse_pressure_range_option(InputInfoPtr pInfo,
struct xf86libinput *driver_data,
struct range *range)
{
#if HAVE_LIBINPUT_PRESSURE_RANGE
struct libinput_tablet_tool *tool = driver_data->tablet_tool;
float min, max;
char *str;
int rc;
range->min = 0.0;
range->max = 1.0;
if ((driver_data->capabilities & CAP_TABLET_TOOL) == 0)
return;
if (!tool || !libinput_tablet_tool_config_pressure_range_is_available(tool))
return;
str = xf86SetStrOption(pInfo->options,
"TabletToolPressureRange",
NULL);
if (!str)
return;
rc = sscanf(str, "%f %f", &min, &max);
if (rc != 2)
goto out;
if (min < 0.0 || max > 1.0 || min >= max)
goto out;
range->min = min;
range->max = max;
out:
free(str);
#endif
}
static inline bool
want_area_handling(struct xf86libinput *driver_data)
{
@@ -3602,6 +3773,9 @@ xf86libinput_parse_options(InputInfoPtr pInfo,
options->scroll_buttonlock = xf86libinput_parse_scrollbuttonlock_option(pInfo, device);
options->scroll_pixel_distance = xf86libinput_parse_scroll_pixel_distance_option(pInfo, device);
options->click_method = xf86libinput_parse_clickmethod_option(pInfo, device);
#if HAVE_LIBINPUT_CLICKFINGER_BUTTON_MAP
options->clickfinger_button_map = xf86libinput_parse_clickfinger_map_option(pInfo, device);
#endif
options->middle_emulation = xf86libinput_parse_middleemulation_option(pInfo, device);
options->disable_while_typing = xf86libinput_parse_disablewhiletyping_option(pInfo, device);
options->rotation_angle = xf86libinput_parse_rotation_angle_option(pInfo, device);
@@ -3620,6 +3794,7 @@ xf86libinput_parse_options(InputInfoPtr pInfo,
xf86libinput_parse_pressurecurve_option(pInfo,
driver_data,
options->pressurecurve);
xf86libinput_parse_pressure_range_option(pInfo, driver_data, &options->pressure_range);
xf86libinput_parse_tablet_area_option(pInfo,
driver_data,
&options->area);
@@ -4083,6 +4258,8 @@ static Atom prop_scroll_pixel_distance_default;
static Atom prop_click_methods_available;
static Atom prop_click_method_enabled;
static Atom prop_click_method_default;
static Atom prop_clickfinger_buttonmap;
static Atom prop_clickfinger_buttonmap_default;
static Atom prop_middle_emulation;
static Atom prop_middle_emulation_default;
static Atom prop_disable_while_typing;
@@ -4094,12 +4271,16 @@ static Atom prop_mode_groups_rings;
static Atom prop_mode_groups_strips;
static Atom prop_rotation_angle;
static Atom prop_rotation_angle_default;
static Atom prop_pressure_range;
static Atom prop_pressure_range_default;
/* driver properties */
static Atom prop_draglock;
static Atom prop_horiz_scroll;
static Atom prop_pressurecurve;
static Atom prop_area_ratio;
static Atom prop_serial;
static Atom prop_tool_id;
static Atom prop_hires_scroll;
/* general properties */
@@ -4210,7 +4391,8 @@ xf86libinput_check_device(DeviceIntPtr dev,
struct libinput_device *device = driver_data->shared_device->device;
if (device == NULL) {
BUG_WARN(dev->public.on);
if (dev->public.on)
xf86IDrvMsg(pInfo, X_WARNING, "BUG: xf86libinput_check_device() device is on\n");
xf86IDrvMsg(pInfo, X_INFO,
"SetProperty on %u called but device is disabled.\n"
"This driver cannot change properties on a disabled device\n",
@@ -4223,9 +4405,9 @@ xf86libinput_check_device(DeviceIntPtr dev,
static inline int
LibinputSetPropertyTap(DeviceIntPtr dev,
Atom atom,
XIPropertyValuePtr val,
BOOL checkonly)
Atom atom,
XIPropertyValuePtr val,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
@@ -4353,8 +4535,8 @@ LibinputSetPropertyTapButtonmap(DeviceIntPtr dev,
static inline int
LibinputSetPropertyCalibration(DeviceIntPtr dev,
Atom atom,
XIPropertyValuePtr val,
Atom atom,
XIPropertyValuePtr val,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
@@ -4504,6 +4686,8 @@ LibinputSetPropertyAccelPoints(DeviceIntPtr dev,
accel_points = &driver_data->options.accel_points_motion;
else if (atom == prop_accel_points_scroll)
accel_points = &driver_data->options.accel_points_scroll;
else
return BadValue;
for (size_t idx = 0; idx < val->size; idx++)
accel_points->points[idx] = data[idx];
@@ -4556,9 +4740,9 @@ LibinputSetPropertyAccelStep(DeviceIntPtr dev,
static inline int
LibinputSetPropertyNaturalScroll(DeviceIntPtr dev,
Atom atom,
XIPropertyValuePtr val,
BOOL checkonly)
Atom atom,
XIPropertyValuePtr val,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
@@ -4824,6 +5008,46 @@ LibinputSetPropertyClickMethod(DeviceIntPtr dev,
return Success;
}
static inline int
LibinputSetPropertyClickfingerButtonmap(DeviceIntPtr dev,
Atom atom,
XIPropertyValuePtr val,
BOOL checkonly)
{
#if HAVE_LIBINPUT_CLICKFINGER_BUTTON_MAP
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
BOOL* data;
enum libinput_config_clickfinger_button_map map;
if (val->format != 8 || val->size != 2 || val->type != XA_INTEGER)
return BadMatch;
data = (BOOL*)val->data;
if (checkonly) {
if ((data[0] && data[1]) || (!data[0] && !data[1]))
return BadValue;
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
}
if (data[0])
map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM;
else if (data[1])
map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR;
else
return BadValue;
if (!checkonly)
driver_data->options.clickfinger_button_map = map;
#endif
return Success;
}
static inline int
LibinputSetPropertyMiddleEmulation(DeviceIntPtr dev,
Atom atom,
@@ -4916,6 +5140,7 @@ prop_draglock_set_pairs(struct xf86libinput *driver_data,
int data[MAX_BUTTONS + 1] = {0};
int i;
int highest = 0;
const unsigned int max = MAX_BUTTONS;
if (len >= ARRAY_SIZE(data))
return BadMatch;
@@ -4926,7 +5151,7 @@ prop_draglock_set_pairs(struct xf86libinput *driver_data,
dl = (checkonly) ? &dummy : &driver_data->draglock;
for (i = 0; i < len; i += 2) {
if (pairs[i] > MAX_BUTTONS)
if (pairs[i] > max)
return BadValue;
data[pairs[i]] = pairs[i+1];
@@ -5098,6 +5323,42 @@ LibinputSetPropertyPressureCurve(DeviceIntPtr dev,
return Success;
}
static inline int
LibinputSetPropertyPressureRange(DeviceIntPtr dev,
Atom atom,
XIPropertyValuePtr val,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
float *vals;
struct range range = { 0.0, 1.0 };
if (val->format != 32 || val->size != 2 || val->type != prop_float)
return BadMatch;
vals = val->data;
range.min = vals[0];
range.max = vals[1];
if (checkonly) {
if (range.min < 0.0 || range.max > 1.0 || range.min >= range.max)
return BadValue;
/* Disallow reducing the range to less than 20% of the range, mostly
* to avoid footguns */
if (range.max - range.min < 0.2)
return BadValue;
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
} else {
driver_data->options.pressure_range = range;
}
return Success;
}
static inline int
LibinputSetPropertyAreaRatio(DeviceIntPtr dev,
Atom atom,
@@ -5182,8 +5443,9 @@ LibinputSetPropertyHighResolutionScroll(DeviceIntPtr dev,
}
static int
LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly)
LibinputSetProperty(DeviceIntPtr dev, Atom atom,
XIPropertyValuePtr val,
BOOL checkonly)
{
int rc;
@@ -5226,6 +5488,8 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
rc = LibinputSetPropertyScrollButtonLock(dev, atom, val, checkonly);
else if (atom == prop_click_method_enabled)
rc = LibinputSetPropertyClickMethod(dev, atom, val, checkonly);
else if (atom == prop_clickfinger_buttonmap)
rc = LibinputSetPropertyClickfingerButtonmap(dev, atom, val, checkonly);
else if (atom == prop_middle_emulation)
rc = LibinputSetPropertyMiddleEmulation(dev, atom, val, checkonly);
else if (atom == prop_disable_while_typing)
@@ -5249,36 +5513,43 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
rc = LibinputSetPropertyRotationAngle(dev, atom, val, checkonly);
else if (atom == prop_pressurecurve)
rc = LibinputSetPropertyPressureCurve(dev, atom, val, checkonly);
else if (atom == prop_pressure_range)
rc = LibinputSetPropertyPressureRange(dev, atom, val, checkonly);
else if (atom == prop_area_ratio)
rc = LibinputSetPropertyAreaRatio(dev, atom, val, checkonly);
else if (atom == prop_hires_scroll)
rc = LibinputSetPropertyHighResolutionScroll(dev, atom, val, checkonly);
else if (atom == prop_device || atom == prop_product_id ||
atom == prop_tap_default ||
atom == prop_tap_drag_default ||
atom == prop_tap_drag_lock_default ||
atom == prop_tap_buttonmap_default ||
atom == prop_calibration_default ||
atom == prop_accel_default ||
else if (atom == prop_accel_default ||
atom == prop_accel_profile_default ||
atom == prop_natural_scroll_default ||
atom == prop_sendevents_default ||
atom == prop_sendevents_available ||
atom == prop_left_handed_default ||
atom == prop_scroll_method_default ||
atom == prop_scroll_methods_available ||
atom == prop_scroll_button_default ||
atom == prop_scroll_buttonlock_default ||
atom == prop_scroll_pixel_distance_default ||
atom == prop_calibration_default ||
atom == prop_click_method_default ||
atom == prop_click_methods_available ||
atom == prop_middle_emulation_default ||
atom == prop_clickfinger_buttonmap_default ||
atom == prop_disable_while_typing_default ||
atom == prop_left_handed_default ||
atom == prop_middle_emulation_default ||
atom == prop_mode_groups_available ||
atom == prop_mode_groups_buttons ||
atom == prop_mode_groups_rings ||
atom == prop_mode_groups_strips ||
atom == prop_rotation_angle_default)
atom == prop_natural_scroll_default ||
atom == prop_product_id ||
atom == prop_pressure_range_default ||
atom == prop_rotation_angle_default ||
atom == prop_scroll_button_default ||
atom == prop_scroll_buttonlock_default ||
atom == prop_scroll_method_default ||
atom == prop_scroll_methods_available ||
atom == prop_scroll_pixel_distance_default ||
atom == prop_sendevents_available ||
atom == prop_sendevents_default ||
atom == prop_serial ||
atom == prop_tap_buttonmap_default ||
atom == prop_tap_default ||
atom == prop_tap_drag_default ||
atom == prop_tap_drag_lock_default ||
atom == prop_tool_id ||
atom == prop_device)
return BadAccess; /* read-only */
else
return Success;
@@ -5955,6 +6226,63 @@ LibinputInitClickMethodsProperty(DeviceIntPtr dev,
methods);
}
static void
LibinputInitClickfingerButtonmapProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
#if HAVE_LIBINPUT_CLICKFINGER_BUTTON_MAP
enum libinput_config_clickfinger_button_map map;
BOOL data[2] = {0};
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
uint32_t click_methods = libinput_device_config_click_get_methods(device);
if ((click_methods & LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) == 0)
return;
map = driver_data->options.clickfinger_button_map;
switch (map) {
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
data[0] = 1;
break;
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
data[1] = 1;
break;
default:
break;
}
prop_clickfinger_buttonmap = LibinputMakeProperty(dev,
LIBINPUT_PROP_CLICKFINGER_BUTTONMAP,
XA_INTEGER, 8,
2, data);
if (!prop_clickfinger_buttonmap)
return;
map = libinput_device_config_click_get_default_clickfinger_button_map(device);
memset(data, 0, sizeof(data));
switch (map) {
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
data[0] = 1;
break;
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
data[1] = 1;
break;
default:
break;
}
prop_clickfinger_buttonmap_default = LibinputMakeProperty(dev,
LIBINPUT_PROP_CLICKFINGER_BUTTONMAP_DEFAULT,
XA_INTEGER, 8,
2, data);
#endif
}
static void
LibinputInitMiddleEmulationProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
@@ -6248,6 +6576,44 @@ LibinputInitPressureCurveProperty(DeviceIntPtr dev,
8, data);
}
static void
LibinputInitPressureRangeProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data)
{
#if HAVE_LIBINPUT_PRESSURE_RANGE
struct libinput_tablet_tool *tool = driver_data->tablet_tool;
const struct range *range = &driver_data->options.pressure_range;
float data[2] = {
range->min,
range->max,
};
if ((driver_data->capabilities & CAP_TABLET_TOOL) == 0)
return;
if (!tool || !libinput_tablet_tool_config_pressure_range_is_available(tool))
return;
prop_pressure_range = LibinputMakeProperty(dev,
LIBINPUT_PROP_TABLET_TOOL_PRESSURE_RANGE,
prop_float, 32,
2, &data);
if (!prop_pressure_range)
return;
data[0] = libinput_tablet_tool_config_pressure_range_get_default_minimum(tool);
data[1] = libinput_tablet_tool_config_pressure_range_get_default_maximum(tool);
prop_pressure_range_default = LibinputMakeProperty(dev,
LIBINPUT_PROP_TABLET_TOOL_PRESSURE_RANGE_DEFAULT,
prop_float, 32,
2, &data);
if (!prop_pressure_range_default)
return;
#endif
}
static void
LibinputInitTabletAreaRatioProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data)
@@ -6267,6 +6633,36 @@ LibinputInitTabletAreaRatioProperty(DeviceIntPtr dev,
2, data);
}
static void
LibinputInitTabletSerialProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data)
{
struct libinput_tablet_tool *tool = driver_data->tablet_tool;
uint32_t serial, tool_id;
if ((driver_data->capabilities & CAP_TABLET_TOOL) == 0)
return;
if (!tool)
return;
/* Serial prop is always created to indicate when we don't have a serial */
serial = libinput_tablet_tool_get_serial(tool);
prop_serial = LibinputMakeProperty(dev,
LIBINPUT_PROP_TABLET_TOOL_SERIAL,
XA_CARDINAL, 32,
1, &serial);
/* The tool ID prop is only created if we have a known tool id */
tool_id = libinput_tablet_tool_get_tool_id(tool);
if (tool_id) {
prop_tool_id = LibinputMakeProperty(dev,
LIBINPUT_PROP_TABLET_TOOL_ID,
XA_CARDINAL, 32,
1, &tool_id);
}
}
static void
LibinputInitHighResolutionScrollProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
@@ -6303,6 +6699,7 @@ LibinputInitProperty(DeviceIntPtr dev)
LibinputInitDisableWhileTypingProperty(dev, driver_data, device);
LibinputInitScrollMethodsProperty(dev, driver_data, device);
LibinputInitClickMethodsProperty(dev, driver_data, device);
LibinputInitClickfingerButtonmapProperty(dev, driver_data, device);
LibinputInitMiddleEmulationProperty(dev, driver_data, device);
LibinputInitRotationAngleProperty(dev, driver_data, device);
LibinputInitAccelProperty(dev, driver_data, device);
@@ -6341,6 +6738,8 @@ LibinputInitProperty(DeviceIntPtr dev)
LibinputInitHorizScrollProperty(dev, driver_data);
LibinputInitScrollPixelDistanceProperty(dev, driver_data, device);
LibinputInitPressureCurveProperty(dev, driver_data);
LibinputInitPressureRangeProperty(dev, driver_data);
LibinputInitTabletAreaRatioProperty(dev, driver_data);
LibinputInitTabletSerialProperty(dev, driver_data);
LibinputInitHighResolutionScrollProperty(dev, driver_data, device);
}

View File

@@ -233,6 +233,7 @@ test_filter_meta_passthrough(void)
int i;
rc = draglock_init_from_string(&dl, "10");
assert(rc == 0);
for (i = 0; i < 10; i++) {
button = i;
@@ -259,6 +260,7 @@ test_filter_meta_click_meta_only(void)
int button, press;
rc = draglock_init_from_string(&dl, "10");
assert(rc == 0);
button = 10;
press = 1;
@@ -283,6 +285,7 @@ test_filter_meta(void)
int i;
rc = draglock_init_from_string(&dl, "10");
assert(rc == 0);
for (i = 1; i < 10; i++) {
/* meta down */
@@ -339,6 +342,7 @@ test_filter_meta_extra_click(void)
int i;
rc = draglock_init_from_string(&dl, "10");
assert(rc == 0);
for (i = 1; i < 10; i++) {
/* meta down */
@@ -409,6 +413,7 @@ test_filter_meta_interleaved(void)
int i;
rc = draglock_init_from_string(&dl, "10");
assert(rc == 0);
for (i = 1; i < 10; i++) {
/* meta down */
@@ -467,6 +472,7 @@ test_filter_pairs(void)
int i;
rc = draglock_init_from_string(&dl, "1 11 2 0 3 13 4 0 5 15 6 0 7 17 8 0 9 19");
assert(rc == 0);
for (i = 1; i < 10; i++) {
button = i;