Compare commits

...

19 Commits

Author SHA1 Message Date
Peter Hutterer
11d506dce6 evdev 2.1.1 2009-01-13 11:36:14 +10:00
Michael Chapman
a34a2cd347 Disable middle mouse button emulation when a middle mouse button event is registered
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 0592d97fbb)
2009-01-13 11:36:14 +10:00
Matt Helsley
78c00bd77f Fix FOO_MAX off-by-one
In linux/input.h each section's (e.g. ABS) FOO_MAX is the maximum FOO
value. Recent kernels define FOO_CNT as the maximum number of FOO there
will ever be. Hence using FOO_MAX to size the bit vectors representing
the capabilities of an evdev device is off by one.

Define FOO_CNT values for use with Linux kernels which lack them. Use
FOO_CNT whenever we need to know the number of bits needed -- usually to
calculate the number of longs needed.

When iterating over the values FOO_MAX still seems appropriate however
the loop test should include FOO_MAX rather than skip it.

Signed-off-by: Matt Helsley <matt.helsley@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 4dfd86b220)

Conflicts:

	src/evdev.c
2009-01-13 11:36:13 +10:00
Matt Helsley
760f1c6bb1 rename NBITS to NLONGS to reflect its actual meaning
NBITS really convers the number of bits passed as its argument
into a number of longs. This is somewhat atypical of many
function-like-macro names. Rename it to NLONGS.

Signed-off-by: Matt Helsley <matt.helsley@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

(cherry-picked from commit d3fd42d864)
Not really required, but it makes cherry-picking
4dfd86b220 easier.
2009-01-13 11:36:13 +10:00
Alan Coopersmith
2db04ba3c3 Remove xorgconfig & xorgcfg from See Also list in man page
(cherry picked from commit 0f0a149067)
2009-01-13 11:36:13 +10:00
Yan Li
363d0bdb9f Fix XkbModel parsing error
Signed-off-by: Yan Li <yan.i.li@intel.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit d170cba0cd)
2009-01-13 11:36:13 +10:00
Peter Hutterer
16a26a1eca Finalize MB emu (and wakeup handlers) before closing the fd.
Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
(cherry picked from commit 2bf6e29b40)
2009-01-13 11:36:13 +10:00
Peter Hutterer
b879ae7351 evdev 2.1 2008-11-18 15:21:01 +10:00
Peter Hutterer
53566b7d4d Store device file's minor/major to avoid duplicate devices.
Devices added that use the same min/maj as an already added device are ignored
by the driver. This way users can have an xorg.conf entry on
/dev/input/by-id/blahblah and not get the same device added by HAL.

Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
(cherry picked from commit 63af314368)
2008-11-18 15:13:34 +10:00
Fernando Carrijo
29c2765fc3 Fix error message
(cherry picked from commit 4c5c9c111d)
2008-11-11 14:37:45 +10:00
Peter Hutterer
7ef4e2c5e1 evdev 2.1 RC 3
That's it, no more new features. Now it's down to bugfixing only.
2008-11-03 13:47:15 +10:30
Peter Hutterer
dd0eeacc24 Add support for axes swapping.
New option: SwapAxes (boolean)
New property: EVDEV_PROP_SWAP_AXES.

Actual swapping code written by Donnie Berkholz.

Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
(cherry picked from commit 4826969f23)
2008-11-03 13:46:40 +10:30
Peter Hutterer
67c0ea6c94 Add support for run-time calibration.
Some devices require run-time axis calibration. We can't change the min/max
ranges once we've initialised the valuator structs though, so in-driver
run-time calibration is required.

If the property is set, the driver scales from the calibrated range to the
values reported to the X server (which then may scale to screen coordinates).
If the property is not set (i.e. zero items) no scaling is performed.
(cherry picked from commit 33eb36f266)
2008-11-03 13:46:39 +10:30
Peter Hutterer
6bcbbc0411 Treat BTN_[0-2] as LMR buttons if necessary.
Treat BTN_[0-2] as LMR buttons on devices that do not advertise BTN_LEFT,
BTN_MIDDLE, BTN_RIGHT (e.g. 3Dconnexion SpaceNavigator).

Otherwise, treat BTN_[0+n] as button 5+n. Note: This causes duplicate
mappings for BTN_0 + n and  BTN_SIDE + n.

