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.
This commit is contained in:
Zephaniah E. Hull
2006-02-24 13:44:56 +00:00
parent 739a0f51b0
commit 47482dad76
9 changed files with 664 additions and 263 deletions

View File

@@ -1,4 +1,87 @@
2006-02-20 Zephaniah E. Hull,,, <warp@aehallh.com>
2006-02-24 Zephaniah E. Hull <warp@aehallh.com>
* src/Makefile.am:
Compile with -Wall now.
Add evdev.h to the sources so that make distcheck gets it.
* src/evdev.h:
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.
* src/evdev.c: (EvdevProc), (EvdevSwitchMode), (EvdevNew),
(EvdevParseBits), (EvdevParseBitOption), (EvdevCorePreInit):
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.
* src/evdev_abs.c: (EvdevAbsSyn), (EvdevAbsProcess),
(EvdevAbsInit), (EvdevAbsNew):
Adaptation for the evdevStateRec split and the change in capability
bitmap handling.
* src/evdev_brain.c: (MatchAll), (MatchNot), (MatchAny),
(MatchDriver), (MatchDevice), (evdevScanDevice), (FillDevInfo),
(evdevRescanDevices), (evdevGetBits):
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.
* src/evdev_btn.c: (EvdevBtnInit), (EvdevBtnOn),
(EvdevBtnCalcRemap), (EvdevBtnNew), (EvdevBtnProcess):
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.
* src/evdev_key.c: (EvdevKeyInit), (SetXkbOption), (EvdevKeyNew):
Adaptation for the evdevStateRec split and the change in capability
bitmap handling.
* src/evdev_rel.c: (EvdevRelSyn), (EvdevRelProcess),
(EvdevRelInit), (EvdevRelNew):
Adaptation for the evdevStateRec split and the change in capability
bitmap handling.
2006-02-20 Zephaniah E. Hull <warp@aehallh.com>
* src/evdev_btn.c: (EvdevBtnInit):
Bugzilla #5950 <https://bugs.freedesktop.org/show_bug.cgi=5950>

View File

@@ -26,6 +26,7 @@
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
@DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
@DRIVER_NAME@_drv_la_CFLAGS = -Wall
@DRIVER_NAME@_drv_ladir = @inputdir@
@DRIVER_NAME@_drv_la_SOURCES = evdev.c evdev_brain.c evdev_abs.c evdev_rel.c evdev_btn.c evdev_key.c
@DRIVER_NAME@_drv_la_SOURCES = evdev.c evdev.h evdev_brain.c evdev_abs.c evdev_rel.c evdev_btn.c evdev_key.c

View File

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

View File

