mirror of
https://github.com/X11Libre/xf86-input-evdev.git
synced 2026-04-14 11:44:16 +00:00
Compare commits
9 Commits
xf86-input
...
xf86-input
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ef4e2c5e1 | ||
|
|
dd0eeacc24 | ||
|
|
67c0ea6c94 | ||
|
|
6bcbbc0411 | ||
|
|
534a3734d0 | ||
|
|
215c230d5c | ||
|
|
8f96530449 | ||
|
|
4fb97edcd4 | ||
|
|
4e86393bc0 |
@@ -22,7 +22,7 @@
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([xf86-input-evdev],
|
||||
2.0.99.2,
|
||||
2.0.99.3,
|
||||
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
|
||||
xf86-input-evdev)
|
||||
|
||||
|
||||
@@ -58,4 +58,12 @@
|
||||
/* CARD8 */
|
||||
#define EVDEV_PROP_REOPEN "Evdev Reopen Attempts"
|
||||
|
||||
/* Run-time calibration */
|
||||
/* CARD32, 4 values [minx, maxx, miny, maxy], or no values for unset */
|
||||
#define EVDEV_PROP_CALIBRATION "Evdev Axis Calibration"
|
||||
|
||||
/* Swap x and y axis. */
|
||||
/* BOOL */
|
||||
#define EVDEV_PROP_SWAP_AXES "Evdev Axes Swap"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -147,6 +147,9 @@ waking up from suspend). In between each attempt is a 100ms wait. Default: 10.
|
||||
.BI "Option \*qInvertY\*q \*q" Bool \*q
|
||||
Invert the given axis. Default: off. Property: "Evdev Axis Inversion".
|
||||
.TP 7
|
||||
.BI "Option \*qSwapAxes\*q \*q" Bool \*q
|
||||
Swap x/y axes. Default: off. Property: "Evdev Axes Swap".
|
||||
.TP 7
|
||||
.BI "Option \*qGrabDevice\*q \*q" boolean \*q
|
||||
Force a grab on the event device. Doing so will ensure that no other driver
|
||||
can initialise the same device and it will also stop the device from sending
|
||||
@@ -186,6 +189,14 @@ value.
|
||||
.TP 7
|
||||
.BI "Evdev Axis Inversion"
|
||||
2 boolean values (8 bit, 0 or 1), order X, Y. 1 inverts the axis.
|
||||
.BI "Evdev Axis Calibration"
|
||||
4 32-bit values, order min-x, max-x, min-y, max-y or 0 values to disable
|
||||
run-time axis calibration. This feature is required for devices that need to
|
||||
scale to a different coordinate system than originally reported to the X
|
||||
server, such as touchscreens that require run-time calibration.
|
||||
.TP 7
|
||||
.BI "Evdev Axis Swap"
|
||||
1 boolean values (8 bit, 0 or 1). 1 swaps x/y axes.
|
||||
|
||||
.SH AUTHORS
|
||||
Kristian Høgsberg.
|
||||
|
||||
@@ -311,12 +311,17 @@ EvdevMBEmuPreInit(InputInfoPtr pInfo)
|
||||
pEvdev->emulateMB.enabled = xf86SetBoolOption(pInfo->options,
|
||||
"Emulate3Buttons",
|
||||
MBEMU_ENABLED);
|
||||
xf86Msg(X_INFO, "%s: Forcing middle mouse button emulation.\n",
|
||||
pInfo->name);
|
||||
xf86Msg(X_INFO, "%s: Forcing middle mouse button emulation %s.\n",
|
||||
pInfo->name, (pEvdev->emulateMB.enabled) ? "on" : "off");
|
||||
}
|
||||
|
||||
pEvdev->emulateMB.timeout = xf86SetIntOption(pInfo->options,
|
||||
"Emulate3Timeout", 50);
|
||||
}
|
||||
|
||||
void
|
||||
EvdevMBEmuOn(InputInfoPtr pInfo)
|
||||
{
|
||||
RegisterBlockAndWakeupHandlers (EvdevMBEmuBlockHandler,
|
||||
EvdevMBEmuWakeupHandler,
|
||||
(pointer)pInfo);
|
||||
|
||||
117
src/evdev.c
117
src/evdev.c
@@ -76,6 +76,7 @@
|
||||
#define EVDEV_TOUCHPAD (1 << 4)
|
||||
#define EVDEV_INITIALIZED (1 << 5) /* WheelInit etc. called already? */
|
||||
#define EVDEV_TOUCHSCREEN (1 << 6)
|
||||
#define EVDEV_CALIBRATED (1 << 7) /* run-time calibrated? */
|
||||
|
||||
#define MIN_KEYCODE 8
|
||||
#define GLYPHS_PER_KEY 2
|
||||
@@ -107,6 +108,8 @@ static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
|
||||
XIPropertyValuePtr val, BOOL checkonly);
|
||||
static Atom prop_invert = 0;
|
||||
static Atom prop_reopen = 0;
|
||||
static Atom prop_calibration = 0;
|
||||
static Atom prop_swap = 0;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -225,13 +228,14 @@ EvdevReadInput(InputInfoPtr pInfo)
|
||||
{
|
||||
struct input_event ev;
|
||||
int len, value;
|
||||
int dx, dy;
|
||||
int dx, dy, tmp;
|
||||
unsigned int abs;
|
||||
unsigned int button;
|
||||
EvdevPtr pEvdev = pInfo->private;
|
||||
|
||||
dx = 0;
|
||||
dy = 0;
|
||||
tmp = 0;
|
||||
abs = 0;
|
||||
|
||||
while (xf86WaitForInput (pInfo->fd, 0) > 0) {
|
||||
@@ -326,7 +330,7 @@ EvdevReadInput(InputInfoPtr pInfo)
|
||||
/* Intentional fallthrough! */
|
||||
|
||||
default:
|
||||
button = EvdevUtilButtonEventToButtonNumber(ev.code);
|
||||
button = EvdevUtilButtonEventToButtonNumber(pEvdev, ev.code);
|
||||
|
||||
/* Handle drag lock */
|
||||
if (EvdevDragLockFilterEvent(pInfo, button, value))
|
||||
@@ -367,6 +371,11 @@ EvdevReadInput(InputInfoPtr pInfo)
|
||||
}
|
||||
|
||||
if (dx != 0 || dy != 0) {
|
||||
if (pEvdev->swap_axes) {
|
||||
tmp = dx;
|
||||
dx = dy;
|
||||
dy = tmp;
|
||||
}
|
||||
if (pEvdev->invert_x)
|
||||
dx *= -1;
|
||||
if (pEvdev->invert_y)
|
||||
@@ -385,12 +394,23 @@ EvdevReadInput(InputInfoPtr pInfo)
|
||||
*/
|
||||
if (abs && pEvdev->tool) {
|
||||
int abs_x, abs_y;
|
||||
abs_x = pEvdev->abs_x;
|
||||
abs_y = pEvdev->abs_y;
|
||||
abs_x = (pEvdev->swap_axes) ? pEvdev->abs_y : pEvdev->abs_x;
|
||||
abs_y = (pEvdev->swap_axes) ? pEvdev->abs_x : pEvdev->abs_y;
|
||||
|
||||
if (pEvdev->flags & EVDEV_CALIBRATED)
|
||||
{
|
||||
abs_x = xf86ScaleAxis(abs_x,
|
||||
pEvdev->max_x, pEvdev->min_x,
|
||||
pEvdev->calibration.max_x, pEvdev->calibration.min_x);
|
||||
abs_y = xf86ScaleAxis(abs_y,
|
||||
pEvdev->max_y, pEvdev->min_y,
|
||||
pEvdev->calibration.max_y, pEvdev->calibration.min_y);
|
||||
}
|
||||
|
||||
if (pEvdev->invert_x)
|
||||
abs_x = pEvdev->max_x - abs_x;
|
||||
abs_x = pEvdev->max_x - (abs_x - pEvdev->min_x);
|
||||
if (pEvdev->invert_y)
|
||||
abs_y = pEvdev->max_y - abs_y;
|
||||
abs_y = pEvdev->max_y - (abs_y - pEvdev->min_y);
|
||||
|
||||
xf86PostMotionEvent(pInfo->dev, TRUE, 0, 2, abs_x, abs_y);
|
||||
}
|
||||
@@ -404,9 +424,6 @@ EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
|
||||
/* Nothing to do, dix handles all settings */
|
||||
}
|
||||
|
||||
/* FIXME: this map works with evdev keyboards, but all the xkb maps
|
||||
* probably don't. The easiest is to remap the event keycodes. */
|
||||
|
||||
static KeySym map[] = {
|
||||
/* 0x00 */ NoSymbol, NoSymbol,
|
||||
/* 0x01 */ XK_Escape, NoSymbol,
|
||||
@@ -1007,7 +1024,9 @@ EvdevOn(DeviceIntPtr device)
|
||||
pEvdev->reopen_timer = TimerSet(NULL, 0, 100, EvdevReopenTimer, pInfo);
|
||||
} else
|
||||
{
|
||||
xf86FlushInput(pInfo->fd);
|
||||
xf86AddEnabledDevice(pInfo);
|
||||
EvdevMBEmuOn(pInfo);
|
||||
pEvdev->flags |= EVDEV_INITIALIZED;
|
||||
device->public.on = TRUE;
|
||||
}
|
||||
@@ -1370,6 +1389,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
|
||||
pEvdev->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10);
|
||||
pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE);
|
||||
pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
|
||||
pEvdev->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE);
|
||||
|
||||
/* Grabbing the event device stops in-kernel event forwarding. In other
|
||||
words, it disables rfkill and the "Macintosh mouse button emulation".
|
||||
@@ -1449,7 +1469,7 @@ _X_EXPORT XF86ModuleData evdevModuleData =
|
||||
* returns 0 on non-button event.
|
||||
*/
|
||||
unsigned int
|
||||
EvdevUtilButtonEventToButtonNumber(int code)
|
||||
EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code)
|
||||
{
|
||||
unsigned int button = 0;
|
||||
|
||||
@@ -1466,6 +1486,21 @@ EvdevUtilButtonEventToButtonNumber(int code)
|
||||
button = 2;
|
||||
break;
|
||||
|
||||
/* Treat BTN_[0-2] as LMR buttons on devices that do not advertise
|
||||
BTN_LEFT, BTN_MIDDLE, BTN_RIGHT.
|
||||
Otherwise, treat BTN_[0+n] as button 5+n.
|
||||
XXX: This causes duplicate mappings for BTN_0 + n and BTN_SIDE + n
|
||||
*/
|
||||
case BTN_0:
|
||||
button = (TestBit(BTN_LEFT, pEvdev->key_bitmask)) ? 8 : 1;
|
||||
break;
|
||||
case BTN_1:
|
||||
button = (TestBit(BTN_MIDDLE, pEvdev->key_bitmask)) ? 9 : 2;
|
||||
break;
|
||||
case BTN_2:
|
||||
button = (TestBit(BTN_RIGHT, pEvdev->key_bitmask)) ? 10 : 3;
|
||||
break;
|
||||
|
||||
case BTN_SIDE:
|
||||
case BTN_EXTRA:
|
||||
case BTN_FORWARD:
|
||||
@@ -1476,8 +1511,12 @@ EvdevUtilButtonEventToButtonNumber(int code)
|
||||
|
||||
default:
|
||||
if ((code > BTN_TASK) && (code < KEY_OK)) {
|
||||
if (code < BTN_JOYSTICK)
|
||||
button = (code - BTN_LEFT + 5);
|
||||
if (code < BTN_JOYSTICK) {
|
||||
if (code < BTN_MOUSE)
|
||||
button = (code - BTN_0 + 5);
|
||||
else
|
||||
button = (code - BTN_LEFT + 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1524,6 +1563,26 @@ EvdevInitProperty(DeviceIntPtr dev)
|
||||
return;
|
||||
|
||||
XISetDevicePropertyDeletable(dev, prop_reopen, FALSE);
|
||||
|
||||
|
||||
prop_calibration = MakeAtom(EVDEV_PROP_CALIBRATION,
|
||||
strlen(EVDEV_PROP_CALIBRATION), TRUE);
|
||||
rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER, 32,
|
||||
PropModeReplace, 0, NULL, FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
|
||||
XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
|
||||
|
||||
prop_swap = MakeAtom(EVDEV_PROP_SWAP_AXES,
|
||||
strlen(EVDEV_PROP_SWAP_AXES), TRUE);
|
||||
|
||||
rc = XIChangeDeviceProperty(dev, prop_swap, XA_INTEGER, 8,
|
||||
PropModeReplace, 1, &pEvdev->swap_axes, FALSE);
|
||||
if (rc != Success)
|
||||
return;
|
||||
|
||||
XISetDevicePropertyDeletable(dev, prop_swap, FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1552,6 +1611,40 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
|
||||
|
||||
if (!checkonly)
|
||||
pEvdev->reopen_attempts = *((CARD8*)val->data);
|
||||
} else if (atom == prop_calibration)
|
||||
{
|
||||
if (val->format != 32 || val->type != XA_INTEGER)
|
||||
return BadMatch;
|
||||
if (val->size != 4 && val->size != 0)
|
||||
return BadMatch;
|
||||
|
||||
if (!checkonly)
|
||||
{
|
||||
if (val->size == 0)
|
||||
{
|
||||
pEvdev->flags &= ~EVDEV_CALIBRATED;
|
||||
pEvdev->calibration.min_x = 0;
|
||||
pEvdev->calibration.max_x = 0;
|
||||
pEvdev->calibration.min_y = 0;
|
||||
pEvdev->calibration.max_y = 0;
|
||||
} else if (val->size == 4)
|
||||
{
|
||||
CARD32 *vals = (CARD32*)val->data;
|
||||
|
||||
pEvdev->flags |= EVDEV_CALIBRATED;
|
||||
pEvdev->calibration.min_x = vals[0];
|
||||
pEvdev->calibration.max_x = vals[1];
|
||||
pEvdev->calibration.min_y = vals[2];
|
||||
pEvdev->calibration.max_y = vals[3];
|
||||
}
|
||||
}
|
||||
} else if (atom == prop_swap)
|
||||
{
|
||||
if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
|
||||
return BadMatch;
|
||||
|
||||
if (!checkonly)
|
||||
pEvdev->swap_axes = *((BOOL*)val->data);
|
||||
}
|
||||
|
||||
return Success;
|
||||
|
||||
11
src/evdev.h
11
src/evdev.h
@@ -64,6 +64,7 @@ typedef struct {
|
||||
int flags;
|
||||
int tool;
|
||||
int buttons; /* number of buttons */
|
||||
BOOL swap_axes;
|
||||
BOOL invert_x;
|
||||
BOOL invert_y;
|
||||
|
||||
@@ -102,6 +103,13 @@ typedef struct {
|
||||
Time expires; /* time of expiry */
|
||||
Time timeout;
|
||||
} emulateWheel;
|
||||
/* run-time calibration */
|
||||
struct {
|
||||
int min_x;
|
||||
int max_x;
|
||||
int min_y;
|
||||
int max_y;
|
||||
} calibration;
|
||||
|
||||
unsigned char btnmap[32]; /* config-file specified button mapping */
|
||||
|
||||
@@ -119,7 +127,7 @@ typedef struct {
|
||||
struct input_absinfo absinfo[ABS_MAX];
|
||||
} EvdevRec, *EvdevPtr;
|
||||
|
||||
unsigned int EvdevUtilButtonEventToButtonNumber(int code);
|
||||
unsigned int EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code);
|
||||
|
||||
/* Middle Button emulation */
|
||||
int EvdevMBEmuTimer(InputInfoPtr);
|
||||
@@ -127,6 +135,7 @@ BOOL EvdevMBEmuFilterEvent(InputInfoPtr, int, BOOL);
|
||||
void EvdevMBEmuWakeupHandler(pointer, int, pointer);
|
||||
void EvdevMBEmuBlockHandler(pointer, struct timeval**, pointer);
|
||||
void EvdevMBEmuPreInit(InputInfoPtr);
|
||||
void EvdevMBEmuOn(InputInfoPtr);
|
||||
void EvdevMBEmuFinalize(InputInfoPtr);
|
||||
void EvdevMBEmuEnable(InputInfoPtr, BOOL);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user