mirror of
https://github.com/X11Libre/xf86-input-evdev.git
synced 2026-04-14 11:44:16 +00:00
Implement XSetDeviceMode request handler
Implement XSetDeviceMode request handler for evdev. Devices with absolute axes can be switched in relative mode or absolute mode. Devices with relative axes can be switched only in relative mode. Other devices return BadMatch, cause they have no valuators and don't report motion events. New option "Mode" force devices with absolute axes to work in relative or absolute mode. Need xinputproto. Signed-off-by: Andrej Gelenberg <andrej.gelenberg@udo.edu>
This commit is contained in:
committed by
Peter Hutterer
parent
0b5844ce67
commit
e81cd935cf
@@ -55,6 +55,9 @@ AC_ARG_WITH(xorg-module-dir,
|
||||
inputdir=${moduledir}/input
|
||||
AC_SUBST(inputdir)
|
||||
|
||||
# Checks for extensions
|
||||
XORG_DRIVER_CHECK_EXT(XINPUT, inputproto)
|
||||
|
||||
# Checks for pkg-config packages. We need to be able to override sdkdir
|
||||
# to satisfy silly distcheck requirements.
|
||||
PKG_CHECK_MODULES(XORG, xorg-server xproto $REQUIRED_MODULES)
|
||||
|
||||
@@ -159,6 +159,11 @@ originally reported by the kernel (e.g. touchscreens). The scaling to the
|
||||
custom coordinate system is done in-driver and the X server is unaware of
|
||||
the transformation. Property: "Evdev Axis Calibration".
|
||||
.TP 7
|
||||
.B Option \*qMode\*q \*qRelative\*q\fP|\fP\*qAbsolute\*q
|
||||
Sets the mode of the device if device has absolute axes.
|
||||
The default value for touchpads is relative, for other absolute.
|
||||
This option has no effect on devices without absolute axes.
|
||||
.TP 7
|
||||
.BI "Option \*qSwapAxes\*q \*q" Bool \*q
|
||||
Swap x/y axes. Default: off. Property: "Evdev Axes Swap".
|
||||
.TP 7
|
||||
|
||||
56
src/evdev.c
56
src/evdev.c
@@ -32,6 +32,7 @@
|
||||
#endif
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/extensions/XI.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
@@ -92,6 +93,7 @@
|
||||
#define EVDEV_TABLET (1 << 8) /* device looks like a tablet? */
|
||||
#define EVDEV_UNIGNORE_ABSOLUTE (1 << 9) /* explicitly unignore abs axes */
|
||||
#define EVDEV_UNIGNORE_RELATIVE (1 << 10) /* explicitly unignore rel axes */
|
||||
#define EVDEV_RELATIVE_MODE (1 << 11) /* Force relative events for devices with absolute axes */
|
||||
|
||||
#define MIN_KEYCODE 8
|
||||
#define GLYPHS_PER_KEY 2
|
||||
@@ -117,6 +119,7 @@ static const char *evdevDefaults[] = {
|
||||
static int EvdevOn(DeviceIntPtr);
|
||||
static int EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare);
|
||||
static void EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl);
|
||||
static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode);
|
||||
|
||||
#ifdef HAVE_PROPERTIES
|
||||
static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
|
||||
@@ -136,6 +139,38 @@ static Atom prop_btn_label = 0;
|
||||
* cannot be used by evdev, leaving us with a space of 2 at the end. */
|
||||
static EvdevPtr evdev_devices[MAXDEVICES] = {NULL};
|
||||
|
||||
static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode)
|
||||
{
|
||||
InputInfoPtr pInfo;
|
||||
EvdevPtr pEvdev;
|
||||
|
||||
pInfo = device->public.devicePrivate;
|
||||
pEvdev = pInfo->private;
|
||||
|
||||
if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
|
||||
{
|
||||
if (mode == Relative)
|
||||
return Success;
|
||||
else
|
||||
return XI_BadMode;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case Absolute:
|
||||
pEvdev->flags &= ~EVDEV_RELATIVE_MODE;
|
||||
break;
|
||||
|
||||
case Relative:
|
||||
pEvdev->flags |= EVDEV_RELATIVE_MODE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return XI_BadMode;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static size_t CountBits(unsigned long *array, size_t nlongs)
|
||||
{
|
||||
unsigned int i;
|
||||
@@ -341,7 +376,7 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
|
||||
*num_v = *first_v = 0;
|
||||
|
||||
/* convert to relative motion for touchpads */
|
||||
if (pEvdev->abs && (pEvdev->flags & EVDEV_TOUCHPAD)) {
|
||||
if (pEvdev->abs && (pEvdev->flags & EVDEV_RELATIVE_MODE)) {
|
||||
if (pEvdev->tool) { /* meaning, touch is active */
|
||||
if (pEvdev->old_vals[0] != -1)
|
||||
pEvdev->delta[REL_X] = pEvdev->vals[0] - pEvdev->old_vals[0];
|
||||
@@ -1129,6 +1164,7 @@ EvdevAddAbsClass(DeviceIntPtr device)
|
||||
EvdevPtr pEvdev;
|
||||
int num_axes, axis, i = 0;
|
||||
Atom *atoms;
|
||||
const char *mode;
|
||||
|
||||
pInfo = device->public.devicePrivate;
|
||||
pEvdev = pInfo->private;
|
||||
@@ -1200,6 +1236,22 @@ EvdevAddAbsClass(DeviceIntPtr device)
|
||||
TestBit(ABS_TILT_Y, pEvdev->abs_bitmask)))
|
||||
pInfo->flags |= XI86_POINTER_CAPABLE;
|
||||
|
||||
if (pEvdev->flags & EVDEV_TOUCHPAD)
|
||||
pEvdev->flags |= EVDEV_RELATIVE_MODE;
|
||||
else
|
||||
pEvdev->flags &= ~EVDEV_RELATIVE_MODE;
|
||||
|
||||
if (xf86FindOption(pInfo->options, "Mode"))
|
||||
{
|
||||
mode = xf86SetStrOption(pInfo->options, "Mode", NULL);
|
||||
if (!strcasecmp("absolute", mode))
|
||||
pEvdev->flags &= ~EVDEV_RELATIVE_MODE;
|
||||
else if (!strcasecmp("relative", mode))
|
||||
pEvdev->flags |= EVDEV_RELATIVE_MODE;
|
||||
else
|
||||
xf86Msg(X_INFO, "%s: unknown mode, use default\n", pInfo->name);
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
@@ -1966,7 +2018,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
|
||||
pInfo->history_size = 0;
|
||||
pInfo->control_proc = NULL;
|
||||
pInfo->close_proc = NULL;
|
||||
pInfo->switch_mode = NULL;
|
||||
pInfo->switch_mode = EvdevSwitchMode;
|
||||
pInfo->conversion_proc = NULL;
|
||||
pInfo->reverse_conversion_proc = NULL;
|
||||
pInfo->dev = NULL;
|
||||
|
||||
Reference in New Issue
Block a user