aboutsummaryrefslogtreecommitdiff
path: root/src/evdev_axes.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/evdev_axes.c')
-rw-r--r--src/evdev_axes.c323
1 files changed, 243 insertions, 80 deletions
diff --git a/src/evdev_axes.c b/src/evdev_axes.c
index 0d9b5a7..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);
@@ -529,7 +677,7 @@ EvdevAxesInit (DeviceIntPtr device)
return !Success;
for (i = 0; i < axes; i++) {
- xf86InitValuatorAxisStruct(device, i, 0, 0, 0, 0, 1);
+ xf86InitValuatorAxisStruct(device, i, 0, -1, 0, 0, 1);
xf86InitValuatorDefaults(device, i);
}
@@ -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;
+ }
+}