mirror of
https://github.com/X11Libre/xf86-input-evdev.git
synced 2026-04-14 11:44:16 +00:00
Compare commits
10 Commits
xf86-input
...
xf86-input
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11d506dce6 | ||
|
|
a34a2cd347 | ||
|
|
78c00bd77f | ||
|
|
760f1c6bb1 | ||
|
|
2db04ba3c3 | ||
|
|
363d0bdb9f | ||
|
|
16a26a1eca | ||
|
|
b879ae7351 | ||
|
|
53566b7d4d | ||
|
|
29c2765fc3 |
@@ -22,7 +22,7 @@
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([xf86-input-evdev],
|
||||
2.0.99.3,
|
||||
2.1.1,
|
||||
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
|
||||
xf86-input-evdev)
|
||||
|
||||
|
||||
@@ -201,5 +201,5 @@ server, such as touchscreens that require run-time calibration.
|
||||
.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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
142
src/evdev.c
142
src/evdev.c
@@ -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
|
||||
@@ -112,6 +117,88 @@ 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)
|
||||
@@ -149,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 &&
|
||||
@@ -161,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);
|
||||
@@ -205,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;
|
||||
@@ -217,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;
|
||||
}
|
||||
|
||||
@@ -765,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);
|
||||
@@ -1024,6 +1113,14 @@ 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);
|
||||
@@ -1053,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))
|
||||
@@ -1062,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;
|
||||
@@ -1079,6 +1179,8 @@ EvdevProc(DeviceIntPtr device, int what)
|
||||
close(pInfo->fd);
|
||||
pInfo->fd = -1;
|
||||
}
|
||||
EvdevRemoveDevice(pInfo);
|
||||
pEvdev->min_maj = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1100,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) {
|
||||
@@ -1118,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;
|
||||
}
|
||||
|
||||
@@ -1164,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))
|
||||
{
|
||||
@@ -1200,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;
|
||||
@@ -1386,6 +1488,17 @@ 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);
|
||||
@@ -1407,6 +1520,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
|
||||
}
|
||||
|
||||
EvdevCacheCompare(pInfo, FALSE); /* cache device data */
|
||||
EvdevAddDevice(pInfo);
|
||||
|
||||
if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
|
||||
{
|
||||
|
||||
36
src/evdev.h
36
src/evdev.h
@@ -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 {
|
||||
@@ -119,12 +138,15 @@ 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(EvdevPtr pEvdev, int code);
|
||||
|
||||
Reference in New Issue
Block a user