diff options
Diffstat (limited to 'src/evdev_axes.c')
-rw-r--r-- | src/evdev_axes.c | 321 |
1 files changed, 242 insertions, 79 deletions
diff --git a/src/evdev_axes.c b/src/evdev_axes.c index 4650b5f..6879ab1 100644 --- a/src/evdev_axes.c +++ b/src/evdev_axes.c @@ -49,6 +49,8 @@ #include <xf86_OSproc.h> +#undef DEBUG + static char *rel_axis_names[] = { "X", "Y", @@ -136,6 +138,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,106 +153,187 @@ 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; evdevAxesPtr axes = state->axes; - int i, btn; + int i; - for (i = 0; i < state->axes->axes; i++) { - if ((state->axes->v[i] > 0) && (btn = state->axes->btnMap[i][0])) - EvdevBtnPostFakeClicks (pInfo, btn, state->axes->v[i]); - else if ((state->axes->v[i] < 0) && (btn = state->axes->btnMap[i][1])) - EvdevBtnPostFakeClicks (pInfo, btn, -state->axes->v[i]); - } +#if DEBUG + if (skip_xy == 2 && (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]); +#endif - 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]); + /* 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 +EvdevAxesAbsSynCfg (InputInfoPtr pInfo) +{ + evdevDevicePtr pEvdev = pInfo->private; + evdevStatePtr state = &pEvdev->state; + struct input_absinfo absinfo; + int i; + + for (i = 0; i < ABS_MAX; i++) { + if (!test_bit (i, pEvdev->bits.abs)) + continue; + + if (ioctl (pInfo->fd, EVIOCGABS(i), &absinfo) < 0) { + xf86Msg(X_ERROR, "ioctl EVIOCGABS (%d) failed: %s\n", i, strerror(errno)); + continue; + } + state->abs->min[state->abs->map[i]] = absinfo.minimum; + state->abs->max[state->abs->map[i]] = absinfo.maximum; + } - for (i = 0; i < ABS_MAX; i++) - state->axes->v[i] = 0; } static void -EvdevAxesAbsSyn (InputInfoPtr pInfo) +EvdevAxesAbsSynRep (InputInfoPtr pInfo) { evdevDevicePtr pEvdev = pInfo->private; evdevStatePtr state = &pEvdev->state; - int i, n; + int i = 0; + Bool skip_xy = 0; if (!state->axes || !state->abs || !state->abs->count) return; - n = state->abs->n & 1; - state->abs->n++; - 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_x && state->abs->v[0] != state->abs->old_x) { + state->axes->v[0] = 0; + state->abs->reset_x = 0; +#if DEBUG + xf86Msg(X_INFO, "%s: Resetting X.\n", pInfo->name); +#endif + } else + state->axes->v[0] = state->abs->v[0] - state->abs->old_x; + + if (state->abs->reset_y && state->abs->v[1] != state->abs->old_y) { + state->axes->v[1] = 0; + state->abs->reset_y = 0; +#if DEBUG + xf86Msg(X_INFO, "%s: Resetting Y.\n", pInfo->name); +#endif + } else + state->axes->v[1] = state->abs->v[1] - state->abs->old_y; + + state->abs->old_x = state->abs->v[0]; + state->abs->old_y = state->abs->v[1]; + 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++) - state->axes->v[i] = xf86ScaleAxis (state->abs->v[n][i], + state->axes->v[i] = xf86ScaleAxis (state->abs->v[i], 0, state->abs->scale[i], 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[0], state->abs->v[1], 0, 0, 0, 0, &conv_x, &conv_y); xf86XInputSetScreen (pInfo, state->abs->screen, conv_x, conv_y); } for (; i < ABS_MAX; i++) - state->axes->v[i] = state->abs->v[n][i]; + state->axes->v[i] = state->abs->v[i]; - EvdevAxesRealSyn (pInfo, 1); + EvdevAxesRealSyn (pInfo, 1, skip_xy); state->abs->count = 0; } static void -EvdevAxesRelSyn (InputInfoPtr pInfo) +EvdevAxesRelSynRep (InputInfoPtr pInfo) { evdevDevicePtr pEvdev = pInfo->private; evdevStatePtr state = &pEvdev->state; - int i; + evdevRelPtr rel = state->rel; + int i, btn; if (!state->axes || !state->rel || !state->rel->count) return; for (i = 0; i < REL_MAX; i++) { - state->axes->v[i] = state->rel->v[i]; - state->rel->v[i] = 0; + if (rel->btnMap[i][0] || rel->btnMap[i][1]) { + if ((rel->v[i] > 0) && (btn = rel->btnMap[i][0])) + EvdevBtnPostFakeClicks (pInfo, btn, rel->v[i]); + else if ((rel->v[i] < 0) && (btn = rel->btnMap[i][1])) + EvdevBtnPostFakeClicks (pInfo, btn, -rel->v[i]); + } + + state->axes->v[i] = rel->v[i]; + rel->v[i] = 0; } - EvdevAxesRealSyn (pInfo, 0); - state->rel->count = 0; + EvdevAxesRealSyn (pInfo, 0, 0); + rel->count = 0; +} + +void +EvdevAxesSynRep (InputInfoPtr pInfo) +{ + EvdevAxesAbsSynRep (pInfo); + EvdevAxesRelSynRep (pInfo); } void -EvdevAxesSyn (InputInfoPtr pInfo) +EvdevAxesSynCfg (InputInfoPtr pInfo) { - EvdevAxesAbsSyn (pInfo); - EvdevAxesRelSyn (pInfo); + EvdevAxesAbsSynCfg (pInfo); +/* EvdevAxesRelSynCfg (pInfo);*/ } void @@ -256,7 +341,6 @@ EvdevAxesAbsProcess (InputInfoPtr pInfo, struct input_event *ev) { evdevDevicePtr pEvdev = pInfo->private; evdevStatePtr state = &pEvdev->state; - int n = state->abs->n & 1; int map; if (ev->code >= ABS_MAX) @@ -265,14 +349,14 @@ EvdevAxesAbsProcess (InputInfoPtr pInfo, struct input_event *ev) /* FIXME: Handle inverted axes properly. */ map = state->abs->map[ev->code]; if (map >= 0) - state->abs->v[n][map] = ev->value; + state->abs->v[map] = ev->value; else - state->abs->v[n][-map] = ev->value; + state->abs->v[-map] = ev->value; state->abs->count++; if (!state->sync) - EvdevAxesAbsSyn (pInfo); + EvdevAxesAbsSynRep (pInfo); } void @@ -294,7 +378,7 @@ EvdevAxesRelProcess (InputInfoPtr pInfo, struct input_event *ev) state->rel->count++; if (!state->sync) - EvdevAxesRelSyn (pInfo); + EvdevAxesRelSynRep (pInfo); } int @@ -310,12 +394,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 +449,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 +504,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; @@ -450,13 +567,13 @@ EvdevAxisRelNew(InputInfoPtr pInfo) k = state->rel->map[i]; - if (!s || (sscanf(s, "%d %d", &state->axes->btnMap[k][0], - &state->axes->btnMap[k][1]) != 2)) - state->axes->btnMap[k][0] = state->axes->btnMap[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->axes->btnMap[k][0] || state->axes->btnMap[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->axes->btnMap[k][0], state->axes->btnMap[k][1]); + state->rel->btnMap[k][0], state->rel->btnMap[k][1]); j++; } @@ -467,26 +584,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 +689,18 @@ EvdevAxesInit (DeviceIntPtr device) return Success; } +static void +EvdevAxesTouchCallback (InputInfoPtr pInfo, int button, int value) +{ + evdevDevicePtr pEvdev = pInfo->private; + evdevStatePtr state = &pEvdev->state; + +#if DEBUG + xf86Msg(X_INFO, "%s: Touch callback; %d.\n", pInfo->name, value); +#endif + if (state->abs->use_touch) { + state->abs->touch = !!value; + if (value) + state->abs->reset_x = state->abs->reset_y = 1; + } +} |