summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}