This also fixes a bug where we could end up with negative button numbers after
trying to map BTN_0.

Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
(cherry picked from commit 64554e4799)
2008-11-03 13:46:35 +10:30
Peter Hutterer
534a3734d0 Remove obsolete FIXME
xkeyboard-config's maps are perfectly able to cope with evdev now.

Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
(cherry picked from commit b77f939857)
2008-11-03 13:46:35 +10:30
Peter Hutterer
215c230d5c Flush input after re-opening the fd.
Suggested by Julien Cristau.

Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
(cherry picked from commit a43ab4999b)
2008-11-03 13:46:33 +10:30
Peter Hutterer
8f96530449 emuMB: add EvdevMBEmuOn and call from EvdevOn to register wakeup handlers.
This got broken in b0737bdbd1, when the
EmuMBPreInit call was removed from EvdevOn. As a result, VT switching away and
back wouldn't restore the wakeup handlers and mouse button presses
disappeared.
(cherry picked from commit af096e8c5d)
2008-11-03 13:46:31 +10:30
Peter Hutterer
4fb97edcd4 Fix axis inversion for absolute coordinates.
If min_x/y was not equal to 0, the inverted calculated range was off and leads
to inaccessible or out-of-range areas.
(cherry picked from commit 12498042fc)
2008-11-03 13:46:25 +10:30
Peter Hutterer
4e86393bc0 emulate MB: fix confusing log message.
If we're forcing MB emulation behaviour as per config, then at least state
whether we're forcing it off or on.

Found by Michel Dänzer.
(cherry picked from commit 0f8fcfccb3)
2008-11-03 13:46:17 +10:30
6 changed files with 305 additions and 38 deletions

View File

@@ -22,7 +22,7 @@
AC_PREREQ(2.57)
AC_INIT([xf86-input-evdev],
2.0.99.2,
2.1.1,
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
xf86-input-evdev)

View File

@@ -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

View File

@@ -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,9 +189,17 @@ 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.
.SH "SEE ALSO"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__),
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__),
README.mouse.

View File

@@ -231,6 +231,11 @@ EvdevMBEmuFilterEvent(InputInfoPtr pInfo, int button, BOOL press)
if (!pEvdev->emulateMB.enabled)
return ret;
if (button == 2) {
EvdevMBEmuEnable(pInfo, FALSE);
return ret;
}
/* don't care about other buttons */
if (button != 1 && button != 3)
return ret;
@@ -311,12 +316,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);

View File

