diff options
-rw-r--r-- | src/evdev.c | 11 | ||||
-rw-r--r-- | src/evdev.h | 13 | ||||
-rw-r--r-- | src/evdev_axes.c | 216 | ||||
-rw-r--r-- | src/evdev_btn.c | 138 |
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); +} |