@@ -62,6 +62,7 @@
#include <linux/input.h>
#include <xf86Xinput.h>
#include <errno.h>
#define BITS_PER_LONG (sizeof(long) * 8)
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
@@ -76,6 +77,7 @@
#include <sys/time.h>
#include <sys/ioctl.h>
#include <asm/types.h>
#include <asm/bitops.h>
#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */
@@ -115,40 +117,64 @@
#define EV_BUS_GSC 0x1A
#define EVDEV_MAXBUTTONS 128
#define EVDEV_MAXBUTTONS 96
typedef struct _evdevState {
Bool can_grab;
Bool sync;
typedef struct {
long ev[NBITS(EV_MAX)];
long key[NBITS(KEY_MAX)];
long rel[NBITS(REL_MAX)];
long abs[NBITS(ABS_MAX)];
long msc[NBITS(MSC_MAX)];
long led[NBITS(LED_MAX)];
long snd[NBITS(SND_MAX)];
long ff[NBITS(FF_MAX)];
} evdevBitsRec, *evdevBitsPtr;
typedef struct {
int real_buttons;
int buttons;
CARD8 buttonMap[EVDEV_MAXBUTTONS];
CARD8 map[EVDEV_MAXBUTTONS];
int *state[EVDEV_MAXBUTTONS];
} evdevBtnRec, *evdevBtnPtr;
int mode; /* Either Absolute or Relative. */
typedef struct {
int axes;
int n; /* Which abs_v is current, and which is previous. */
int v[2][ABS_MAX];
int min[ABS_MAX];
int max[ABS_MAX];
int map[ABS_MAX];
Bool scale;
int scale_x;
int scale_y;
int screen; /* Screen number for this device. */
} evdevAbsRec, *evdevAbsPtr;
int abs_axes;
int abs_n; /* Which abs_v is current, and which is previous. */
int abs_v[2][ABS_MAX];
int abs_min[ABS_MAX];
int abs_max[ABS_MAX];
int absMap[ABS_MAX];
Bool abs_scale;
int abs_scale_x;
int abs_scale_y;
int abs_screen; /* Screen number for this device. */
typedef struct {
int axes;
int v[REL_MAX];
CARD8 btnMap[REL_MAX][2];
int map[REL_MAX];
} evdevRelRec, *evdevRelPtr;
int rel_axes;
int rel_v[REL_MAX];
CARD8 relToBtnMap[REL_MAX][2];
int relMap[REL_MAX];
Bool keys;
typedef struct {
char *xkb_rules;
char *xkb_model;
char *xkb_layout;
char *xkb_variant;
char *xkb_options;
XkbComponentNamesRec xkbnames;
} evdevKeyRec, *evdevKeyPtr;
typedef struct _evdevState {
Bool can_grab;
Bool sync;
int mode; /* Either Absolute or Relative. */
evdevBtnPtr btn;
evdevAbsPtr abs;
evdevRelPtr rel;
evdevKeyPtr key;
} evdevStateRec, *evdevStatePtr;
typedef struct _evdevDevice {
@@ -160,6 +186,9 @@ typedef struct _evdevDevice {
InputInfoPtr pInfo;
int (*callback)(DeviceIntPtr cb_data, int what);
evdevBitsRec bits;
struct input_id id;
evdevStateRec state;
struct _evdevDevice *next;
@@ -170,6 +199,14 @@ typedef struct _evdevDriver {
const char *phys;
const char *device;
evdevBitsRec all_bits;
evdevBitsRec not_bits;
evdevBitsRec any_bits;
struct input_id id;
int pass;
InputDriverPtr drv;
IDevPtr dev;
Bool (*callback)(struct _evdevDriver *driver, evdevDevicePtr device);
@@ -182,6 +219,7 @@ typedef struct _evdevDriver {
int evdevGetFDForDevice (evdevDevicePtr driver);
Bool evdevStart (InputDriverPtr drv);
Bool evdevNewDriver (evdevDriverPtr driver);
Bool evdevGetBits (int fd, evdevBitsPtr bits);
int EvdevBtnInit (DeviceIntPtr device);
int EvdevBtnOn (DeviceIntPtr device);

View File

@@ -160,40 +160,42 @@ EvdevAbsSyn (InputInfoPtr pInfo)
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int i;
int n = state->abs_n & 1;
int n;
if (!state->abs_axes)
if (!state->abs)
return;
n = state->abs->n & 1;
if (state->mode == Absolute) {
if ((state->abs_screen >= 0) && state->abs_axes >= 2) {
if ((state->abs->screen >= 0) && state->abs->axes >= 2) {
int conv_x, conv_y;
for (i = 0; i < 2; i++)
state->abs_v[n][i] = xf86ScaleAxis (state->abs_v[n][i], 0,
state->abs_scale_x,
state->abs_min[i], state->abs_max[i]);
state->abs->v[n][i] = xf86ScaleAxis (state->abs->v[n][i], 0,
state->abs->scale_x,
state->abs->min[i], state->abs->max[i]);
EvdevConvert (pInfo, 0, 2, state->abs_v[n][0], state->abs_v[n][1],
EvdevConvert (pInfo, 0, 2, state->abs->v[n][0], state->abs->v[n][1],
0, 0, 0, 0, &conv_x, &conv_y);
xf86XInputSetScreen (pInfo, state->abs_screen, conv_x, conv_y);
xf86XInputSetScreen (pInfo, state->abs->screen, conv_x, conv_y);
}
xf86PostMotionEvent(pInfo->dev, 1, 0, state->abs_axes,
state->abs_v[n][0],
state->abs_v[n][1], state->abs_v[n][2], state->abs_v[n][3],
state->abs_v[n][4], state->abs_v[n][5], state->abs_v[n][6],
state->abs_v[n][7], state->abs_v[n][8], state->abs_v[n][9],
state->abs_v[n][10], state->abs_v[n][11], state->abs_v[n][12],
state->abs_v[n][13], state->abs_v[n][14], state->abs_v[n][15]);
xf86PostMotionEvent(pInfo->dev, 1, 0, state->abs->axes,
state->abs->v[n][0],
state->abs->v[n][1], state->abs->v[n][2], state->abs->v[n][3],
state->abs->v[n][4], state->abs->v[n][5], state->abs->v[n][6],
state->abs->v[n][7], state->abs->v[n][8], state->abs->v[n][9],
state->abs->v[n][10], state->abs->v[n][11], state->abs->v[n][12],
state->abs->v[n][13], state->abs->v[n][14], state->abs->v[n][15]);
} else {
for (i = 0; i < 2; i++)
state->rel_v[i] = state->abs_v[n][i] - state->abs_v[!n][i];
state->rel->v[i] = state->abs->v[n][i] - state->abs->v[!n][i];
}
state->abs_n++;
state->abs->n++;
}
void
@@ -201,17 +203,17 @@ EvdevAbsProcess (InputInfoPtr pInfo, struct input_event *ev)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int n = state->abs_n & 1;
int n = state->abs->n & 1;
int map;
if (ev->code >= ABS_MAX)
return;
map = pEvdev->state.absMap[ev->code];
map = pEvdev->state.abs->map[ev->code];
if (map >= 0)
pEvdev->state.abs_v[n][map] += ev->value;
pEvdev->state.abs->v[n][map] += ev->value;
else
pEvdev->state.abs_v[n][-map] -= ev->value;
pEvdev->state.abs->v[n][-map] -= ev->value;
if (!pEvdev->state.sync)
EvdevAbsSyn (pInfo);
@@ -224,12 +226,12 @@ EvdevAbsInit (DeviceIntPtr device)
evdevDevicePtr pEvdev = pInfo->private;
int i;
if (!InitValuatorClassDeviceStruct(device, pEvdev->state.abs_axes,
if (!InitValuatorClassDeviceStruct(device, pEvdev->state.abs->axes,
miPointerGetMotionEvents,
miPointerGetMotionBufferSize(), 0))
return !Success;
for (i = 0; i < pEvdev->state.abs_axes; i++) {
for (i = 0; i < pEvdev->state.abs->axes; i++) {
xf86InitValuatorAxisStruct(device, i, 0, 0, 0, 0, 1);
xf86InitValuatorDefaults(device, i);
}
@@ -257,25 +259,20 @@ EvdevAbsNew(InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
long abs_bitmask[NBITS(KEY_MAX)];
struct input_absinfo absinfo;
char *s, option[64];
int i, j, k = 0, real_axes;
if (ioctl(pInfo->fd,
EVIOCGBIT(EV_ABS, ABS_MAX), abs_bitmask) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
return !Success;
}
real_axes = 0;
for (i = 0; i < ABS_MAX; i++)
if (TestBit (i, abs_bitmask))
if (TestBit (i, pEvdev->bits.abs))
real_axes++;
if (!real_axes)
return !Success;
state->abs = Xcalloc (sizeof (evdevAbsRec));
xf86Msg(X_INFO, "%s: Found %d absolute axes.\n", pInfo->name, real_axes);
xf86Msg(X_INFO, "%s: Configuring as pointer.\n", pInfo->name);
pInfo->flags |= XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS |
@@ -284,15 +281,15 @@ EvdevAbsNew(InputInfoPtr pInfo)
pInfo->conversion_proc = EvdevConvert;
for (i = 0, j = 0; i < ABS_MAX; i++) {
if (!TestBit (i, abs_bitmask))
if (!TestBit (i, pEvdev->bits.abs))
continue;
snprintf(option, sizeof(option), "%sAbsoluteAxisMap", axis_names[i]);
k = xf86SetIntOption(pInfo->options, option, -1);
if (k != -1)
state->absMap[i] = k;
state->abs->map[i] = k;
else
state->absMap[i] = j;
state->abs->map[i] = j;
if (k != -1)
xf86Msg(X_CONFIG, "%s: %s: %d.\n", pInfo->name, option, k);
@@ -301,21 +298,21 @@ EvdevAbsNew(InputInfoPtr pInfo)
xf86Msg(X_ERROR, "ioctl EVIOCGABS failed: %s\n", strerror(errno));
return !Success;
}
state->abs_min[state->absMap[i]] = absinfo.minimum;
state->abs_max[state->absMap[i]] = absinfo.maximum;
state->abs->min[state->abs->map[i]] = absinfo.minimum;
state->abs->max[state->abs->map[i]] = absinfo.maximum;
j++;
}
state->abs_axes = real_axes;
state->abs->axes = real_axes;
for (i = 0; i < ABS_MAX; i++) {
if (state->absMap[i] > state->abs_axes)
state->abs_axes = state->absMap[i];
if (state->abs->map[i] > state->abs->axes)
state->abs->axes = state->abs->map[i];
}
if (state->abs_axes != real_axes)
if (state->abs->axes != real_axes)
xf86Msg(X_CONFIG, "%s: Configuring %d absolute axes.\n", pInfo->name,
state->abs_axes);
state->abs->axes);
s = xf86SetStrOption(pInfo->options, "Mode", "Absolute");
if (!strcasecmp(s, "Absolute")) {
@@ -329,20 +326,20 @@ EvdevAbsNew(InputInfoPtr pInfo)
xf86Msg(X_CONFIG, "%s: Unknown Mode: %s.\n", pInfo->name, s);
}
if (TestBit (ABS_X, abs_bitmask) && TestBit (ABS_Y, abs_bitmask))
if (TestBit (ABS_X, pEvdev->bits.abs) && TestBit (ABS_Y, pEvdev->bits.abs))
k = xf86SetIntOption(pInfo->options, "AbsoluteScreen", 0);
else
k = xf86SetIntOption(pInfo->options, "AbsoluteScreen", -1);
if (k < screenInfo.numScreens) {
state->abs_screen = k;
state->abs->screen = k;
xf86Msg(X_CONFIG, "%s: AbsoluteScreen: %d.\n", pInfo->name, k);
} else {
state->abs_screen = 0;
state->abs->screen = 0;
xf86Msg(X_CONFIG, "%s: AbsoluteScreen: %d is not a valid screen.\n", pInfo->name, k);
}
state->abs_scale_x = screenInfo.screens[state->abs_screen]->width;
state->abs_scale_y = screenInfo.screens[state->abs_screen]->height;
state->abs->scale_x = screenInfo.screens[state->abs->screen]->width;
state->abs->scale_y = screenInfo.screens[state->abs->screen]->height;
return Success;
}

View File

@@ -106,75 +106,232 @@ evdevGetFDForDevice (evdevDevicePtr device)
driver->devices = device; \
} while (0)
typedef struct {
int fd;
evdevBitsRec bits;
char name[256];
char phys[256];
char dev[256];
struct input_id id;
} evdevDevInfoRec, *evdevDevInfoPtr;
static Bool
MatchAll (long *dev, long *match, int len)
{
int i;
for (i = 0; i < len; i++)
if ((dev[i] & match[i]) != match[i])
return FALSE;
return TRUE;
}
static Bool
MatchNot (long *dev, long *match, int len)
{
int i;
for (i = 0; i < len; i++)
if ((dev[i] & match[i]))
return FALSE;
return TRUE;
}
static Bool
MatchAny (long *dev, long *match, int len)
{
int i, found = 0;
for (i = 0; i < len; i++)
if (match[i]) {
found = 1;
if ((dev[i] & match[i]))
return TRUE;
}
if (found)
return FALSE;
else
return TRUE;
}
static Bool
MatchDriver (evdevDriverPtr driver, evdevDevInfoPtr info)
{
if (driver->name && glob_match(driver->name, info->name))
return FALSE;
if (driver->phys && glob_match(driver->phys, info->phys))
return FALSE;
if (driver->device && glob_match(driver->device, info->dev))
return FALSE;
if (driver->id.bustype && driver->id.bustype != info->id.bustype)
return FALSE;
if (driver->id.vendor && driver->id.vendor != info->id.vendor)
return FALSE;
if (driver->id.product && driver->id.product != info->id.product)
return FALSE;
if (driver->id.version && driver->id.version != info->id.version)
return FALSE;
#define match(which) \
if (!MatchAll(info->bits.which, driver->all_bits.which, \
sizeof(driver->all_bits.which) / \
sizeof(driver->all_bits.which[0]))) \
return FALSE; \
if (!MatchNot(info->bits.which, driver->not_bits.which, \
sizeof(driver->not_bits.which) / \
sizeof(driver->not_bits.which[0]))) \
return FALSE; \
if (!MatchAny(info->bits.which, driver->any_bits.which, \
sizeof(driver->any_bits.which) / \
sizeof(driver->any_bits.which[0]))) \
return FALSE;
match(ev)
match(key)
match(rel)
match(abs)
match(msc)
match(led)
match(snd)
match(ff)
#undef match
return TRUE;
}
static Bool
MatchDevice (evdevDevicePtr device, evdevDevInfoPtr info)
{
int i, len;
if (device->id.bustype != info->id.bustype)
return FALSE;
if (device->id.vendor != info->id.vendor)
return FALSE;
if (device->id.product != info->id.product)
return FALSE;
if (device->id.version != info->id.version)
return FALSE;
if (strcmp(device->name, info->name))
return FALSE;
len = sizeof(info->bits.ev) / sizeof(info->bits.ev[0]);
for (i = 0; i < len; i++)
if (device->bits.ev[i] != info->bits.ev[i])
return FALSE;
return TRUE;
}
static Bool
evdevScanDevice (evdevDriverPtr driver, evdevDevInfoPtr info)
{
evdevDevicePtr device;
int found;
if (!MatchDriver (driver, info))
return FALSE;
found = 0;
for (device = driver->devices; device; device = device->next) {
if (MatchDevice (device, info)) {
if (device->seen != (evdev_seq - 1)) {
device->device = xstrdup(info->dev);
device->phys = xstrdup(info->phys);
device->callback(device->pInfo->dev, DEVICE_ON);
}
device->seen = evdev_seq;
return TRUE;
}
}
device = Xcalloc (sizeof (evdevDeviceRec));
device->device = xstrdup(info->dev);
device->name = xstrdup(info->name);
device->phys = xstrdup(info->phys);
device->id.bustype = info->id.bustype;
device->id.vendor = info->id.vendor;
device->id.product = info->id.product;
device->id.version = info->id.version;
device->seen = evdev_seq;
device_add(driver, device);
driver->callback(driver, device);
return TRUE;
}
static Bool
FillDevInfo (char *dev, evdevDevInfoPtr info)
{
int fd;
SYSCALL(fd = open (dev, O_RDWR | O_NONBLOCK));
if (fd == -1)
return FALSE;
if (ioctl(fd, EVIOCGNAME(sizeof(info->name)), info->name) == -1)
info->name[0] = '\0';
if (ioctl(fd, EVIOCGPHYS(sizeof(info->phys)), info->phys) == -1)
info->phys[0] = '\0';
if (ioctl(fd, EVIOCGID, &info->id) == -1) {
close (fd);
return FALSE;
}
if (!evdevGetBits (fd, &info->bits)) {
close (fd);
return FALSE;
}
strncpy (info->dev, dev, sizeof(info->dev));
info->fd = fd;
return TRUE;
}
static void
evdevRescanDevices (InputInfoPtr pInfo)
{
char dev[20];
char name[256], phys[256];
int fd, i;
int old_seq = evdev_seq;
int i, j, found;
evdevDriverPtr driver;
evdevDevicePtr device;
Bool found;
evdevDevInfoRec info;
evdev_seq++;
xf86Msg(X_INFO, "%s: Rescanning devices (%d).\n", pInfo->name, evdev_seq);
for (i = 0; i < 32; i++) {
snprintf(dev, sizeof(dev), "/dev/input/event%d", i);
SYSCALL(fd = open (dev, O_RDWR | O_NONBLOCK));
if (fd == -1)
if (!FillDevInfo (dev, &info))
continue;
if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) == -1)
name[0] = '\0';
if (ioctl(fd, EVIOCGPHYS(sizeof(phys)), phys) == -1)
phys[0] = '\0';
found = 0;
for (driver = evdev_drivers; driver; driver = driver->next) {
if (driver->name && glob_match(driver->name, name))
continue;
if (driver->phys && glob_match(driver->phys, phys))
continue;
if (driver->device && glob_match(driver->device, dev))
continue;
found = 0;
for (device = driver->devices; device; device = device->next) {
xf86Msg(X_INFO, "%s: %s %d -> %s %d.\n", pInfo->name, name, evdev_seq, device->name, device->seen);
if (!strcmp(device->name, name)) {
if (device->seen != old_seq) {
device->device = xstrdup(dev);
device->phys = xstrdup(phys);
device->callback(device->pInfo->dev, DEVICE_ON);
}
device->seen = evdev_seq;
found = 1;
for (j = 0; j <= 3 && !found; j++) {
for (driver = evdev_drivers; driver && !found; driver = driver->next) {
if ((driver->pass == j) && (found = evdevScanDevice (driver, &info)))
break;
}
}
if (!found) {
device = Xcalloc (sizeof (evdevDeviceRec));
device->device = xstrdup(dev);
device->name = xstrdup(name);
device->phys = xstrdup(phys);
device->seen = evdev_seq;
device_add(driver, device);
driver->callback(driver, device);
}
device->seen = evdev_seq;
break;
}
close (fd);
if (!found)
close (info.fd);
}
for (driver = evdev_drivers; driver; driver = driver->next)
for (device = driver->devices; device; device = device->next)
if (device->seen == old_seq) {
if (device->seen == (evdev_seq - 1)) {
device->callback(device->pInfo->dev, DEVICE_OFF);
if (device->device)
@@ -282,3 +439,27 @@ evdevNewDriver (evdevDriverPtr driver)
driver->configured = TRUE;
return TRUE;
}
Bool
evdevGetBits (int fd, evdevBitsPtr bits)
{
#define get_bitmask(fd, which, where) \
if (ioctl(fd, EVIOCGBIT(which, sizeof (where)), where) < 0) { \
xf86Msg(X_ERROR, "ioctl EVIOCGBIT %s failed: %s\n", #which, strerror(errno)); \
return FALSE; \
}
get_bitmask (fd, 0, bits->ev);
get_bitmask (fd, EV_KEY, bits->key);
get_bitmask (fd, EV_REL, bits->rel);
get_bitmask (fd, EV_ABS, bits->abs);
get_bitmask (fd, EV_MSC, bits->msc);
get_bitmask (fd, EV_LED, bits->led);
get_bitmask (fd, EV_SND, bits->snd);
get_bitmask (fd, EV_FF, bits->ff);
#undef get_bitmask
return TRUE;
}

View File

@@ -84,18 +84,18 @@ EvdevBtnInit (DeviceIntPtr device)
CARD8 *map;
int i;
if (!pEvdev->state.buttons)
if (!pEvdev->state.btn)
return Success;
map = Xcalloc (sizeof (CARD8) * (pEvdev->state.buttons + 1));
map = Xcalloc (sizeof (CARD8) * (pEvdev->state.btn->buttons + 1));
for (i = 0; i <= pEvdev->state.buttons; i++)
for (i = 0; i <= pEvdev->state.btn->buttons; i++)
map[i] = i;
xf86Msg(X_ERROR, "%s (%d): Registering %d buttons.\n", __FILE__, __LINE__,
pEvdev->state.buttons);
if (!InitButtonClassDeviceStruct (device, pEvdev->state.buttons, map)) {
pEvdev->state.buttons = 0;
pEvdev->state.btn->buttons);
if (!InitButtonClassDeviceStruct (device, pEvdev->state.btn->buttons, map)) {
pEvdev->state.btn->buttons = 0;
return !Success;
}
@@ -112,11 +112,11 @@ EvdevBtnOn (DeviceIntPtr device)
evdevDevicePtr pEvdev = pInfo->private;
int i, blocked;
if (!pEvdev->state.buttons)
if (!pEvdev->state.btn)
return Success;
blocked = xf86BlockSIGIO ();
for (i = 1; i <= pEvdev->state.buttons; i++)
for (i = 1; i <= pEvdev->state.btn->buttons; i++)
xf86PostButtonEvent (device, 0, i, 0, 0, 0);
xf86UnblockSIGIO (blocked);
@@ -136,42 +136,47 @@ static void
EvdevBtnCalcRemap (InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int i, j, base, clear, fake;
for (i = 0, base = 1, fake = 0; i < pEvdev->state.real_buttons; i++) {
do {
clear = 1;
for (j = 0; j < REL_MAX; j++) {
if (pEvdev->state.relToBtnMap[j][0] == (i + base)) {
base++;
clear = 0;
break;
for (i = 0, base = 1, fake = 0; i < pEvdev->state.btn->real_buttons; i++) {
if (state->rel) {
do {
clear = 1;
for (j = 0; j < REL_MAX; j++) {
if (state->rel->btnMap[j][0] == (i + base)) {
base++;
clear = 0;
break;
}
if (state->rel->btnMap[j][1] == (i + base)) {
base++;
clear = 0;
break;
}
}
if (pEvdev->state.relToBtnMap[j][1] == (i + base)) {
base++;
clear = 0;
break;
}
}
} while (!clear);
} while (!clear);
}
if (!fake && base != 1)
fake = i;
pEvdev->state.buttons = pEvdev->state.buttonMap[i] = i + base;
state->btn->buttons = state->btn->map[i] = i + base;
}
if (pEvdev->state.real_buttons >= 3 && (!fake || fake >= 3)) {
base = pEvdev->state.buttonMap[1];
pEvdev->state.buttonMap[1] = pEvdev->state.buttonMap[2];
pEvdev->state.buttonMap[2] = base;
if (state->btn->real_buttons >= 3 && (!fake || fake >= 3)) {
base = state->btn->map[1];
state->btn->map[1] = state->btn->map[2];
state->btn->map[2] = base;
}
for (i = 0; i < REL_MAX; i++) {
if (pEvdev->state.relToBtnMap[i][0] > pEvdev->state.buttons)
pEvdev->state.buttons = pEvdev->state.relToBtnMap[i][0];
if (pEvdev->state.relToBtnMap[i][1] > pEvdev->state.buttons)
pEvdev->state.buttons = pEvdev->state.relToBtnMap[i][1];
if (state->rel) {
for (i = 0; i < REL_MAX; i++) {
if (state->rel->btnMap[i][0] > state->btn->buttons)
state->btn->buttons = state->rel->btnMap[i][0];
if (state->rel->btnMap[i][1] > state->btn->buttons)
state->btn->buttons = state->rel->btnMap[i][1];
}
}
}
@@ -180,30 +185,41 @@ int
EvdevBtnNew(InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
long key_bitmask[NBITS(KEY_MAX)];
int i;
evdevStatePtr state = &pEvdev->state;
int i, bit;
if (ioctl(pInfo->fd,
EVIOCGBIT(EV_KEY, KEY_MAX), key_bitmask) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
return !Success;
}
state->btn = Xcalloc (sizeof (evdevBtnRec));
for (i = 0; i < (BTN_JOYSTICK - BTN_MOUSE); i++)
if (TestBit (BTN_MOUSE + i, key_bitmask))
pEvdev->state.real_buttons = i + 1;
for (i = BTN_MISC; i < (KEY_OK - 1); i++)
if (TestBit (i, pEvdev->bits.key)) {
bit = i;
if ((bit >= BTN_MOUSE) && (bit < BTN_JOYSTICK)) {
bit -= BTN_MOUSE - BTN_MISC;
} else if ((bit >= BTN_MISC) && (bit < BTN_MOUSE)) {
bit += BTN_MOUSE - BTN_MISC;
}
bit -= BTN_MISC;
state->btn->real_buttons = bit + 1;
}
if (pEvdev->state.real_buttons)
xf86Msg(X_INFO, "%s: Found %d mouse buttons\n", pInfo->name, pEvdev->state.real_buttons);
if (state->btn->real_buttons)
xf86Msg(X_INFO, "%s: Found %d mouse buttons\n", pInfo->name, state->btn->real_buttons);
EvdevBtnCalcRemap (pInfo);
if (pEvdev->state.buttons)
xf86Msg(X_INFO, "%s: Configured %d mouse buttons\n", pInfo->name, pEvdev->state.buttons);
else
if (state->btn->buttons)
xf86Msg(X_INFO, "%s: Configured %d mouse buttons\n", pInfo->name, state->btn->buttons);
else {
Xfree (state->btn);
state->btn = NULL;
return !Success;
}
pInfo->flags |= XI86_SEND_DRAG_EVENTS | XI86_CONFIGURED;
/*
* FIXME: Mouse may not be accurate.
* Check buttons to see if we're actually a joystick or something.
*/
pInfo->type_name = XI_MOUSE;
return Success;
@@ -213,17 +229,23 @@ void
EvdevBtnProcess (InputInfoPtr pInfo, struct input_event *ev)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int button;
if (!pEvdev->state.buttons)
if (!state->btn)
return;
if ((ev->code >= BTN_MOUSE) && (ev->code < BTN_JOYSTICK)) {
button = ev->code - BTN_MOUSE;
button = pEvdev->state.buttonMap[button];
button = ev->code - BTN_MISC;
xf86PostButtonEvent (pInfo->dev, 0, button, ev->value, 0, 0);
} else {
/* FIXME: Handle the non-mouse case. */
if ((ev->code >= BTN_MOUSE) && (ev->code < BTN_JOYSTICK)) {
button -= BTN_MOUSE - BTN_MISC;
} else if ((ev->code >= BTN_MISC) && (ev->code < BTN_MOUSE)) {
button += BTN_MOUSE - BTN_MISC;
}
if (state->btn->state[button])
*state->btn->state[button] = ev->value;
button = state->btn->map[button];
xf86PostButtonEvent (pInfo->dev, 0, button, ev->value, 0, 0);
}

View File

@@ -328,10 +328,11 @@ EvdevKeyInit (DeviceIntPtr device)
keySyms.maxKeyCode = MIN_KEYCODE + ArrayLength(map) / GLYPHS_PER_KEY - 1;
XkbSetRulesDflts (state->xkb_rules, state->xkb_model, state->xkb_layout,
state->xkb_variant, state->xkb_options);
XkbSetRulesDflts (state->key->xkb_rules, state->key->xkb_model,
state->key->xkb_layout, state->key->xkb_variant,
state->key->xkb_options);
XkbInitKeyboardDeviceStruct (device, &state->xkbnames, &keySyms, modMap,
XkbInitKeyboardDeviceStruct (device, &state->key->xkbnames, &keySyms, modMap,
EvdevKbdBell, EvdevKbdCtrl);
return Success;
@@ -348,7 +349,6 @@ SetXkbOption(InputInfoPtr pInfo, char *name, char *value, char **option)
*option = NULL;
} else {
*option = s;
xf86Msg(X_CONFIG, "%s: %s: \"%s\"\n", pInfo->name, name, s);
}
}
}
@@ -358,44 +358,39 @@ EvdevKeyNew (InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
long key_bitmask[NBITS(KEY_MAX)];
int i;
if (ioctl(pInfo->fd,
EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
return !Success;
}
int i, keys = 0;
for (i = 0; i <= KEY_UNKNOWN; i++)
if (TestBit (i, key_bitmask)) {
state->keys = 1;
if (TestBit (i, pEvdev->bits.key)) {
keys = 1;
break;
}
if (!state->keys)
if (!keys)
return !Success;
state->key = Xcalloc (sizeof (evdevKeyRec));
pInfo->type_name = XI_KEYBOARD;
pInfo->flags |= XI86_KEYBOARD_CAPABLE | XI86_CONFIGURED;
SetXkbOption (pInfo, "XkbKeymap", NULL, &state->xkbnames.keymap);
if (state->xkbnames.keymap) {
SetXkbOption (pInfo, "XkbKeymap", NULL, &state->key->xkbnames.keymap);
if (state->key->xkbnames.keymap) {
xf86Msg(X_CONFIG, "%s: XkbKeymap overrides all other XKB settings\n",
pInfo->name);
} else {
SetXkbOption (pInfo, "XkbRules", __XKBDEFRULES__, &state->xkb_rules);
SetXkbOption (pInfo, "XkbModel", "evdev", &state->xkb_model);
SetXkbOption (pInfo, "XkbLayout", "us", &state->xkb_layout);
SetXkbOption (pInfo, "XkbVariant", NULL, &state->xkb_variant);
SetXkbOption (pInfo, "XkbOptions", NULL, &state->xkb_options);
SetXkbOption (pInfo, "XkbRules", __XKBDEFRULES__, &state->key->xkb_rules);
SetXkbOption (pInfo, "XkbModel", "evdev", &state->key->xkb_model);
SetXkbOption (pInfo, "XkbLayout", "us", &state->key->xkb_layout);
SetXkbOption (pInfo, "XkbVariant", NULL, &state->key->xkb_variant);
SetXkbOption (pInfo, "XkbOptions", NULL, &state->key->xkb_options);
SetXkbOption (pInfo, "XkbKeycodes", NULL, &state->xkbnames.keycodes);
SetXkbOption (pInfo, "XkbTypes", NULL, &state->xkbnames.types);
SetXkbOption (pInfo, "XkbCompat", NULL, &state->xkbnames.compat);
SetXkbOption (pInfo, "XkbSymbols", NULL, &state->xkbnames.symbols);
SetXkbOption (pInfo, "XkbGeometry", NULL, &state->xkbnames.geometry);
SetXkbOption (pInfo, "XkbKeycodes", NULL, &state->key->xkbnames.keycodes);
SetXkbOption (pInfo, "XkbTypes", NULL, &state->key->xkbnames.types);
SetXkbOption (pInfo, "XkbCompat", NULL, &state->key->xkbnames.compat);
SetXkbOption (pInfo, "XkbSymbols", NULL, &state->key->xkbnames.symbols);
SetXkbOption (pInfo, "XkbGeometry", NULL, &state->key->xkbnames.geometry);
}
return Success;

View File

@@ -114,24 +114,24 @@ EvdevRelSyn (InputInfoPtr pInfo)
evdevStatePtr state = &pEvdev->state;
int i, btn;
if (!state->rel_axes || state->mode != Relative)
if (!state->rel || state->mode != Relative)
return;
for (i = 0; i < state->rel_axes; i++) {
if ((state->rel_v[i] > 0) && (btn = state->relToBtnMap[i][0]))
EvdevBtnPostFakeClicks (pInfo, btn, state->rel_v[i]);
else if ((state->rel_v[i] < 0) && (btn = state->relToBtnMap[i][1]))
EvdevBtnPostFakeClicks (pInfo, btn, -state->rel_v[i]);
for (i = 0; i < state->rel->axes; i++) {
if ((state->rel->v[i] > 0) && (btn = state->rel->btnMap[i][0]))
EvdevBtnPostFakeClicks (pInfo, btn, state->rel->v[i]);
else if ((state->rel->v[i] < 0) && (btn = state->rel->btnMap[i][1]))
EvdevBtnPostFakeClicks (pInfo, btn, -state->rel->v[i]);
}
xf86PostMotionEvent(pInfo->dev, 0, 0, state->rel_axes,
state->rel_v[0], state->rel_v[1], state->rel_v[2], state->rel_v[3],
state->rel_v[4], state->rel_v[5], state->rel_v[6], state->rel_v[7],
state->rel_v[8], state->rel_v[9], state->rel_v[10], state->rel_v[11],
state->rel_v[12], state->rel_v[13], state->rel_v[14], state->rel_v[15]);
xf86PostMotionEvent(pInfo->dev, 0, 0, state->rel->axes,
state->rel->v[0], state->rel->v[1], state->rel->v[2], state->rel->v[3],
state->rel->v[4], state->rel->v[5], state->rel->v[6], state->rel->v[7],
state->rel->v[8], state->rel->v[9], state->rel->v[10], state->rel->v[11],
state->rel->v[12], state->rel->v[13], state->rel->v[14], state->rel->v[15]);
for (i = 0; i < REL_MAX; i++)
state->rel_v[i] = 0;
state->rel->v[i] = 0;
}
void
@@ -143,11 +143,11 @@ EvdevRelProcess (InputInfoPtr pInfo, struct input_event *ev)
if (ev->code >= REL_MAX)
return;
map = pEvdev->state.relMap[ev->code];
map = pEvdev->state.rel->map[ev->code];
if (map >= 0)
pEvdev->state.rel_v[map] += ev->value;
pEvdev->state.rel->v[map] += ev->value;
else
pEvdev->state.rel_v[-map] -= ev->value;
pEvdev->state.rel->v[-map] -= ev->value;
if (!pEvdev->state.sync)
EvdevRelSyn (pInfo);
@@ -160,12 +160,12 @@ EvdevRelInit (DeviceIntPtr device)
evdevDevicePtr pEvdev = pInfo->private;
int i;
if (!InitValuatorClassDeviceStruct(device, pEvdev->state.rel_axes,
if (!InitValuatorClassDeviceStruct(device, pEvdev->state.rel->axes,
miPointerGetMotionEvents,
miPointerGetMotionBufferSize(), 0))
return !Success;
for (i = 0; i < pEvdev->state.rel_axes; i++) {
for (i = 0; i < pEvdev->state.rel->axes; i++) {
xf86InitValuatorAxisStruct(device, i, 0, 0, 0, 0, 1);
xf86InitValuatorDefaults(device, i);
}
@@ -193,24 +193,19 @@ EvdevRelNew(InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
long rel_bitmask[NBITS(KEY_MAX)];
char *s, option[64];
int i, j, k = 0, real_axes;
if (ioctl(pInfo->fd,
EVIOCGBIT(EV_REL, REL_MAX), rel_bitmask) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
return !Success;
}
real_axes = 0;
for (i = 0; i < REL_MAX; i++)
if (TestBit (i, rel_bitmask))
if (TestBit (i, pEvdev->bits.rel))
real_axes++;
if (!real_axes && (state->abs_axes < 2))
if (!real_axes && (!state->abs || state->abs->axes < 2))
return !Success;
state->rel = Xcalloc (sizeof (evdevRelRec));
xf86Msg(X_INFO, "%s: Found %d relative axes.\n", pInfo->name,
real_axes);
xf86Msg(X_INFO, "%s: Configuring as pointer.\n", pInfo->name);
@@ -220,15 +215,15 @@ EvdevRelNew(InputInfoPtr pInfo)
pInfo->conversion_proc = EvdevConvert;
for (i = 0, j = 0; i < REL_MAX; i++) {
if (!TestBit (i, rel_bitmask))
if (!TestBit (i, pEvdev->bits.rel))
continue;
snprintf(option, sizeof(option), "%sRelativeAxisMap", axis_names[i]);
s = xf86SetStrOption(pInfo->options, option, "0");
if (s && (k = strtol(s, NULL, 0)))
state->relMap[i] = k;
state->rel->map[i] = k;
else
state->relMap[i] = j;
state->rel->map[i] = j;
if (s && k)
xf86Msg(X_CONFIG, "%s: %s: %d.\n", pInfo->name, option, k);
@@ -242,30 +237,30 @@ EvdevRelNew(InputInfoPtr pInfo)
else
s = xf86SetStrOption(pInfo->options, option, "0 0");
k = state->relMap[i];
k = state->rel->map[i];
if (!s || (sscanf(s, "%d %d", &state->relToBtnMap[k][0],
&state->relToBtnMap[k][1]) != 2))
state->relToBtnMap[k][0] = state->relToBtnMap[k][1] = 0;
if (!s || (sscanf(s, "%d %d", &state->rel->btnMap[k][0],
&state->rel->btnMap[k][1]) != 2))
state->rel->btnMap[k][0] = state->rel->btnMap[k][1] = 0;
if (state->relToBtnMap[k][0] || state->relToBtnMap[k][1])
if (state->rel->btnMap[k][0] || state->rel->btnMap[k][1])
xf86Msg(X_CONFIG, "%s: %s: %d %d.\n", pInfo->name, option,
state->relToBtnMap[k][0], state->relToBtnMap[k][1]);
state->rel->btnMap[k][0], state->rel->btnMap[k][1]);
j++;
}
state->rel_axes = real_axes;
state->rel->axes = real_axes;
for (i = 0; i < REL_MAX; i++)
if (state->relMap[i] > state->rel_axes)
state->rel_axes = state->relMap[i];
if (state->rel->map[i] > state->rel->axes)
state->rel->axes = state->rel->map[i];
if ((state->abs_axes >= 2) && (state->rel_axes < 2))
state->rel_axes = 2;
if (state->abs && (state->abs->axes >= 2) && (state->rel->axes < 2))
state->rel->axes = 2;
if (state->rel_axes != real_axes)
if (state->rel->axes != real_axes)
xf86Msg(X_CONFIG, "%s: Configuring %d relative axes.\n", pInfo->name,
state->rel_axes);
state->rel->axes);
return Success;
}