@@ -32,6 +32,7 @@
#include <X11/keysym.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
@@ -51,6 +52,10 @@
#include <evdev-properties.h>
#endif
#ifndef MAXDEVICES
#include <inputstr.h> /* for MAX_DEVICES */
#define MAXDEVICES MAX_DEVICES
#endif
/* 2.4 compatibility */
#ifndef EVIOCGRAB
@@ -76,6 +81,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,8 +113,92 @@ 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
/* All devices the evdev driver has allocated and knows about.
* MAXDEVICES is safe as null-terminated array, as two devices (VCP and VCK)
* cannot be used by evdev, leaving us with a space of 2 at the end. */
static EvdevPtr evdev_devices[MAXDEVICES] = {0};
static int
EvdevGetMajorMinor(InputInfoPtr pInfo)
{
struct stat st;
if (fstat(pInfo->fd, &st) == -1)
{
xf86Msg(X_ERROR, "%s: stat failed (%s). cannot check for duplicates.\n",
pInfo->name, strerror(errno));
return 0;
}
return st.st_rdev;
}
/**
* Return TRUE if one of the devices we know about has the same min/maj
* number.
*/
static BOOL
EvdevIsDuplicate(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
EvdevPtr* dev = evdev_devices;
if (pEvdev->min_maj)
{
while(*dev)
{
if ((*dev) != pEvdev &&
(*dev)->min_maj &&
(*dev)->min_maj == pEvdev->min_maj)
return TRUE;
dev++;
}
}
return FALSE;
}
/**
* Add to internal device list.
*/
static void
EvdevAddDevice(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
EvdevPtr* dev = evdev_devices;
while(*dev)
dev++;
*dev = pEvdev;
}
/**
* Remove from internal device list.
*/
static void
EvdevRemoveDevice(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
EvdevPtr *dev = evdev_devices;
int count = 0;
while(*dev)
{
count++;
if (*dev == pEvdev)
{
memmove(dev, dev + 1,
sizeof(evdev_devices) - (count * sizeof(EvdevPtr)));
break;
}
dev++;
}
}
static void
SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
@@ -146,7 +236,7 @@ static void
PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
{
int code = ev->code + MIN_KEYCODE;
static char warned[KEY_MAX];
static char warned[KEY_CNT];
/* filter repeat events for chording keys */
if (value == 2 &&
@@ -158,7 +248,7 @@ PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
ev->code == KEY_SCROLLLOCK)) /* XXX windows keys? */
return;
if (code > 255 && ev->code < KEY_MAX) {
if (code > 255 && ev->code <= KEY_MAX) {
if (!warned[ev->code])
xf86Msg(X_WARNING, "%s: unable to handle keycode %d\n",
pInfo->name, ev->code);
@@ -202,6 +292,7 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
DisableDevice(pInfo->dev);
close(pInfo->fd);
pInfo->fd = -1;
pEvdev->min_maj = 0; /* don't hog the device */
}
pEvdev->reopen_left = 0;
return 0;
@@ -214,6 +305,7 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
xf86Msg(X_ERROR, "%s: Failed to reopen device after %d attempts.\n",
pInfo->name, pEvdev->reopen_attempts);
DisableDevice(pInfo->dev);
pEvdev->min_maj = 0; /* don't hog the device */
return 0;
}
@@ -225,13 +317,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 +419,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 +460,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 +483,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 +513,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,
@@ -748,7 +854,7 @@ EvdevAddKeyClass(DeviceIntPtr device)
SetXkbOption(pInfo, "xkb_rules", &pEvdev->xkb_rules);
SetXkbOption(pInfo, "xkb_model", &pEvdev->xkb_model);
if (!pEvdev->xkb_model)
SetXkbOption(pInfo, "XkbModel", &pEvdev->xkb_rules);
SetXkbOption(pInfo, "XkbModel", &pEvdev->xkb_model);
SetXkbOption(pInfo, "xkb_layout", &pEvdev->xkb_layout);
if (!pEvdev->xkb_layout)
SetXkbOption(pInfo, "XkbLayout", &pEvdev->xkb_layout);
@@ -1007,7 +1113,17 @@ EvdevOn(DeviceIntPtr device)
pEvdev->reopen_timer = TimerSet(NULL, 0, 100, EvdevReopenTimer, pInfo);
} else
{
pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
if (EvdevIsDuplicate(pInfo))
{
xf86Msg(X_WARNING, "%s: Refusing to enable duplicate device.\n",
pInfo->name);
return !Success;
}
xf86FlushInput(pInfo->fd);
xf86AddEnabledDevice(pInfo);
EvdevMBEmuOn(pInfo);
pEvdev->flags |= EVDEV_INITIALIZED;
device->public.on = TRUE;
}
@@ -1034,6 +1150,8 @@ EvdevProc(DeviceIntPtr device, int what)
return EvdevOn(device);
case DEVICE_OFF:
if (pEvdev->flags & EVDEV_INITIALIZED)
EvdevMBEmuFinalize(pInfo);
if (pInfo->fd != -1)
{
if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
@@ -1043,6 +1161,7 @@ EvdevProc(DeviceIntPtr device, int what)
close(pInfo->fd);
pInfo->fd = -1;
}
pEvdev->min_maj = 0;
if (pEvdev->flags & EVDEV_INITIALIZED)
EvdevMBEmuFinalize(pInfo);
pEvdev->flags &= ~EVDEV_INITIALIZED;
@@ -1060,6 +1179,8 @@ EvdevProc(DeviceIntPtr device, int what)
close(pInfo->fd);
pInfo->fd = -1;
}
EvdevRemoveDevice(pInfo);
pEvdev->min_maj = 0;
break;
}
@@ -1081,12 +1202,12 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
int i;
char name[1024] = {0};
long bitmask[NBITS(EV_MAX)] = {0};
long key_bitmask[NBITS(KEY_MAX)] = {0};
long rel_bitmask[NBITS(REL_MAX)] = {0};
long abs_bitmask[NBITS(ABS_MAX)] = {0};
long led_bitmask[NBITS(LED_MAX)] = {0};
struct input_absinfo absinfo[ABS_MAX];
long bitmask[NLONGS(EV_CNT)] = {0};
long key_bitmask[NLONGS(KEY_CNT)] = {0};
long rel_bitmask[NLONGS(REL_CNT)] = {0};
long abs_bitmask[NLONGS(ABS_CNT)] = {0};
long led_bitmask[NLONGS(LED_CNT)] = {0};
struct input_absinfo absinfo[ABS_CNT];
if (ioctl(pInfo->fd,
EVIOCGNAME(sizeof(name) - 1), name) < 0) {
@@ -1099,7 +1220,7 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
if (ioctl(pInfo->fd,
EVIOCGBIT(0, sizeof(bitmask)), bitmask) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
goto error;
}
@@ -1145,7 +1266,7 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
memset(absinfo, 0, sizeof(absinfo));
for (i = 0; i < ABS_MAX; i++)
for (i = ABS_X; i <= ABS_MAX; i++)
{
if (TestBit(i, abs_bitmask))
{
@@ -1181,9 +1302,9 @@ error:
static int
EvdevProbe(InputInfoPtr pInfo)
{
long key_bitmask[NBITS(KEY_MAX)] = {0};
long rel_bitmask[NBITS(REL_MAX)] = {0};
long abs_bitmask[NBITS(ABS_MAX)] = {0};
long key_bitmask[NLONGS(KEY_CNT)] = {0};
long rel_bitmask[NLONGS(REL_CNT)] = {0};
long abs_bitmask[NLONGS(ABS_CNT)] = {0};
int i, has_axes, has_keys, num_buttons;
int kernel24 = 0;
EvdevPtr pEvdev = pInfo->private;
@@ -1367,9 +1488,21 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
return NULL;
}
/* Check major/minor of device node to avoid adding duplicate devices. */
pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
if (EvdevIsDuplicate(pInfo))
{
xf86Msg(X_WARNING, "%s: device file already in use. Ignoring.\n",
pInfo->name);
close(pInfo->fd);
xf86DeleteInput(pInfo, 0);
return NULL;
}
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".
@@ -1387,6 +1520,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
}
EvdevCacheCompare(pInfo, FALSE); /* cache device data */
EvdevAddDevice(pInfo);
if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
{
@@ -1449,7 +1583,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 +1600,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 +1625,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 +1677,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 +1725,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;

View File

@@ -31,6 +31,7 @@
#define EVDEV_H
#include <linux/input.h>
#include <linux/types.h>
#include <xf86Xinput.h>
#include <xf86_OSproc.h>
@@ -39,6 +40,22 @@
#include <xkbstr.h>
#endif
#ifndef EV_CNT /* linux 2.4 kernels and earlier lack _CNT defines */
#define EV_CNT (EV_MAX+1)
#endif
#ifndef KEY_CNT
#define KEY_CNT (KEY_MAX+1)
#endif
#ifndef REL_CNT
#define REL_CNT (REL_MAX+1)
#endif
#ifndef ABS_CNT
#define ABS_CNT (ABS_MAX+1)
#endif
#ifndef LED_CNT
#define LED_CNT (LED_MAX+1)
#endif
#define EVDEV_MAXBUTTONS 32
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
@@ -46,7 +63,9 @@
#endif
#define LONG_BITS (sizeof(long) * 8)
#define NBITS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
/* Number of longs needed to hold the given number of bits */
#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
/* axis specific data for wheel emulation */
typedef struct {
@@ -64,6 +83,7 @@ typedef struct {
int flags;
int tool;
int buttons; /* number of buttons */
BOOL swap_axes;
BOOL invert_x;
BOOL invert_y;
@@ -102,6 +122,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 */
@@ -111,15 +138,18 @@ typedef struct {
/* Cached info from device. */
char name[1024];
long bitmask[NBITS(EV_MAX)];
long key_bitmask[NBITS(KEY_MAX)];
long rel_bitmask[NBITS(REL_MAX)];
long abs_bitmask[NBITS(ABS_MAX)];
long led_bitmask[NBITS(LED_MAX)];
struct input_absinfo absinfo[ABS_MAX];
long bitmask[NLONGS(EV_CNT)];
long key_bitmask[NLONGS(KEY_CNT)];
long rel_bitmask[NLONGS(REL_CNT)];
long abs_bitmask[NLONGS(ABS_CNT)];
long led_bitmask[NLONGS(LED_CNT)];
struct input_absinfo absinfo[ABS_CNT];
/* minor/major number */
dev_t min_maj;
} EvdevRec, *EvdevPtr;
unsigned int EvdevUtilButtonEventToButtonNumber(int code);
unsigned int EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code);
/* Middle Button emulation */
int EvdevMBEmuTimer(InputInfoPtr);
@@ -127,6 +157,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);