aboutsummaryrefslogtreecommitdiff
path: root/src/evdev.c
diff options
context:
space:
mode:
authorZephaniah E. Hull <warp@aehallh.com>2006-02-24 13:44:56 +0000
committerZephaniah E. Hull <warp@aehallh.com>2006-02-24 13:44:56 +0000
commit47482dad76ab74c0b5c9e8d455f04935651173ec (patch)
tree22818646846473ac8826d724fab4a297ac35e541 /src/evdev.c
parentinclude errno.h to make it compile. (diff)
downloadxf86-input-evdev-47482dad76ab74c0b5c9e8d455f04935651173ec.tar.gz
xf86-input-evdev-47482dad76ab74c0b5c9e8d455f04935651173ec.tar.bz2
xf86-input-evdev-47482dad76ab74c0b5c9e8d455f04935651173ec.zip
Compile with -Wall now. Add evdev.h to the sources so that make distcheck
gets it. Bugzilla #5943 <https://bugs.freedesktop.org/show_bug.cgi=5943> Make sure we include errno.h. Reduce EVDEV_MAXBUTTONS to 96. Split up evdevStateRec into a struct with pointers to new structs for btn, abs, rel, and key. New structure type for handling the device capability bitmaps. Add device bits and struct input_id to evdevDeviceRec. Add matching device bits, struct input_id, and pass number to evdevDriverRec. Prototype for evdevGetBits from evdev_brain.c. Conversion for the evdevStateRec split. Remove the errno.h include, it's in evdev.h for now. Move the bit getting from the drivers to here, into evdevDeviceRec. Fix a rare case of fd leakage. Add several new (and somewhat ugly) device matching options: <map>Bits: Where map is one of ev, key, rel, abs, msc, led, snd, or ff. In the format of '+0 +3 -1-2 ~5-10', requires bits 0 and 3 be set, bits 1 and 2 to not be set, and at least one bit in the range of 5 to 10 be set. bustype, vendor, product, and version: Simple integer options for matching the struct device_id fields, must be 0 (the default) or the exact value you wish to match against. pass: Bounded to 0-3, devices are matched to the first matching entry found, order for multiple matching entries in the same pass is undefined, but it starts with pass 0 and goes to pass 3. Adaptation for the evdevStateRec split and the change in capability bitmap handling. Add evdevGetBits to fill the new evdevBitsRec struct type. Lots of somewhat ugly code for matching by capability bits. Split out of evdevRescanDevices to smaller handling functions. The new design should be better if I decide to handle arbitrary Device fields again. Adaptation for the evdevStateRec split and the change in capability bitmap handling. Handle all buttons, no button compression at this time, however we reorder things so that BTN_MOUSE comes before BTN_MISC, somewhat evily. Support for the new btn->state[] array of int pointers. Adaptation for the evdevStateRec split and the change in capability bitmap handling. Adaptation for the evdevStateRec split and the change in capability bitmap handling. I really hope I didn't miss any changes.
Diffstat (limited to 'src/evdev.c')
-rw-r--r--src/evdev.c133
1 files changed, 111 insertions, 22 deletions
diff --git a/src/evdev.c b/src/evdev.c
index 701fd03..fa5a1d9 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -62,7 +62,6 @@
#include <X11/extensions/XIproto.h>
#include <string.h>
-#include <errno.h>
/* The libc wrapper just blows... linux/input.h must be included
* before xf86_ansic.h and xf86_libc.h so we avoid defining ioctl
@@ -141,16 +140,19 @@ EvdevProc(DeviceIntPtr device, int what)
InputInfoPtr pInfo = device->public.devicePrivate;
evdevDevicePtr pEvdev = pInfo->private;
+ if (!pEvdev->device)
+ return BadRequest;
+
switch (what)
{
case DEVICE_INIT:
- if (pEvdev->state.abs_axes)
+ if (pEvdev->state.abs)
EvdevAbsInit (device);
- if (pEvdev->state.rel_axes)
+ if (pEvdev->state.rel)
EvdevRelInit (device);
- if (pEvdev->state.buttons)
+ if (pEvdev->state.btn)
EvdevBtnInit (device);
- if (pEvdev->state.keys)
+ if (pEvdev->state.key)
EvdevKeyInit (device);
xf86Msg(X_INFO, "%s: Init\n", pInfo->name);
break;
@@ -184,13 +186,13 @@ EvdevProc(DeviceIntPtr device, int what)
device->public.on = TRUE;
- if (pEvdev->state.abs_axes)
+ if (pEvdev->state.abs)
EvdevAbsOn (device);
- if (pEvdev->state.rel_axes)
+ if (pEvdev->state.rel)
EvdevRelOn (device);
- if (pEvdev->state.buttons)
+ if (pEvdev->state.btn)
EvdevBtnOn (device);
- if (pEvdev->state.keys)
+ if (pEvdev->state.key)
EvdevKeyOn (device);
break;
@@ -205,13 +207,13 @@ EvdevProc(DeviceIntPtr device, int what)
xf86RemoveSIGIOHandler (pInfo->fd);
close (pInfo->fd);
- if (pEvdev->state.abs_axes)
+ if (pEvdev->state.abs)
EvdevAbsOff (device);
- if (pEvdev->state.rel_axes)
+ if (pEvdev->state.rel)
EvdevRelOff (device);
- if (pEvdev->state.buttons)
+ if (pEvdev->state.btn)
EvdevBtnOff (device);
- if (pEvdev->state.keys)
+ if (pEvdev->state.key)
EvdevKeyOff (device);
}
@@ -233,7 +235,7 @@ EvdevSwitchMode (ClientPtr client, DeviceIntPtr device, int mode)
{
case Absolute:
case Relative:
- if (state->abs_axes)
+ if (state->abs)
state->mode = mode;
else
return !Success;
@@ -286,6 +288,14 @@ EvdevNew(evdevDriverPtr driver, evdevDevicePtr device)
return 0;
}
+ if (!evdevGetBits (pInfo->fd, &device->bits)) {
+ xf86Msg(X_ERROR, "%s: cannot load bits\n", pInfo->name);
+ pInfo->private = NULL;
+ close (pInfo->fd);
+ xf86DeleteInput (pInfo, 0);
+ return 0;
+ }
+
if (ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
xf86Msg(X_INFO, "%s: Unable to grab device (%s). Cowardly refusing to check use as keyboard.\n", pInfo->name, strerror(errno));
device->state.can_grab = 0;
@@ -294,6 +304,7 @@ EvdevNew(evdevDriverPtr driver, evdevDevicePtr device)
ioctl(pInfo->fd, EVIOCGRAB, (void *)0);
}
+
/* XXX: Note, the order of these is important. */
EvdevAbsNew (pInfo);
EvdevRelNew (pInfo);
@@ -308,6 +319,7 @@ EvdevNew(evdevDriverPtr driver, evdevDevicePtr device)
if (!(pInfo->flags & XI86_CONFIGURED)) {
xf86Msg(X_ERROR, "%s: Don't know how to use device.\n", pInfo->name);
pInfo->private = NULL;
+ close (pInfo->fd);
xf86DeleteInput (pInfo, 0);
return 0;
}
@@ -322,10 +334,59 @@ EvdevNew(evdevDriverPtr driver, evdevDevicePtr device)
return 1;
}
+static void
+EvdevParseBits (char *in, long *out, int len)
+{
+ unsigned long v[2];
+ int n, i, max_bits = len * BITS_PER_LONG;
+
+ n = sscanf (in, "%lu-%lu", &v[0], &v[1]);
+ if (!n)
+ return;
+
+ if (v[0] >= max_bits)
+ return;
+
+ if (n == 2) {
+ if (v[1] >= max_bits)
+ v[1] = max_bits - 1;
+
+ for (i = v[0]; i <= v[1]; i++)
+ set_bit (i, out);
+ } else
+ set_bit (v[0], out);
+}
+
+static void
+EvdevParseBitOption (char *opt, long *all, long *not, long *any, int len)
+{
+ char *cur, *next;
+
+ next = opt - 1;
+ while (next) {
+ cur = next + 1;
+ if ((next = strchr(cur, ' ')))
+ *next = '\0';
+
+ switch (cur[0]) {
+ case '+':
+ EvdevParseBits (cur + 1, all, len);
+ break;
+ case '-':
+ EvdevParseBits (cur + 1, not, len);
+ break;
+ case '~':
+ EvdevParseBits (cur + 1, any, len);
+ break;
+ }
+ }
+}
+
static InputInfoPtr
EvdevCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
{
evdevDriverPtr pEvdev;
+ char *opt, *tmp;
if (!(pEvdev = Xcalloc(sizeof(*pEvdev))))
return NULL;
@@ -333,20 +394,48 @@ EvdevCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
pEvdev->name = xf86CheckStrOption(dev->commonOptions, "Name", NULL);
pEvdev->phys = xf86CheckStrOption(dev->commonOptions, "Phys", NULL);
pEvdev->device = xf86CheckStrOption(dev->commonOptions, "Device", NULL);
- xf86Msg(X_ERROR, "%s: name: %s, phys: %s, device: %s.\n", dev->identifier,
- pEvdev->name, pEvdev->phys, pEvdev->device);
+
+#define bitoption(field) \
+ opt = xf86CheckStrOption(dev->commonOptions, #field "Bits", NULL); \
+ if (opt) { \
+ tmp = strdup(opt); \
+ EvdevParseBitOption (tmp, pEvdev->all_bits.field, \
+ pEvdev->not_bits.field, \
+ pEvdev->any_bits.field, \
+ sizeof(pEvdev->not_bits.field) / sizeof (long)); \
+ free (tmp); \
+ }
+ bitoption(ev);
+ bitoption(key);
+ bitoption(rel);
+ bitoption(abs);
+ bitoption(msc);
+ bitoption(led);
+ bitoption(snd);
+ bitoption(ff);
+#undef bitoption
+
+ pEvdev->id.bustype = xf86CheckIntOption(dev->commonOptions, "bustype", 0);
+ pEvdev->id.vendor = xf86CheckIntOption(dev->commonOptions, "vendor", 0);
+ pEvdev->id.product = xf86CheckIntOption(dev->commonOptions, "product", 0);
+ pEvdev->id.version = xf86CheckIntOption(dev->commonOptions, "version", 0);
+
+ pEvdev->pass = xf86CheckIntOption(dev->commonOptions, "Pass", 0);
+ if (pEvdev->pass > 3)
+ pEvdev->pass = 3;
+ else if (pEvdev->pass < 0)
+ pEvdev->pass = 0;
+
+
+ xf86Msg(X_CONFIG, "%s: name: %s, phys: %s, device: %s, pass: %d.\n",
+ dev->identifier, pEvdev->name, pEvdev->phys, pEvdev->device,
+ pEvdev->pass);
pEvdev->callback = EvdevNew;
pEvdev->dev = dev;
pEvdev->drv = drv;
- if (!pEvdev->name && !pEvdev->phys && !pEvdev->device) {
- xf86Msg(X_ERROR, "%s: No device identifiers specified.\n", dev->identifier);
- xfree(pEvdev);
- return NULL;
- }
-
if (!evdevStart (drv)) {
xf86Msg(X_ERROR, "%s: cannot start evdev brain.\n", dev->identifier);
xfree(pEvdev);