diff options
author | Zephaniah E. Hull <warp@aehallh.com> | 2006-04-08 17:23:06 +0000 |
---|---|---|
committer | Zephaniah E. Hull <warp@aehallh.com> | 2006-04-08 17:23:06 +0000 |
commit | c97fdb44493e55f3456222855293016a596ff56e (patch) | |
tree | ee32d366365e870a35ab04bdcd173d4a4b00f7e1 /src/evdev_axes.c | |
parent | Unlibcwrap. Bump server version requirement. Bump to 1.1.0. (diff) | |
download | xf86-input-evdev-c97fdb44493e55f3456222855293016a596ff56e.tar.gz xf86-input-evdev-c97fdb44493e55f3456222855293016a596ff56e.tar.bz2 xf86-input-evdev-c97fdb44493e55f3456222855293016a596ff56e.zip |
Remove evdev_abs.c and evdev_rel.c. Added evdev_axes.c.
Change the calls to refer to EvdevAxes instead of Abs and Rel. Include
mipointer.h. (Fixes a compile error.) Remove an unused variable from
EvdevReadInput.
Removed evdev_abs.c and evdev_rel.c, added evdev_axes.c. Added count to rel
and abs. Moved btnMap from rel to the new axes. Shuffle some includes,
and include stdarg.h.
Removed.
New, a mix of rel and abs that should actually work in the rel case.
Rearrange include order. btnMap was moved from being part of rel to being
part of axes.
Removed.
Rearrange include order.
Rearrange include order.
NOTE: This commit has been compile tested, not run tested.
I have some other changes to make before I can do more heavy testing.
Diffstat (limited to 'src/evdev_axes.c')
-rw-r--r-- | src/evdev_axes.c | 535 |
1 files changed, 535 insertions, 0 deletions
diff --git a/src/evdev_axes.c b/src/evdev_axes.c new file mode 100644 index 0000000..a164f84 --- /dev/null +++ b/src/evdev_axes.c @@ -0,0 +1,535 @@ +/* + * Copyright © 2006 Zephaniah E. Hull + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Author: Zephaniah E. Hull (warp@aehallh.com) + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <X11/keysym.h> +#include <X11/XF86keysym.h> +#include <X11/extensions/XIproto.h> + +#include <string.h> + +#include "evdev.h" + +#include <xf86.h> + +#include <xf86Module.h> +#include <mipointer.h> + + +#include <xf86_OSproc.h> + +#define ArrayLength(a) (sizeof(a) / (sizeof((a)[0]))) + +#define BITS_PER_LONG (sizeof(long) * 8) +#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) +#define OFF(x) ((x)%BITS_PER_LONG) +#define LONG(x) ((x)/BITS_PER_LONG) +#define TestBit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1) + +static char *rel_axis_names[] = { + "X", + "Y", + "Z", + "RX", + "RY", + "RZ", + "HWHEEL", + "DIAL", + "WHEEL", + "MISC", + "10", + "11", + "12", + "13", + "14", + "15", + NULL +}; + +static char *abs_axis_names[] = { + "X", + "Y", + "Z", + "RX", + "RY", + "RZ", + "THROTTLE", + "RUDDER", + "WHEEL", + "GAS", + "BRAKE", + "11", + "12", + "13", + "14", + "15", + "HAT0X", + "HAT0Y", + "HAT1X", + "HAT1Y", + "HAT2X", + "HAT2Y", + "HAT3X", + "HAT3Y", + "PRESSURE", + "TILT_X", + "TILT_Y", + "TOOL_WIDTH", + "VOLUME", + "29", + "30", + "31", + "32", + "33", + "34", + "35", + "36", + "37", + "38", + "39", + "MISC", + "41", + "42", + "43", + "44", + "45", + "46", + "47", + "48", + "49", + "50", + "51", + "52", + "53", + "54", + "55", + "56", + "57", + "58", + "59", + "60", + "61", + "62", + NULL +}; + +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) +{ + if (first == 0) { + *x = v0; + *y = v1; + return TRUE; + } else + return FALSE; +} + +static void +EvdevAxesRealSyn (InputInfoPtr pInfo, int absolute) +{ + evdevDevicePtr pEvdev = pInfo->private; + evdevStatePtr state = &pEvdev->state; + evdevAxesPtr axes = state->axes; + int i, btn; + + 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]); + } + + 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; +} + +static void +EvdevAxesAbsSyn (InputInfoPtr pInfo) +{ + evdevDevicePtr pEvdev = pInfo->private; + evdevStatePtr state = &pEvdev->state; + int i, n; + + if (!state->axes || !state->abs || !state->abs->count) + return; + + n = state->abs->n & 1; + 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) { + 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]); + + + 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); + } + + for (; i < ABS_MAX; i++) + state->axes->v[i] = state->abs->v[n][i]; + + EvdevAxesRealSyn (pInfo, 1); + state->abs->count = 0; +} + +static void +EvdevAxesRelSyn (InputInfoPtr pInfo) +{ + evdevDevicePtr pEvdev = pInfo->private; + evdevStatePtr state = &pEvdev->state; + int i; + + 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; + } + + EvdevAxesRealSyn (pInfo, 0); + state->rel->count = 0; +} + +void +EvdevAxesSyn (InputInfoPtr pInfo) +{ + EvdevAxesAbsSyn (pInfo); + EvdevAxesRelSyn (pInfo); +} + +void +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) + return; + + map = state->abs->map[ev->code]; + if (map >= 0) + state->abs->v[n][map] += ev->value; + else + state->abs->v[n][-map] -= ev->value; + + state->abs->count++; + + if (!state->sync) + EvdevAxesAbsSyn (pInfo); +} + +void +EvdevAxesRelProcess (InputInfoPtr pInfo, struct input_event *ev) +{ + evdevDevicePtr pEvdev = pInfo->private; + evdevStatePtr state = &pEvdev->state; + int map; + + if (ev->code >= REL_MAX) + return; + + map = state->rel->map[ev->code]; + if (map >= 0) + state->rel->v[map] += ev->value; + else + state->rel->v[-map] -= ev->value; + + state->rel->count++; + + if (!state->sync) + EvdevAxesRelSyn (pInfo); +} + +int +EvdevAxesOn (DeviceIntPtr device) +{ + return Success; +} + +int +EvdevAxesOff (DeviceIntPtr device) +{ + return Success; +} + +static int +EvdevAxisAbsNew(InputInfoPtr pInfo) +{ + evdevDevicePtr pEvdev = pInfo->private; + evdevStatePtr state = &pEvdev->state; + struct input_absinfo absinfo; + char *s, option[64]; + int i, j, k = 0, real_axes; + + real_axes = 0; + for (i = 0; i < ABS_MAX; i++) + 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 | + XI86_CONFIGURED; + pInfo->type_name = XI_MOUSE; + pInfo->conversion_proc = EvdevConvert; + + for (i = 0, j = 0; i < ABS_MAX; i++) { + if (!TestBit (i, pEvdev->bits.abs)) + continue; + + snprintf(option, sizeof(option), "%sAbsoluteAxisMap", abs_axis_names[i]); + k = xf86SetIntOption(pInfo->options, option, -1); + if (k != -1) + state->abs->map[i] = k; + else + state->abs->map[i] = j; + + if (k != -1) + xf86Msg(X_CONFIG, "%s: %s: %d.\n", pInfo->name, option, k); + + if (ioctl (pInfo->fd, EVIOCGABS(i), &absinfo) < 0) { + xf86Msg(X_ERROR, "ioctl EVIOCGABS failed: %s\n", strerror(errno)); + return !Success; + } + state->abs->min[state->abs->map[i]] = absinfo.minimum; + state->abs->max[state->abs->map[i]] = absinfo.maximum; + + j++; + } + + state->abs->axes = real_axes; + for (i = 0; i < ABS_MAX; i++) { + if (state->abs->map[i] > state->abs->axes) + 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); + + s = xf86SetStrOption(pInfo->options, "Mode", "Absolute"); + if (!strcasecmp(s, "Absolute")) { + state->mode = Absolute; + xf86Msg(X_CONFIG, "%s: Configuring in %s mode.\n", pInfo->name, s); + } else if (!strcasecmp(s, "Relative")) { + state->mode = Relative; + xf86Msg(X_CONFIG, "%s: Configuring in %s mode.\n", pInfo->name, s); + } else { + state->mode = Absolute; + xf86Msg(X_CONFIG, "%s: Unknown Mode: %s.\n", pInfo->name, s); + } + + 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; + xf86Msg(X_CONFIG, "%s: AbsoluteScreen: %d.\n", pInfo->name, k); + } else { + 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; + + return Success; +} + +static int +EvdevAxisRelNew(InputInfoPtr pInfo) +{ + evdevDevicePtr pEvdev = pInfo->private; + evdevStatePtr state = &pEvdev->state; + char *s, option[64]; + int i, j, k = 0, real_axes; + + real_axes = 0; + for (i = 0; i < REL_MAX; i++) + if (TestBit (i, pEvdev->bits.rel)) + real_axes++; + + 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); + pInfo->flags |= XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS | + XI86_CONFIGURED; + pInfo->type_name = XI_MOUSE; + pInfo->conversion_proc = EvdevConvert; + + for (i = 0, j = 0; i < REL_MAX; i++) { + if (!TestBit (i, pEvdev->bits.rel)) + continue; + + snprintf(option, sizeof(option), "%sRelativeAxisMap", rel_axis_names[i]); + s = xf86SetStrOption(pInfo->options, option, "0"); + if (s && (k = strtol(s, NULL, 0))) + state->rel->map[i] = k; + else + state->rel->map[i] = j; + + if (s && k) + xf86Msg(X_CONFIG, "%s: %s: %d.\n", pInfo->name, option, k); + + + snprintf(option, sizeof(option), "%sRelativeAxisButtons", rel_axis_names[i]); + if (i == REL_WHEEL || i == REL_Z) + s = xf86SetStrOption(pInfo->options, option, "4 5"); + else if (i == REL_HWHEEL) + s = xf86SetStrOption(pInfo->options, option, "6 7"); + else + s = xf86SetStrOption(pInfo->options, option, "0 0"); + + 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 (state->axes->btnMap[k][0] || state->axes->btnMap[k][1]) + xf86Msg(X_CONFIG, "%s: %s: %d %d.\n", pInfo->name, option, + state->axes->btnMap[k][0], state->axes->btnMap[k][1]); + + j++; + } + + state->rel->axes = real_axes; + for (i = 0; i < REL_MAX; i++) + if (state->rel->map[i] > state->rel->axes) + state->rel->axes = state->rel->map[i]; + + if (state->abs && (state->abs->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; +} + +int +EvdevAxesNew (InputInfoPtr pInfo) +{ + int ret = Success; + if (EvdevAxisAbsNew(pInfo) != Success) + ret = !Success; + if (EvdevAxisRelNew(pInfo) != Success) + ret = !Success; + + return ret; +} + + +static void +EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl) +{ + /* Nothing to do, dix handles all settings */ +} + +int +EvdevAxesInit (DeviceIntPtr device) +{ + InputInfoPtr pInfo = device->public.devicePrivate; + evdevDevicePtr pEvdev = pInfo->private; + evdevStatePtr state = &pEvdev->state; + int i, axes = 0; + + if (state->abs && state->abs->axes > axes) + axes = state->abs->axes; + if (state->abs && state->rel->axes > axes) + axes = state->rel->axes; + + if (!axes) + return Success; + + if (!InitValuatorClassDeviceStruct(device, axes, + miPointerGetMotionEvents, + miPointerGetMotionBufferSize(), 0)) + return !Success; + + for (i = 0; i < axes; i++) { + xf86InitValuatorAxisStruct(device, i, 0, 0, 0, 0, 1); + xf86InitValuatorDefaults(device, i); + } + + if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc)) + return !Success; + + return Success; +} + |