summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/evdev.c11
-rw-r--r--src/evdev.h13
-rw-r--r--src/evdev_axes.c216
-rw-r--r--src/evdev_btn.c138
4 files changed, 322 insertions, 56 deletions
diff --git a/src/evdev.c b/src/evdev.c
index 00323ae..2d8d120 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -228,6 +228,7 @@ EvdevSwitchMode (ClientPtr client, DeviceIntPtr device, int mode)
{
case Absolute:
case Relative:
+ xf86Msg(X_INFO, "%s: Switching mode to %d.\n", pInfo->name, mode);
if (state->abs)
state->mode = mode;
else
@@ -298,9 +299,13 @@ EvdevNew(evdevDriverPtr driver, evdevDevicePtr device)
}
- /* XXX: Note, the order of these is important. */
- EvdevAxesNew (pInfo);
- EvdevBtnNew (pInfo);
+ /* XXX: Note, the order of these is (maybe) still important. */
+ EvdevAxesNew0 (pInfo);
+ EvdevBtnNew0 (pInfo);
+
+ EvdevAxesNew1 (pInfo);
+ EvdevBtnNew1 (pInfo);
+
if (device->state.can_grab)
EvdevKeyNew (pInfo);
diff --git a/src/evdev.h b/src/evdev.h
index a399571..2a65530 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -151,7 +151,7 @@ typedef struct {
int real_buttons;
int buttons;
CARD8 map[EVDEV_MAXBUTTONS];
- int *state[EVDEV_MAXBUTTONS];
+ void (*callback[EVDEV_MAXBUTTONS])(InputInfoPtr pInfo, int button, int value);
} evdevBtnRec, *evdevBtnPtr;
typedef struct {
@@ -164,6 +164,9 @@ typedef struct {
int map[ABS_MAX];
int scale[2];
int screen; /* Screen number for this device. */
+ Bool use_touch;
+ Bool touch;
+ Bool reset;
} evdevAbsRec, *evdevAbsPtr;
typedef struct {
@@ -247,14 +250,18 @@ Bool evdevGetBits (int fd, evdevBitsPtr bits);
int EvdevBtnInit (DeviceIntPtr device);
int EvdevBtnOn (DeviceIntPtr device);
int EvdevBtnOff (DeviceIntPtr device);
-int EvdevBtnNew(InputInfoPtr pInfo);
+int EvdevBtnNew0(InputInfoPtr pInfo);
+int EvdevBtnNew1(InputInfoPtr pInfo);
void EvdevBtnProcess (InputInfoPtr pInfo, struct input_event *ev);
void EvdevBtnPostFakeClicks(InputInfoPtr pInfo, int button, int count);
+int EvdevBtnFind (InputInfoPtr pInfo, const char *button);
+int EvdevBtnExists (InputInfoPtr pInfo, int button);
int EvdevAxesInit (DeviceIntPtr device);
int EvdevAxesOn (DeviceIntPtr device);
int EvdevAxesOff (DeviceIntPtr device);
-int EvdevAxesNew(InputInfoPtr pInfo);
+int EvdevAxesNew0(InputInfoPtr pInfo);
+int EvdevAxesNew1(InputInfoPtr pInfo);
void EvdevAxesAbsProcess (InputInfoPtr pInfo, struct input_event *ev);
void EvdevAxesRelProcess (InputInfoPtr pInfo, struct input_event *ev);
void EvdevAxesSyn (InputInfoPtr pInfo);
diff --git a/src/evdev_axes.c b/src/evdev_axes.c
index 0d9b5a7..751978f 100644
--- a/src/evdev_axes.c
+++ b/src/evdev_axes.c
@@ -136,6 +136,8 @@ static char *abs_axis_names[] = {
NULL
};
+static void EvdevAxesTouchCallback (InputInfoPtr pInfo, int button, int value);
+
static Bool
EvdevConvert(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
int v3, int v4, int v5, int *x, int *y)
@@ -149,7 +151,7 @@ EvdevConvert(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
}
static void
-EvdevAxesRealSyn (InputInfoPtr pInfo, int absolute)
+EvdevAxesRealSyn (InputInfoPtr pInfo, int absolute, int skip_xy)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
@@ -163,27 +165,60 @@ EvdevAxesRealSyn (InputInfoPtr pInfo, int absolute)
EvdevBtnPostFakeClicks (pInfo, btn, -state->axes->v[i]);
}
- xf86PostMotionEvent(pInfo->dev, absolute, 0,
- state->axes->axes,
- axes->v[0x00], axes->v[0x01], axes->v[0x02], axes->v[0x03],
- axes->v[0x04], axes->v[0x05], axes->v[0x06], axes->v[0x07],
- axes->v[0x08], axes->v[0x09], axes->v[0x0a], axes->v[0x0b],
- axes->v[0x0c], axes->v[0x0d], axes->v[0x0e], axes->v[0x0f],
- axes->v[0x10], axes->v[0x11], axes->v[0x12], axes->v[0x13],
- axes->v[0x14], axes->v[0x15], axes->v[0x16], axes->v[0x17],
- axes->v[0x18], axes->v[0x19], axes->v[0x1a], axes->v[0x1b],
- axes->v[0x1c], axes->v[0x1d], axes->v[0x1e], axes->v[0x1f],
- axes->v[0x20], axes->v[0x21], axes->v[0x22], axes->v[0x23],
- axes->v[0x24], axes->v[0x25], axes->v[0x26], axes->v[0x27],
- axes->v[0x28], axes->v[0x29], axes->v[0x2a], axes->v[0x2b],
- axes->v[0x2c], axes->v[0x2d], axes->v[0x2e], axes->v[0x2f],
- axes->v[0x30], axes->v[0x31], axes->v[0x32], axes->v[0x33],
- axes->v[0x34], axes->v[0x35], axes->v[0x36], axes->v[0x37],
- axes->v[0x38], axes->v[0x39], axes->v[0x3a], axes->v[0x3b],
- axes->v[0x3c], axes->v[0x3d], axes->v[0x3e], axes->v[0x3f]);
-
- for (i = 0; i < ABS_MAX; i++)
- state->axes->v[i] = 0;
+ /*
+ if (skip_xy && (axes->v[0] || axes->v[1]))
+ xf86Msg(X_INFO, "%s: skip_xy: %d, x: %d, y: %d.\n", pInfo->name, skip_xy, axes->v[0], axes->v[1]);
+ */
+
+ /* FIXME: This is a truly evil kluge. */
+ if (skip_xy == 1 && state->axes->axes >= 2)
+ xf86PostMotionEvent(pInfo->dev, absolute, 2,
+ state->axes->axes - 2,
+ axes->v[0x02], axes->v[0x03],
+ axes->v[0x04], axes->v[0x05], axes->v[0x06], axes->v[0x07],
+ axes->v[0x08], axes->v[0x09], axes->v[0x0a], axes->v[0x0b],
+ axes->v[0x0c], axes->v[0x0d], axes->v[0x0e], axes->v[0x0f],
+ axes->v[0x10], axes->v[0x11], axes->v[0x12], axes->v[0x13],
+ axes->v[0x14], axes->v[0x15], axes->v[0x16], axes->v[0x17],
+ axes->v[0x18], axes->v[0x19], axes->v[0x1a], axes->v[0x1b],
+ axes->v[0x1c], axes->v[0x1d], axes->v[0x1e], axes->v[0x1f],
+ axes->v[0x20], axes->v[0x21], axes->v[0x22], axes->v[0x23],
+ axes->v[0x24], axes->v[0x25], axes->v[0x26], axes->v[0x27],
+ axes->v[0x28], axes->v[0x29], axes->v[0x2a], axes->v[0x2b],
+ axes->v[0x2c], axes->v[0x2d], axes->v[0x2e], axes->v[0x2f],
+ axes->v[0x30], axes->v[0x31], axes->v[0x32], axes->v[0x33],
+ axes->v[0x34], axes->v[0x35], axes->v[0x36], axes->v[0x37],
+ axes->v[0x38], axes->v[0x39], axes->v[0x3a], axes->v[0x3b],
+ axes->v[0x3c], axes->v[0x3d], axes->v[0x3e], axes->v[0x3f]);
+ else
+ xf86PostMotionEvent(pInfo->dev, absolute, 0,
+ state->axes->axes,
+ axes->v[0x00], axes->v[0x01], axes->v[0x02], axes->v[0x03],
+ axes->v[0x04], axes->v[0x05], axes->v[0x06], axes->v[0x07],
+ axes->v[0x08], axes->v[0x09], axes->v[0x0a], axes->v[0x0b],
+ axes->v[0x0c], axes->v[0x0d], axes->v[0x0e], axes->v[0x0f],
+ axes->v[0x10], axes->v[0x11], axes->v[0x12], axes->v[0x13],
+ axes->v[0x14], axes->v[0x15], axes->v[0x16], axes->v[0x17],
+ axes->v[0x18], axes->v[0x19], axes->v[0x1a], axes->v[0x1b],
+ axes->v[0x1c], axes->v[0x1d], axes->v[0x1e], axes->v[0x1f],
+ axes->v[0x20], axes->v[0x21], axes->v[0x22], axes->v[0x23],
+ axes->v[0x24], axes->v[0x25], axes->v[0x26], axes->v[0x27],
+ axes->v[0x28], axes->v[0x29], axes->v[0x2a], axes->v[0x2b],
+ axes->v[0x2c], axes->v[0x2d], axes->v[0x2e], axes->v[0x2f],
+ axes->v[0x30], axes->v[0x31], axes->v[0x32], axes->v[0x33],
+ axes->v[0x34], axes->v[0x35], axes->v[0x36], axes->v[0x37],
+ axes->v[0x38], axes->v[0x39], axes->v[0x3a], axes->v[0x3b],
+ axes->v[0x3c], axes->v[0x3d], axes->v[0x3e], axes->v[0x3f]);
+
+ if (!skip_xy)
+ for (i = 0; i < ABS_MAX; i++)
+ state->axes->v[i] = 0;
+ else if (skip_xy == 1)
+ for (i = 2; i < ABS_MAX; i++)
+ state->axes->v[i] = 0;
+ else if (skip_xy == 2)
+ for (i = 0; i < 2; i++)
+ state->axes->v[i] = 0;
}
static void
@@ -192,6 +227,7 @@ EvdevAxesAbsSyn (InputInfoPtr pInfo)
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int i, n;
+ Bool skip_xy = 0;
if (!state->axes || !state->abs || !state->abs->count)
return;
@@ -201,10 +237,21 @@ EvdevAxesAbsSyn (InputInfoPtr pInfo)
i = 0;
if (state->mode == Relative && state->abs->axes >= 2) {
- for (i = 0; i < 2; i++)
- state->axes->v[i] = state->abs->v[n][i] - state->abs->v[!n][i];
- EvdevAxesRealSyn (pInfo, 0);
- } else if (state->mode == Absolute && state->abs->screen >= 0 && state->abs->axes >= 2) {
+ if (!state->abs->use_touch || state->abs->touch) {
+ if (state->abs->reset) {
+ for (i = 0; i < 2; i++)
+ state->axes->v[i] = 0;
+ xf86Msg(X_INFO, "%s: Resetting.\n", pInfo->name);
+ state->abs->reset = 0;
+ } else
+ for (i = 0; i < 2; i++) {
+ state->axes->v[i] = state->abs->v[n][i] - state->abs->v[!n][i];
+ state->axes->v[i] /= 4;
+ }
+ EvdevAxesRealSyn (pInfo, 0, 2);
+ }
+ skip_xy = 1;
+ } else if (state->mode == Absolute && state->abs->screen != -1 && state->abs->axes >= 2) {
int conv_x, conv_y;
for (i = 0; i < 2; i++)
@@ -221,7 +268,7 @@ EvdevAxesAbsSyn (InputInfoPtr pInfo)
for (; i < ABS_MAX; i++)
state->axes->v[i] = state->abs->v[n][i];
- EvdevAxesRealSyn (pInfo, 1);
+ EvdevAxesRealSyn (pInfo, 1, skip_xy);
state->abs->count = 0;
}
@@ -240,7 +287,7 @@ EvdevAxesRelSyn (InputInfoPtr pInfo)
state->rel->v[i] = 0;
}
- EvdevAxesRealSyn (pInfo, 0);
+ EvdevAxesRealSyn (pInfo, 0, 0);
state->rel->count = 0;
}
@@ -310,12 +357,12 @@ EvdevAxesOff (DeviceIntPtr device)
}
static int
-EvdevAxisAbsNew(InputInfoPtr pInfo)
+EvdevAxisAbsNew0(InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
struct input_absinfo absinfo;
- char *s, option[64];
+ char option[64];
int i, j, k = 0, real_axes;
real_axes = 0;
@@ -365,9 +412,41 @@ EvdevAxisAbsNew(InputInfoPtr pInfo)
state->abs->axes = state->abs->map[i];
}
- if (state->abs->axes != real_axes)
- xf86Msg(X_CONFIG, "%s: Configuring %d absolute axes.\n", pInfo->name,
- state->abs->axes);
+ return Success;
+}
+
+static int
+EvdevAxisAbsNew1(InputInfoPtr pInfo)
+{
+ evdevDevicePtr pEvdev = pInfo->private;
+ evdevStatePtr state = &pEvdev->state;
+ char *s;
+ int k = 0;
+
+ if (!state->abs)
+ return !Success;
+
+ xf86Msg(X_CONFIG, "%s: Configuring %d absolute axes.\n", pInfo->name,
+ state->abs->axes);
+
+ {
+ int btn;
+
+ s = xf86SetStrOption(pInfo->options, "AbsoluteTouch", "DIGI_Touch");
+ btn = EvdevBtnFind (pInfo, s);
+ if (btn != -1) {
+ if (EvdevBtnExists (pInfo, btn)) {
+ state->abs->use_touch = 1;
+ xf86Msg(X_ERROR, "%s: Button: %d.\n", pInfo->name, btn);
+ xf86Msg(X_ERROR, "%s: state->btn: %p.\n", pInfo->name, state->btn);
+ state->btn->callback[btn] = &EvdevAxesTouchCallback;
+ } else {
+ xf86Msg(X_ERROR, "%s: AbsoluteTouch: '%s' does not exist.\n", pInfo->name, s);
+ }
+ } else {
+ xf86Msg(X_ERROR, "%s: AbsoluteTouch: '%s' is not a valid button name.\n", pInfo->name, s);
+ }
+ }
s = xf86SetStrOption(pInfo->options, "Mode", "Absolute");
if (!strcasecmp(s, "Absolute")) {
@@ -388,19 +467,20 @@ EvdevAxisAbsNew(InputInfoPtr pInfo)
if (k < screenInfo.numScreens && k >= 0) {
state->abs->screen = k;
xf86Msg(X_CONFIG, "%s: AbsoluteScreen: %d.\n", pInfo->name, k);
+
+ state->abs->scale[0] = screenInfo.screens[state->abs->screen]->width;
+ state->abs->scale[1] = screenInfo.screens[state->abs->screen]->height;
} else {
- state->abs->screen = 0;
- xf86Msg(X_CONFIG, "%s: AbsoluteScreen: %d is not a valid screen.\n", pInfo->name, k);
+ if (k != -1)
+ xf86Msg(X_CONFIG, "%s: AbsoluteScreen: %d is not a valid screen.\n", pInfo->name, k);
+ state->abs->screen = -1;
}
- state->abs->scale[0] = screenInfo.screens[state->abs->screen]->width;
- state->abs->scale[1] = screenInfo.screens[state->abs->screen]->height;
-
return Success;
}
static int
-EvdevAxisRelNew(InputInfoPtr pInfo)
+EvdevAxisRelNew0(InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
@@ -467,26 +547,57 @@ EvdevAxisRelNew(InputInfoPtr pInfo)
state->rel->axes = state->rel->map[i];
if (state->abs && (state->abs->axes >= 2) && (state->rel->axes < 2))
- state->rel->axes = 2;
+ state->rel->axes += 2;
- if (state->rel->axes != real_axes)
- xf86Msg(X_CONFIG, "%s: Configuring %d relative axes.\n", pInfo->name,
- state->rel->axes);
+ return Success;
+}
+
+static int
+EvdevAxisRelNew1(InputInfoPtr pInfo)
+{
+ evdevDevicePtr pEvdev = pInfo->private;
+ evdevStatePtr state = &pEvdev->state;
+
+ if (!state->rel)
+ return !Success;
+
+ xf86Msg(X_CONFIG, "%s: Configuring %d relative axes.\n", pInfo->name,
+ state->rel->axes);
return Success;
}
int
-EvdevAxesNew (InputInfoPtr pInfo)
+EvdevAxesNew0 (InputInfoPtr pInfo)
+{
+ evdevDevicePtr pEvdev = pInfo->private;
+ evdevStatePtr state = &pEvdev->state;
+ int ret = Success;
+
+ state->axes = Xcalloc (sizeof (evdevAxesRec));
+ if (EvdevAxisAbsNew0(pInfo) != Success)
+ ret = !Success;
+ if (EvdevAxisRelNew0(pInfo) != Success)
+ ret = !Success;
+ if (!state->abs && !state->rel) {
+ Xfree (state->axes);
+ state->axes = NULL;
+ }
+
+ return ret;
+}
+
+int
+EvdevAxesNew1 (InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int ret = Success;
state->axes = Xcalloc (sizeof (evdevAxesRec));
- if (EvdevAxisAbsNew(pInfo) != Success)
+ if (EvdevAxisAbsNew1(pInfo) != Success)
ret = !Success;
- if (EvdevAxisRelNew(pInfo) != Success)
+ if (EvdevAxisRelNew1(pInfo) != Success)
ret = !Success;
if (!state->abs && !state->rel) {
Xfree (state->axes);
@@ -541,3 +652,16 @@ EvdevAxesInit (DeviceIntPtr device)
return Success;
}
+static void
+EvdevAxesTouchCallback (InputInfoPtr pInfo, int button, int value)
+{
+ evdevDevicePtr pEvdev = pInfo->private;
+ evdevStatePtr state = &pEvdev->state;
+
+ xf86Msg(X_INFO, "%s: Touch callback; %d.\n", pInfo->name, value);
+ if (state->abs->use_touch) {
+ state->abs->touch = !!value;
+ if (value)
+ state->abs->reset = 1;
+ }
+}
diff --git a/src/evdev_btn.c b/src/evdev_btn.c
index 35edee1..9a9b65e 100644
--- a/src/evdev_btn.c
+++ b/src/evdev_btn.c
@@ -51,6 +51,91 @@
#include <xf86Module.h>
+static char *button_names[] = {
+ "MISC_0",
+ "MISC_1",
+ "MISC_2",
+ "MISC_3",
+ "MISC_4",
+ "MISC_5",
+ "MISC_6",
+ "MISC_7",
+ "MISC_8",
+ "MISC_9",
+ "MISC_10",
+ "MISC_11",
+ "MISC_12",
+ "MISC_13",
+ "MISC_14",
+ "MISC_15",
+ "MOUSE_LEFT",
+ "MOUSE_RIGHT",
+ "MOUSE_MIDDLE",
+ "MOUSE_SIDE",
+ "MOUSE_EXTRA",
+ "MOUSE_FORWARD",
+ "MOUSE_BACK",
+ "MOUSE_TASK",
+ "MOUSE_8",
+ "MOUSE_9",
+ "MOUSE_10",
+ "MOUSE_12",
+ "MOUSE_13",
+ "MOUSE_14",
+ "MOUSE_15",
+ "JOY_TRIGGER",
+ "JOY_THUMB",
+ "JOY_THUMB2",
+ "JOY_TOP",
+ "JOY_TOP2",
+ "JOY_PINKIE",
+ "JOY_BASE",
+ "JOY_BASE2",
+ "JOY_BASE3",
+ "JOY_BASE4",
+ "JOY_BASE5",
+ "JOY_BASE6",
+ "JOY_12",
+ "JOY_13",
+ "JOY_14",
+ "JOY_DEAD",
+ "GAME_A",
+ "GAME_B",
+ "GAME_C",
+ "GAME_X",
+ "GAME_Y",
+ "GAME_Z",
+ "GAME_TL",
+ "GAME_TR",
+ "GAME_TL2",
+ "GAME_TR2",
+ "GAME_SELECT",
+ "GAME_START",
+ "GAME_MODE",
+ "GAME_THUMBL",
+ "GAME_THUMBR",
+ "GAME_15",
+ "DIGI_TOOL_PEN",
+ "DIGI_TOOL_RUBBER",
+ "DIGI_TOOL_BRUSH",
+ "DIGI_TOOL_PENCIL",
+ "DIGI_TOOL_AIRBRUSH",
+ "DIGI_TOOL_FINGER",
+ "DIGI_TOOL_MOUSE",
+ "DIGI_TOOL_LENS",
+ "DIGI_8",
+ "DIGI_9",
+ "DIGI_TOUCH",
+ "DIGI_STYLUS",
+ "DIGI_STYLUS2",
+ "DIGI_TOOL_DOUBLETAP",
+ "DIGI_TOOL_TRIPLETAP",
+ "DIGI_15",
+ "WHEEL_GEAR_UP",
+ "WHEEL_GEAR_DOWN",
+ NULL
+};
+
void
EvdevBtnPostFakeClicks(InputInfoPtr pInfo, int button, int count)
{
@@ -168,7 +253,7 @@ EvdevBtnCalcRemap (InputInfoPtr pInfo)
int
-EvdevBtnNew(InputInfoPtr pInfo)
+EvdevBtnNew0(InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
@@ -191,6 +276,18 @@ EvdevBtnNew(InputInfoPtr pInfo)
if (state->btn->real_buttons)
xf86Msg(X_INFO, "%s: Found %d mouse buttons\n", pInfo->name, state->btn->real_buttons);
+ return Success;
+}
+
+int
+EvdevBtnNew1(InputInfoPtr pInfo)
+{
+ evdevDevicePtr pEvdev = pInfo->private;
+ evdevStatePtr state = &pEvdev->state;
+
+ if (!state->btn)
+ return !Success;
+
EvdevBtnCalcRemap (pInfo);
if (state->btn->buttons)
@@ -221,7 +318,7 @@ EvdevBtnProcess (InputInfoPtr pInfo, struct input_event *ev)
if (!state->btn)
return;
- button = ev->code - BTN_MISC;
+ button = ev->code;
if ((ev->code >= BTN_MOUSE) && (ev->code < BTN_JOYSTICK)) {
button -= BTN_MOUSE - BTN_MISC;
@@ -229,9 +326,42 @@ EvdevBtnProcess (InputInfoPtr pInfo, struct input_event *ev)
button += BTN_MOUSE - BTN_MISC;
}
- if (state->btn->state[button])
- *state->btn->state[button] = ev->value;
+ button -= BTN_MISC;
+
+ if (state->btn->callback[button])
+ state->btn->callback[button](pInfo, button, ev->value);
button = state->btn->map[button];
xf86PostButtonEvent (pInfo->dev, 0, button, ev->value, 0, 0);
}
+
+int
+EvdevBtnFind (InputInfoPtr pInfo, const char *button)
+{
+ int i;
+
+ for (i = 0; button_names[i]; i++)
+ if (!strcasecmp(button, button_names[i]))
+ return i + 1;
+
+ return -1;
+}
+
+int
+EvdevBtnExists (InputInfoPtr pInfo, int button)
+{
+ evdevDevicePtr pEvdev = pInfo->private;
+
+ button += BTN_MISC;
+
+ xf86Msg(X_INFO, "%s: Checking button %s (%d)\n", pInfo->name, button_names[button - BTN_MISC], button);
+
+ if ((button >= BTN_MOUSE) && (button < BTN_JOYSTICK)) {
+ button -= BTN_MOUSE - BTN_MISC;
+ } else if ((button >= BTN_MISC) && (button < BTN_MOUSE)) {
+ button += BTN_MOUSE - BTN_MISC;
+ }
+
+ xf86Msg(X_INFO, "%s: Checking bit %d\n", pInfo->name, button);
+ return test_bit(button, pEvdev->bits.key);
+}