summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZephaniah E. Hull <warp@agamemnon.b5>2007-06-05 23:12:58 -0400
committerZephaniah E. Hull <warp@agamemnon.b5>2007-06-05 23:12:58 -0400
commit294355842ba9fb3cb3bbd7bfd60c9ca3ce704475 (patch)
tree243c982bb7f88578246e8c50715220a30199ab8b
parentc22c955c482df9a7645662023b6d1cf0f33aff15 (diff)
downloadxorg-driver-xf86-input-evdev-294355842ba9fb3cb3bbd7bfd60c9ca3ce704475.tar.gz
Alright, this is a really big commit that breaks stuff.
evdev.h: Switch to flags in the abs and rel structs. Add the axes struct, and defines. Rework the abs and rel structs, moving stuff to the axes struct and moving everything to the new mapping handling. Add the structs and function declarations for the new tokenization stuff, parsing stuff, and mapping stuff. evdev.c: Add EvdevTokenize, and the evdev_map_parsers list. evdev_axes.c: Basicly a full rewrite, big, messy. We now use a completely different mapping setup for axes, and mapping to buttons is currently missing. However we now handle ABS_CALIB and ABS_AREA, including rotation in both rel and abs modes. evdev_btn.c: Disable lots of code and break things horribly, we compile but we don't work very well. Fixing this is next on my todo list.
-rw-r--r--src/evdev.c98
-rw-r--r--src/evdev.h113
-rw-r--r--src/evdev_axes.c828
-rw-r--r--src/evdev_btn.c8
4 files changed, 752 insertions, 295 deletions
diff --git a/src/evdev.c b/src/evdev.c
index 7e8b633..3b91e53 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -103,6 +103,104 @@ evdevGetBits (int fd, evdevBitsPtr bits)
return TRUE;
}
+/*
+ * Evdev option handling stuff.
+ *
+ * We should probably move this all off to it's own file, but for now it lives
+ * hereish.
+ */
+
+evdev_map_parsers_t evdev_map_parsers[] = {
+ {
+ .name = "RelAxis",
+ .func = EvdevParseMapToRelAxis,
+ },
+ {
+ .name = "AbsAxis",
+ .func = EvdevParseMapToAbsAxis,
+ },
+ {
+ .name = NULL,
+ .func = NULL,
+ }
+};
+
+evdev_option_token_t *
+EvdevTokenize (const char *option, const char *tokens, const char *first)
+{
+ evdev_option_token_t *head = NULL, *token = NULL, *prev = NULL;
+ const char *ctmp;
+ char *tmp = NULL;
+ int len;
+
+ if (!first) {
+ first = strchr (option, tokens[0]);
+ }
+
+ while (1) {
+ if (first)
+ len = first - option;
+ else {
+ len = strlen(option);
+ if (!len)
+ break;
+ }
+
+ if (!len) {
+ option++;
+ first = strchr (option, tokens[0]);
+ continue;
+ }
+
+ token = calloc (1, sizeof(evdev_option_token_t));
+ if (!head)
+ head = token;
+ if (prev)
+ prev->next = token;
+
+ prev = token;
+
+ tmp = calloc(1, len + 1);
+ strncpy (tmp, option, len);
+
+ if (tokens[1]) {
+ ctmp = strchr (tmp, tokens[1]);
+ if (ctmp) {
+ token->is_chain = 1;
+ token->u.chain = EvdevTokenize (tmp, tokens + 1, ctmp);
+ } else
+ token->u.str = tmp;
+ } else
+ token->u.str = tmp;
+
+ if (!first)
+ break;
+
+ option = first + 1;
+ first = strchr (option, tokens[0]);
+ }
+
+ return head;
+}
+
+void
+EvdevFreeTokens (evdev_option_token_t *token)
+{
+ evdev_option_token_t *next;
+
+ while (token) {
+ if (token->is_chain)
+ EvdevFreeTokens (token->u.chain);
+ else
+ free (token->u.str);
+ next = token->next;
+ free (token);
+ token = next;
+ }
+}
+
+
+
static void
EvdevReadInput(InputInfoPtr pInfo)
{
diff --git a/src/evdev.h b/src/evdev.h
index 06d8aeb..517840d 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -94,9 +94,26 @@
#include <X11/extensions/XKB.h>
#include <X11/extensions/XKBstr.h>
+/*
+ * At the moment, ABS_MAX is larger then REL_MAX.
+ * As they are the only two providors of axes, ABS_MAX is it.
+ */
+#define AXES_MAX ABS_MAX
+
#define EVDEV_MAXBUTTONS 96
+struct _evdevDevice;
+
+/*
+ * FIXME: The mode option here is a kludge.
+ * It can be 0 (rel mode), 1 (abs mode), or -1 (input side has no clue).
+ *
+ * Worse, it arguably shouldn't even be the sender that decides here.
+ * And only the Axes targets and sources care at all right now.
+ */
+typedef void (*evdev_map_func_f)(InputInfoPtr pInfo, int value, int mode, void *map_data);
+
typedef struct {
unsigned long ev[NBITS(EV_MAX)];
unsigned long key[NBITS(KEY_MAX)];
@@ -111,6 +128,7 @@ typedef struct {
#define EV_BTN_IGNORE_X 1
#define EV_BTN_IGNORE_EVDEV 2
#define EV_BTN_IGNORE_MAP (EV_BTN_IGNORE_X | EV_BTN_IGNORE_EVDEV)
+
typedef struct {
int real_buttons;
int buttons;
@@ -119,31 +137,60 @@ typedef struct {
void (*callback[EVDEV_MAXBUTTONS])(InputInfoPtr pInfo, int button, int value);
} evdevBtnRec, *evdevBtnPtr;
+#define EV_ABS_V_PRESENT (1<<0)
+#define EV_ABS_V_M_AUTO (1<<1)
+#define EV_ABS_V_M_REL (1<<2)
+#define EV_ABS_V_INVERT (1<<3)
+#define EV_ABS_V_RESET (1<<4)
+#define EV_ABS_V_USE_TOUCH (1<<5)
+
+#define EV_ABS_USE_TOUCH (1<<0)
+#define EV_ABS_TOUCH (1<<1)
+#define EV_ABS_UPDATED (1<<2)
+
typedef struct {
+ int flags;
int axes;
int v[ABS_MAX];
- int old_x, old_y;
- int count;
- int min[ABS_MAX];
- int max[ABS_MAX];
- int map[ABS_MAX];
- int screen; /* Screen number for this device. */
- Bool use_touch;
- Bool touch;
- Bool reset_x, reset_y;
+ int v_flags[ABS_MAX];
+ int v_min[ABS_MAX];
+ int v_max[ABS_MAX];
+ void *v_map_data[ABS_MAX];
+ evdev_map_func_f v_map[ABS_MAX];
} evdevAbsRec, *evdevAbsPtr;
+#define EV_REL_V_PRESENT (1<<0)
+#define EV_REL_V_INVERT (1<<1)
+#define EV_REL_UPDATED (1<<0)
+
typedef struct {
- int axes;
+ int flags;
+ int v_flags[REL_MAX];
int v[REL_MAX];
- int count;
- int map[REL_MAX];
- int btnMap[REL_MAX][2];
+ int axes;
+ void *v_map_data[REL_MAX];
+ evdev_map_func_f v_map[REL_MAX];
} evdevRelRec, *evdevRelPtr;
+#define EV_AXES_V_M_ABS (1<<0)
+#define EV_AXES_V_M_REL (1<<1)
+#define EV_AXES_V_PRESENT (1<<2)
+#define EV_AXES_V_UPDATED (1<<3)
+
+#define EV_AXES_V_M_MASK (EV_AXES_V_M_ABS | EV_AXES_V_M_REL)
+
+#define EV_AXES_UPDATED (1<<0)
+
typedef struct {
int axes;
- int v[ABS_MAX];
+ int flags;
+ int v_flags[AXES_MAX];
+ int v_min[AXES_MAX];
+ int v_max[AXES_MAX];
+ int v[AXES_MAX];
+ int rotation;
+ float rot_sin, rot_cos;
+ int x, y;
} evdevAxesRec, *evdevAxesPtr;
typedef struct {
@@ -201,4 +248,42 @@ int EvdevKeyOn (DeviceIntPtr device);
int EvdevKeyOff (DeviceIntPtr device);
void EvdevKeyProcess (InputInfoPtr pInfo, struct input_event *ev);
+
+/*
+ * Option handling stuff.
+ */
+
+typedef struct evdev_option_token_s {
+ int is_chain;
+ union {
+ const char *str;
+ struct evdev_option_token_s *chain;
+ } u;
+ struct evdev_option_token_s *next;
+} evdev_option_token_t;
+
+typedef Bool (*evdev_parse_opt_func_f)(InputInfoPtr pInfo, const char *name, evdev_option_token_t *token, int *flags);
+typedef Bool (*evdev_parse_map_func_f)(InputInfoPtr pInfo,
+ const char *name,
+ evdev_option_token_t *option,
+ void **map_data, evdev_map_func_f *map_func);
+
+evdev_option_token_t *EvdevTokenize (const char *option, const char *tokens, const char *first);
+void EvdevFreeTokens (evdev_option_token_t *token);
+Bool EvdevParseMapToRelAxis (InputInfoPtr pInfo,
+ const char *name,
+ evdev_option_token_t *option,
+ void **map_data, evdev_map_func_f *map_func);
+Bool EvdevParseMapToAbsAxis (InputInfoPtr pInfo,
+ const char *name,
+ evdev_option_token_t *option,
+ void **map_data, evdev_map_func_f *map_func);
+
+typedef struct {
+ char *name;
+ evdev_parse_map_func_f func;
+} evdev_map_parsers_t;
+
+extern evdev_map_parsers_t evdev_map_parsers[];
+
#endif /* LNX_EVDEV_H_ */
diff --git a/src/evdev_axes.c b/src/evdev_axes.c
index 481038d..f58e1f1 100644
--- a/src/evdev_axes.c
+++ b/src/evdev_axes.c
@@ -140,202 +140,451 @@ static char *abs_axis_names[] = {
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)
-{
- if (first == 0) {
- *x = v0;
- *y = v1;
- return TRUE;
- } else
- return FALSE;
-}
-
-static void
-EvdevAxesRealSyn (InputInfoPtr pInfo, int absolute, int skip_xy)
+void
+EvdevAxesMapAxis (InputInfoPtr pInfo, int value, int mode, void *map_data)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
evdevAxesPtr axes = state->axes;
- int i;
+ long map = (long) map_data;
-#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
+ if (map >= AXES_MAX || !axes || !(axes->v_flags[map] & (EV_AXES_V_M_ABS | EV_AXES_V_M_REL)))
+ return;
- /* 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;
+ axes->v[map] = value;
+ if (mode == 0) {
+ axes->v_flags[map] &= ~EV_AXES_V_M_ABS;
+ axes->v_flags[map] |= EV_AXES_V_M_REL;
+ } else if (mode == 1) {
+ axes->v_flags[map] &= ~EV_AXES_V_M_REL;
+ axes->v_flags[map] |= EV_AXES_V_M_ABS;
+ }
+ axes->v_flags[map] |= EV_AXES_V_UPDATED;
+ axes->flags |= EV_AXES_UPDATED;
}
-static void
-EvdevAxesAbsSynCfg (InputInfoPtr pInfo)
+#if 0
+typedef struct {
+ int button_plus;
+ int button_minus;
+ int step;
+ int count;
+} AxisMapButton_t;
+
+void
+EvdevAxesMapButton (InputInfoPtr pInfo, int value, void *map_data)
{
- evdevDevicePtr pEvdev = pInfo->private;
- evdevStatePtr state = &pEvdev->state;
- struct input_absinfo absinfo;
+ AxisMapButton_t *map = map_data;
int i;
- for (i = 0; i < ABS_MAX; i++) {
- if (!test_bit (i, pEvdev->bits.abs))
+ // FIXME: Scream loudly, this is bad.
+ if (!map)
+ return;
+
+ map->count += value;
+ i = map->count / map->step;
+ if (i) {
+ map->count -= i * map->step;
+ if (i > 0)
+ EvdevBtnPostFakeClicks (pInfo, map->button_plus, i);
+ else
+ EvdevBtnPostFakeClicks (pInfo, map->button_minus, -i);
+ }
+}
+#endif
+
+static Bool
+EvdevParseRelOptions (InputInfoPtr pInfo, const char *name, evdev_option_token_t *option, int *flags)
+{
+ if (!option)
+ return 0;
+
+ for (; option; option = option->next) {
+ // XXX: Impossible.
+ if (option->is_chain)
continue;
- if (ioctl (pInfo->fd, EVIOCGABS(i), &absinfo) < 0) {
- xf86Msg(X_ERROR, "ioctl EVIOCGABS (%d) failed: %s\n", i, strerror(errno));
+ if (!strcasecmp (option->u.str, "invert"))
+ *flags |= EV_REL_V_INVERT;
+ else
+ xf86Msg(X_ERROR, "%s: %s unknown relative option '%s'.\n", pInfo->name, name, option->u.str);
+
+ }
+ *flags |= EV_REL_V_PRESENT;
+
+ return 1;
+}
+
+static Bool
+EvdevParseAbsOptions (InputInfoPtr pInfo, const char *name, evdev_option_token_t *option, int *flags)
+{
+ if (!option)
+ return 0;
+
+ for (; option; option = option->next) {
+ // XXX: Impossible.
+ if (option->is_chain)
continue;
- }
- state->abs->min[state->abs->map[i]] = absinfo.minimum;
- state->abs->max[state->abs->map[i]] = absinfo.maximum;
+
+ if (!strcasecmp (option->u.str, "invert"))
+ *flags |= EV_ABS_V_INVERT;
+ else if (!strcasecmp (option->u.str, "use_touch"))
+ *flags |= EV_ABS_V_USE_TOUCH;
+ else if (!strcasecmp (option->u.str, "mode_auto"))
+ *flags |= EV_ABS_V_M_AUTO;
+ else if (!strcasecmp (option->u.str, "mode_rel"))
+ *flags |= EV_ABS_V_M_REL;
+ else
+ xf86Msg(X_ERROR, "%s: %s unknown absolute option '%s'.\n", pInfo->name, name, option->u.str);
+
}
+ *flags |= EV_ABS_V_PRESENT;
+ return 1;
}
-static void
-EvdevAxesAbsSynRep (InputInfoPtr pInfo)
+Bool
+EvdevParseMapToRelAxis (InputInfoPtr pInfo,
+ const char *name,
+ evdev_option_token_t *option,
+ void **map_data, evdev_map_func_f *map_func)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
- int i = 0;
- Bool skip_xy = 0;
+ evdevAxesPtr axes = state->axes;
+ long i;
- if (!state->axes || !state->abs || !state->abs->count)
- return;
+ if (!option || option->is_chain)
+ return 0;
- if (state->mode == Relative && 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;
+ errno = 0;
+ i = strtol (option->u.str, NULL, 0);
+ if (errno) {
+ for (i = 0; rel_axis_names[i]; i++) {
+ if (!strcmp (option->u.str, rel_axis_names[i]))
+ break;
+ }
+ if (!rel_axis_names[i])
+ return 0;
+ }
+ if ((i < 0) || (i > AXES_MAX))
+ return 0;
- 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;
+ if (axes->v_flags[i] & EV_AXES_V_PRESENT)
+ return 0;
+
+ axes->v_flags[i] = EV_AXES_V_M_REL | EV_AXES_V_PRESENT;
+
+ *map_data = (void *) i;
+ *map_func = EvdevAxesMapAxis;
+
+ return 1;
+}
- state->abs->old_x = state->abs->v[0];
- state->abs->old_y = state->abs->v[1];
- EvdevAxesRealSyn (pInfo, 0, 2);
+Bool
+EvdevParseMapToAbsAxis (InputInfoPtr pInfo,
+ const char *name,
+ evdev_option_token_t *option,
+ void **map_data, evdev_map_func_f *map_func)
+{
+ evdevDevicePtr pEvdev = pInfo->private;
+ evdevStatePtr state = &pEvdev->state;
+ evdevAxesPtr axes = state->axes;
+ long i;
+
+ if (!option || option->is_chain) {
+ xf86Msg (X_ERROR, "%s: %s: No option/option is chain.\n", pInfo->name, name);
+ return 0;
+ }
+
+ errno = 0;
+ i = strtol (option->u.str, NULL, 0);
+ if (errno) {
+ for (i = 0; abs_axis_names[i]; i++) {
+ if (!strcmp (option->u.str, abs_axis_names[i]))
+ break;
}
- skip_xy = 1;
- } else if (state->mode == Absolute && state->abs->screen != -1 && state->abs->axes >= 2) {
- int conv_x, conv_y;
- int scale[2];
+ if (!abs_axis_names[i]) {
+ xf86Msg (X_ERROR, "%s: %s: No axis named '%s'.\n", pInfo->name, name, option->u.str);
+ return 0;
+ }
+ }
+ if ((i < 0) || (i > AXES_MAX)) {
+ xf86Msg (X_ERROR, "%s: %s: Axis %ld out of range.\n", pInfo->name, name, i);
+ return 0;
+ }
- scale[0] = screenInfo.screens[state->abs->screen]->width;
- scale[1] = screenInfo.screens[state->abs->screen]->height;
+ if (axes->v_flags[i] & EV_AXES_V_PRESENT) {
+ xf86Msg (X_ERROR, "%s: %s: Axis %ld already claimed.\n", pInfo->name, name, i);
+ return 0;
+ }
- for (i = 0; i < 2; i++)
- state->axes->v[i] = xf86ScaleAxis (state->abs->v[i],
- 0, scale[i], state->abs->min[i], state->abs->max[i]);
+ option = option->next;
+ if (!option || option->is_chain) {
+ xf86Msg (X_ERROR, "%s: %s: No min.\n", pInfo->name, name);
+ return 0;
+ }
+ errno = 0;
+ axes->v_min[i] = strtol (option->u.str, NULL, 0);
+ if (errno) {
+ xf86Msg (X_ERROR, "%s: %s: Unable to parse '%s' as min. (%s)\n", pInfo->name, name, option->u.str, strerror(errno));
+ return 0;
+ }
- 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);
+ option = option->next;
+ if (!option || option->is_chain) {
+ xf86Msg (X_ERROR, "%s: %s: No max.\n", pInfo->name, name);
+ return 0;
}
- for (; i < ABS_MAX; i++)
- state->axes->v[i] = state->abs->v[i];
+ errno = 0;
+ axes->v_max[i] = strtol (option->u.str, NULL, 0);
+ if (errno) {
+ xf86Msg (X_ERROR, "%s: %s: Unable to parse '%s' as max. (%s)\n", pInfo->name, name, option->u.str, strerror(errno));
+ return 0;
+ }
+
+ axes->v_flags[i] = EV_AXES_V_M_ABS | EV_AXES_V_PRESENT;
- EvdevAxesRealSyn (pInfo, 1, skip_xy);
- state->abs->count = 0;
+ *map_data = (void *) i;
+ *map_func = EvdevAxesMapAxis;
+
+ return 1;
}
+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;
+}
+
+
+/*
+ * Rotation and rep code, this is a mess and much of it needs to live in mi/
+ * after a cleanup.
+ */
static void
-EvdevAxesRelSynRep (InputInfoPtr pInfo)
+EvdevAxesDoRotation (InputInfoPtr pInfo, float x, float y)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
- evdevRelPtr rel = state->rel;
- int i, btn;
+ evdevAxesPtr axes = state->axes;
+ DeviceIntPtr dev = pInfo->dev;
+ AbsoluteClassRec *dabs = dev->absolute;
+
+ /*
+ * Rotation.
+ * Cache the sine and cosine results so we're not doing it every time.
+ */
+ if (dabs->rotation != axes->rotation || (axes->rot_cos == axes->rot_sin)) {
+ axes->rotation = dabs->rotation % 360;
+ axes->rot_cos = cos ( ((float) axes->rotation) * (M_PI/180));
+ axes->rot_sin = sin ( ((float) axes->rotation) * (M_PI/180));
+ }
- if (!state->axes || !state->rel || !state->rel->count)
- return;
+ if (axes->rotation) {
+ axes->v[0] = (x * axes->rot_cos) - (y * axes->rot_sin);
+ axes->v[1] = (y * axes->rot_cos) + (x * axes->rot_sin);
- for (i = 0; i < REL_MAX; i++) {
- 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]);
- }
+ axes->v_flags[0] |= EV_AXES_V_UPDATED;
+ axes->v_flags[1] |= EV_AXES_V_UPDATED;
+#if DEBUG
+ xf86Msg(X_ERROR, "%s %d (%s): cos=%f, sin=%f, x=%f, y=%f, v[0]=%d, v[1]=%d\n", __FILE__, __LINE__, __FUNCTION__,
+ axes->rot_cos, axes->rot_sin, x, y, axes->v[0], axes->v[1]);
+#endif
+ } else {
+ axes->v[0] = x;
+ axes->v[1] = y;
+ }
+}
- state->axes->v[i] = rel->v[i];
- rel->v[i] = 0;
+/*
+ * Cx - raw data from touch screen
+ * Sxhigh - scaled highest dimension
+ * (remember, this is of rows - 1 because of 0 origin)
+ * Sxlow - scaled lowest dimension
+ * Rxhigh - highest raw value from touch screen calibration
+ * Rxlow - lowest raw value from touch screen calibration
+ *
+ * This function is the same for X or Y coordinates.
+ * You may have to reverse the high and low values to compensate for
+ * different orgins on the touch screen vs X.
+ */
+
+_X_EXPORT int
+EvdevScaleAxis(int Cx,
+ int Sxlow,
+ int Sxhigh,
+ int Rxlow,
+ int Rxhigh)
+{
+ int X;
+ int dSx = Sxhigh - Sxlow;
+ int dRx = Rxhigh - Rxlow;
+
+ /* This is +, because Cx is negitive, so we're really subtracting. */
+ if (Cx < 0)
+ Cx = Rxhigh + Cx;
+
+ dSx = Sxhigh - Sxlow;
+ if (dRx) {
+ X = ((dSx * (Cx - Rxlow)) / dRx) + Sxlow;
+ }
+ else {
+ X = 0;
+ ErrorF ("Divide by Zero in evdevScaleAxis");
}
+
+ if (X < Sxlow)
+ X = Sxlow;
+ if (X > Sxhigh)
+ X = Sxhigh;
- EvdevAxesRealSyn (pInfo, 0, 0);
- rel->count = 0;
+ return (X);
}
void
EvdevAxesSynRep (InputInfoPtr pInfo)
{
- EvdevAxesAbsSynRep (pInfo);
- EvdevAxesRelSynRep (pInfo);
+ evdevDevicePtr pEvdev = pInfo->private;
+ evdevStatePtr state = &pEvdev->state;
+ evdevAxesPtr axes = state->axes;
+ DeviceIntPtr dev = pInfo->dev;
+ AbsoluteClassRec *dabs = dev->absolute;
+
+ int i, start, run, mode;
+
+ if (!axes || !(axes->flags & EV_AXES_UPDATED))
+ return;
+
+ start = 0;
+ mode = 0;
+ run = 0;
+
+ /*
+ * This handles most, but not all, of the ABS_CALIB and ABS_AREA
+ * additions to XInput 1.0.
+ *
+ * Note, we do this if both X and Y are set to absolute, or a more
+ * limited subset if both X and Y are relative, we don't do anything
+ * if we lack X or Y, or if they are not both set to both be ABS or REL.
+ */
+ if (axes->axes >= 2 && dabs) {
+ if ((axes->v_flags[0] & EV_AXES_V_M_ABS) &&
+ (axes->v_flags[1] & EV_AXES_V_M_ABS) &&
+ ((axes->v_flags[0] & EV_AXES_V_UPDATED) ||
+ (axes->v_flags[1] & EV_AXES_V_UPDATED))
+ ) {
+ int width, height, min_x, max_x, min_y, max_y;
+
+ if (axes->v_flags[0] & EV_AXES_V_UPDATED) axes->x = axes->v[0];
+ else axes->v[0] = axes->x;
+ if (axes->v_flags[1] & EV_AXES_V_UPDATED) axes->y = axes->v[1];
+ else axes->v[1] = axes->y;
+
+ if (dabs->width > 0)
+ width = dabs->width;
+ else
+ width = screenInfo.screens[dabs->screen]->width;
+
+ if (dabs->height > 0)
+ height = dabs->height;
+ else
+ height = screenInfo.screens[dabs->screen]->height;
+
+ if (dabs->flip_x)
+ axes->v[0] = dabs->max_x - axes->v[0];
+ if (dabs->flip_y)
+ axes->v[1] = dabs->max_y - axes->v[1];
+
+ /*
+ * In some cases we need to swap width and height.
+ * This depends on the rotation.
+ */
+ if ( (axes->rotation >= 45 && axes->rotation < 135) ||
+ (axes->rotation >= 225 && axes->rotation < 315)) {
+ min_x = dabs->min_y;
+ max_x = dabs->max_y;
+ min_y = dabs->min_x;
+ max_y = dabs->max_x;
+ } else {
+ min_x = dabs->min_x;
+ max_x = dabs->max_x;
+ min_y = dabs->min_y;
+ max_y = dabs->max_y;
+ }
+
+ EvdevAxesDoRotation (pInfo, axes->v[0], axes->v[1]);
+
+ axes->v[0] = EvdevScaleAxis (axes->v[0], 0, width, min_x, max_x);
+ axes->v[1] = EvdevScaleAxis (axes->v[1], 0, height, min_y, max_y);
+
+ axes->v[0] += dabs->offset_x;
+ axes->v[1] += dabs->offset_y;
+
+ xf86XInputSetScreen (pInfo, dabs->screen, axes->v[0], axes->v[1]);
+ } else if ((axes->v_flags[0] & EV_AXES_V_M_REL) &&
+ (axes->v_flags[1] & EV_AXES_V_M_REL) &&
+ ((axes->v_flags[0] & EV_AXES_V_UPDATED) ||
+ (axes->v_flags[1] & EV_AXES_V_UPDATED))
+ ) {
+
+ if (axes->v_flags[0] & EV_AXES_V_UPDATED) axes->x = axes->v[0];
+ else axes->v[0] = axes->x;
+ if (axes->v_flags[1] & EV_AXES_V_UPDATED) axes->y = axes->v[1];
+ else axes->v[1] = axes->y;
+
+ if (dabs->flip_x)
+ axes->v[0] = -axes->v[0];
+ if (dabs->flip_y)
+ axes->v[1] = -axes->v[1];
+
+ EvdevAxesDoRotation (pInfo, axes->v[0], axes->v[1]);
+ }
+ }
+
+ for (i = 0; i < axes->axes; i++) {
+ if (axes->v_flags[i] & EV_AXES_V_UPDATED) {
+ if (run) {
+ if (mode != (axes->v_flags[i] & EV_AXES_V_M_MASK)) {
+ mode = (mode == EV_AXES_V_M_ABS);
+ xf86PostMotionEventP (pInfo->dev, mode, start, i - start, axes->v + start);
+ start = i;
+ mode = axes->v_flags[i] & EV_AXES_V_M_MASK;
+ }
+ } else {
+ start = i;
+ mode = axes->v_flags[i] & EV_AXES_V_M_MASK;
+ }
+ run = 1;
+ axes->v_flags[i] &= ~EV_AXES_V_UPDATED;
+ } else if (run) {
+ mode = (mode == EV_AXES_V_M_ABS);
+ xf86PostMotionEventP (pInfo->dev, mode, start, i - start, axes->v + start);
+ }
+ }
+ if (run) {
+ mode = (mode == EV_AXES_V_M_ABS);
+ xf86PostMotionEventP (pInfo->dev, mode, start, i - start, axes->v + start);
+ }
}
+/*
+ * End rotation and rep code, this is a mess and much of it needs to live in mi/
+ * after a cleanup.
+ */
+
void
EvdevAxesSynCfg (InputInfoPtr pInfo)
{
- EvdevAxesAbsSynCfg (pInfo);
+/* EvdevAxesAbsSynCfg (pInfo);*/
/* EvdevAxesRelSynCfg (pInfo);*/
}
@@ -344,22 +593,38 @@ EvdevAxesAbsProcess (InputInfoPtr pInfo, struct input_event *ev)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
- int map;
+ evdevAbsRec *abs = state->abs;
+ int value, v_flags, is_rel;
- if (ev->code >= ABS_MAX)
+ if (ev->code >= ABS_MAX || !abs->v_map[ev->code])
return;
- /* FIXME: Handle inverted axes properly. */
- map = state->abs->map[ev->code];
- if (map >= 0)
- state->abs->v[map] = ev->value;
+ value = ev->value;
+ v_flags = abs->v_flags[ev->code];
+
+ if ((v_flags & EV_ABS_V_USE_TOUCH) && !(state->abs->flags & EV_ABS_TOUCH))
+ return;
+
+ if (v_flags & EV_ABS_V_INVERT)
+ value = state->abs->v_max[ev->code] - value;
+
+ if (v_flags & EV_ABS_V_M_REL)
+ is_rel = 1;
+ else if ((v_flags & EV_ABS_V_M_AUTO) && state->mode == Relative)
+ is_rel = 1;
else
- state->abs->v[-map] = ev->value;
+ is_rel = 0;
+
+ if (is_rel) {
+ if ((v_flags & EV_ABS_V_RESET) && value != abs->v[ev->code]) {
+ abs->v_flags[ev->code] &= ~EV_ABS_V_RESET;
+ } else
+ abs->v_map[ev->code](pInfo, value - abs->v[ev->code], 0, abs->v_map_data[ev->code]);
- state->abs->count++;
+ abs->v[ev->code] = value;
+ } else
+ abs->v_map[ev->code](pInfo, value, 1, abs->v_map_data[ev->code]);
- if (!state->sync)
- EvdevAxesAbsSynRep (pInfo);
}
void
@@ -367,21 +632,19 @@ EvdevAxesRelProcess (InputInfoPtr pInfo, struct input_event *ev)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
- int map;
+ evdevRelRec *rel = state->rel;
+ int value, v_flags;
- if (ev->code >= REL_MAX)
+ if (ev->code >= REL_MAX || !rel->v_map[ev->code])
return;
- map = state->rel->map[ev->code];
- if (map >= 0)
- state->rel->v[map] += ev->value;
- else
- state->rel->v[-map] -= ev->value;
+ value = ev->value;
+ v_flags = rel->v_flags[ev->code];
- state->rel->count++;
+ if (v_flags & EV_REL_V_INVERT)
+ value = -value;
- if (!state->sync)
- EvdevAxesRelSynRep (pInfo);
+ rel->v_map[ev->code](pInfo, value, 0, rel->v_map_data[ev->code]);
}
int
@@ -397,13 +660,16 @@ EvdevAxesOff (DeviceIntPtr device)
}
static int
-EvdevAxisAbsNew0(InputInfoPtr pInfo)
+EvdevAxisAbsNew(InputInfoPtr pInfo)
{
- evdevDevicePtr pEvdev = pInfo->private;
- evdevStatePtr state = &pEvdev->state;
+ evdevDeviceRec *pEvdev = pInfo->private;
+ evdevStateRec *state = &pEvdev->state;
+ evdevAbsRec *abs;
struct input_absinfo absinfo;
- char option[64];
- int i, j, k = 0, real_axes;
+ char option[128], value[128];
+ const char *s;
+ int i, j, k, real_axes;
+ evdev_option_token_t *tokens;
real_axes = 0;
for (i = 0; i < ABS_MAX; i++)
@@ -413,7 +679,7 @@ EvdevAxisAbsNew0(InputInfoPtr pInfo)
if (!real_axes)
return !Success;
- state->abs = Xcalloc (sizeof (evdevAbsRec));
+ state->abs = 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);
@@ -426,31 +692,46 @@ EvdevAxisAbsNew0(InputInfoPtr pInfo)
if (!test_bit (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;
+
+ snprintf(option, sizeof(option), "Abs%sMapTo", abs_axis_names[i]);
+ snprintf(value, sizeof(value), "AbsAxis %d %d %d", j, absinfo.minimum, absinfo.maximum);
+ s = xf86SetStrOption(pInfo->options, option, value);
+ tokens = EvdevTokenize (s, " =", NULL);
+ if (!tokens->is_chain && tokens->next) {
+ for (k = 0; evdev_map_parsers[k].name; k++) {
+ if (!strcasecmp (tokens->u.str, evdev_map_parsers[k].name)) {
+ if (!evdev_map_parsers[k].func (pInfo, option, tokens->next, &abs->v_map_data[i], &abs->v_map[i]))
+ xf86Msg (X_ERROR, "%s: Unable to parse '%s' as a map specifier (%s).\n", pInfo->name, s, evdev_map_parsers[k].name);
+ break;
+ }
+ }
+
+ if (!evdev_map_parsers[k].name)
+ xf86Msg (X_ERROR, "%s: Unable to find parser for '%s' as a map specifier.\n", pInfo->name, s);
+ }
+ EvdevFreeTokens (tokens);
+
+ snprintf(option, sizeof(option), "Abs%sOptions", abs_axis_names[i]);
+ if (i == ABS_X || i == ABS_Y)
+ s = xf86SetStrOption(pInfo->options, option, "use_touch mode_auto");
+ else
+ s = xf86SetStrOption(pInfo->options, option, "");
+ if (s[0]) {
+ tokens = EvdevTokenize (s, " =", NULL);
+ if (!EvdevParseAbsOptions (pInfo, option, tokens, &abs->v_flags[i]))
+ xf86Msg (X_ERROR, "%s: Unable to parse '%s' as absolute options.\n", pInfo->name, s);
+ EvdevFreeTokens (tokens);
+ }
+ abs->v_flags[i] |= EV_ABS_V_PRESENT;
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];
- }
return Success;
}
@@ -461,7 +742,6 @@ EvdevAxisAbsNew1(InputInfoPtr pInfo)
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
char *s;
- int k = 0;
if (!state->abs)
return !Success;
@@ -476,7 +756,7 @@ EvdevAxisAbsNew1(InputInfoPtr pInfo)
btn = EvdevBtnFind (pInfo, s);
if (btn != -1) {
if (EvdevBtnExists (pInfo, btn)) {
- state->abs->use_touch = 1;
+ state->abs->flags |= EV_ABS_USE_TOUCH;
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;
@@ -500,29 +780,18 @@ EvdevAxisAbsNew1(InputInfoPtr pInfo)
xf86Msg(X_CONFIG, "%s: Unknown Mode: %s.\n", pInfo->name, s);
}
- if (test_bit (ABS_X, pEvdev->bits.abs) && test_bit (ABS_Y, pEvdev->bits.abs))
- k = xf86SetIntOption(pInfo->options, "AbsoluteScreen", 0);
- else
- k = xf86SetIntOption(pInfo->options, "AbsoluteScreen", -1);
- if (k < screenInfo.numScreens && k >= 0) {
- state->abs->screen = k;
- xf86Msg(X_CONFIG, "%s: AbsoluteScreen: %d.\n", pInfo->name, k);
- } else {
- if (k != -1)
- xf86Msg(X_CONFIG, "%s: AbsoluteScreen: %d is not a valid screen.\n", pInfo->name, k);
- state->abs->screen = -1;
- }
-
return Success;
}
static int
-EvdevAxisRelNew0(InputInfoPtr pInfo)
+EvdevAxisRelNew(InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
- char *s, option[64];
- int i, j, k = 0, real_axes;
+ evdevRelPtr rel = state->rel;
+ char *s, option[128], value[128];
+ int i, j, k, real_axes;
+ evdev_option_token_t *tokens;
real_axes = 0;
for (i = 0; i < REL_MAX; i++)
@@ -546,61 +815,44 @@ EvdevAxisRelNew0(InputInfoPtr pInfo)
if (!test_bit (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]);
+ snprintf(option, sizeof(option), "Rel%sMapTo", rel_axis_names[i]);
if (i == REL_WHEEL || i == REL_Z)
- s = xf86SetStrOption(pInfo->options, option, "4 5");
+ snprintf(value, sizeof(value), "Buttons 4 5 1");
else if (i == REL_HWHEEL)
- s = xf86SetStrOption(pInfo->options, option, "6 7");
+ snprintf(value, sizeof(value), "Buttons 6 7 1");
else
- s = xf86SetStrOption(pInfo->options, option, "0 0");
+ snprintf(value, sizeof(value), "RelAxis %d", j);
+ s = xf86SetStrOption(pInfo->options, option, value);
+ tokens = EvdevTokenize (s, " =", NULL);
+ if (!tokens->is_chain && tokens->next) {
+ for (k = 0; evdev_map_parsers[k].name; k++) {
+ if (!strcasecmp (tokens->u.str, evdev_map_parsers[k].name)) {
+ if (!evdev_map_parsers[k].func (pInfo, option, tokens->next, &rel->v_map_data[i], &rel->v_map[i]))
+ xf86Msg (X_ERROR, "%s: Unable to parse '%s' as a map specifier.\n", pInfo->name, s);
+ break;
+ }
- k = state->rel->map[i];
+ }
- 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 (!evdev_map_parsers[k].name)
+ xf86Msg (X_ERROR, "%s: Unable to find parser for '%s' as a map specifier.\n", pInfo->name, s);
+ }
+ EvdevFreeTokens (tokens);
+
+ snprintf(option, sizeof(option), "Rel%sOptions", rel_axis_names[i]);
+ s = xf86SetStrOption(pInfo->options, option, "");
+ if (s[0]) {
+ tokens = EvdevTokenize (s, " =", NULL);
+ if (!EvdevParseRelOptions (pInfo, option, tokens, &rel->v_flags[i]))
+ xf86Msg (X_ERROR, "%s: Unable to parse '%s' as relative options.\n", pInfo->name, s);
+ EvdevFreeTokens (tokens);
+ }
+ rel->v_flags[i] |= EV_REL_V_PRESENT;
- if (state->rel->btnMap[k][0] || state->rel->btnMap[k][1])
- xf86Msg(X_CONFIG, "%s: %s: %d %d.\n", pInfo->name, option,
- state->rel->btnMap[k][0], state->rel->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;
-
- 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;
}
@@ -612,9 +864,9 @@ EvdevAxesNew0 (InputInfoPtr pInfo)
int ret = Success;
state->axes = Xcalloc (sizeof (evdevAxesRec));
- if (EvdevAxisAbsNew0(pInfo) != Success)
+ if (EvdevAxisAbsNew(pInfo) != Success)
ret = !Success;
- if (EvdevAxisRelNew0(pInfo) != Success)
+ if (EvdevAxisRelNew(pInfo) != Success)
ret = !Success;
if (!state->abs && !state->rel) {
Xfree (state->axes);
@@ -627,15 +879,20 @@ EvdevAxesNew0 (InputInfoPtr pInfo)
int
EvdevAxesNew1 (InputInfoPtr pInfo)
{
- evdevDevicePtr pEvdev = pInfo->private;
- evdevStatePtr state = &pEvdev->state;
- int ret = Success;
+ evdevDeviceRec *pEvdev = pInfo->private;
+ evdevStateRec *state = &pEvdev->state;
+ evdevAxesRec *axes = state->axes;
+ int i, ret = Success;
+
+ if (!state->axes)
+ return ret;
+
+ for (i = 0; i < AXES_MAX; i++)
+ if (axes->v_flags[i] & EV_AXES_V_PRESENT)
+ axes->axes = i + 1;
- state->axes = Xcalloc (sizeof (evdevAxesRec));
if (EvdevAxisAbsNew1(pInfo) != Success)
ret = !Success;
- if (EvdevAxisRelNew1(pInfo) != Success)
- ret = !Success;
if (!state->abs && !state->rel) {
Xfree (state->axes);
state->axes = NULL;
@@ -657,43 +914,47 @@ 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->rel && state->rel->axes > axes)
- axes = state->rel->axes;
+ evdevAxesRec *axes = state->axes;
+ AbsoluteClassRec *dev_abs;
+ int i;
- state->axes->axes = axes;
+ if (!axes || !axes->axes)
+ return Success;
xf86Msg(X_CONFIG, "%s: %d valuators.\n", pInfo->name,
- axes);
- if (!axes)
- return Success;
+ axes->axes);
- if (!InitValuatorClassDeviceStruct(device, axes,
-#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 1
+ if (!InitValuatorClassDeviceStruct(device, axes->axes,
GetMotionHistory,
GetMotionHistorySize(),
-#else
- miPointerGetMotionEvents,
- miPointerGetMotionBufferSize(),
-#endif
0))
return !Success;
- for (i = 0; i < axes; i++) {
- xf86InitValuatorAxisStruct(device, i, -1, -1, 0, 0, 1);
+ /*
+ * Yes, we want to do this for relative devices too.
+ * Some of the settings are useful for both.
+ */
+ if ((axes->v_flags[0] & EV_AXES_V_PRESENT) &&
+ (axes->v_flags[1] & EV_AXES_V_PRESENT) &&
+ InitAbsoluteClassDeviceStruct (device)) {
+ dev_abs = device->absolute;
+ if (axes->v_min[0] != axes->v_max[1] && axes->v_min[1] != axes->v_max[1]) {
+ device->absolute->min_x = axes->v_min[0];
+ device->absolute->max_x = axes->v_max[0];
+ device->absolute->min_y = axes->v_min[1];
+ device->absolute->max_y = axes->v_max[1];
+ }
+ }
+
+ for (i = 0; i < axes->axes; i++) {
+ xf86InitValuatorAxisStruct(device, i, -1, -1, 1, 1, 1);
+
xf86InitValuatorDefaults(device, i);
}
if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
return !Success;
-#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
- xf86MotionHistoryAllocate (pInfo);
-#endif
-
return Success;
}
@@ -702,13 +963,18 @@ EvdevAxesTouchCallback (InputInfoPtr pInfo, int button, int value)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
+ int i;
#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;
+ if (state->abs->flags & EV_ABS_USE_TOUCH) {
+ if (value) {
+ state->abs->flags |= EV_ABS_TOUCH;
+ for (i = 0; i < ABS_MAX; i++)
+ if (state->abs->v_flags[i] & EV_ABS_V_USE_TOUCH)
+ state->abs->v_flags[i] |= EV_ABS_V_RESET;
+ } else
+ state->abs->flags &= ~EV_ABS_TOUCH;
}
}
diff --git a/src/evdev_btn.c b/src/evdev_btn.c
index b9bfe07..3914bad 100644
--- a/src/evdev_btn.c
+++ b/src/evdev_btn.c
@@ -214,6 +214,7 @@ EvdevBtnOff (DeviceIntPtr device)
return Success;
}
+#if 0
/*
* Warning, evil lives here.
*/
@@ -286,6 +287,7 @@ EvdevBtnCalcRemap (InputInfoPtr pInfo)
}
}
}
+#endif
int
@@ -350,7 +352,11 @@ EvdevBtnNew1(InputInfoPtr pInfo)
if (!state->btn)
return !Success;
+#if 0
EvdevBtnCalcRemap (pInfo);
+#else
+ state->btn->buttons = state->btn->real_buttons;
+#endif
if (state->btn->buttons)
xf86Msg(X_INFO, "%s: Configured %d mouse buttons\n", pInfo->name, state->btn->buttons);
@@ -399,7 +405,9 @@ EvdevBtnProcess (InputInfoPtr pInfo, struct input_event *ev)
if (state->btn->ignore[button] & EV_BTN_IGNORE_X)
return;
+#if 0
button = state->btn->map[button];
+#endif
xf86PostButtonEvent (pInfo->dev, 0, button, ev->value, 0, 0);
}