aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZephaniah E. Hull <warp@agamemnon.b5>2007-06-06 04:41:54 -0400
committerZephaniah E. Hull <warp@agamemnon.b5>2007-06-06 04:41:54 -0400
commitf15636ac529481a9d83e0250ff89690296f96a3d (patch)
tree05ee199bf76f8479b6a9261c0a8a351d19bab6fe
parentFix REL mode. (diff)
downloadxf86-input-evdev-f15636ac529481a9d83e0250ff89690296f96a3d.tar.gz
xf86-input-evdev-f15636ac529481a9d83e0250ff89690296f96a3d.tar.bz2
xf86-input-evdev-f15636ac529481a9d83e0250ff89690296f96a3d.zip
Wheel mice work again!
(Old configs don't.) evdev.c: Add EvdevParseMapToButton and EvdevParseMapToButtons to evdev_map_parsers. Add EvdevParseMapOption to search through evdev_map_parsers. Fix up EvdevTokenize to handle the evdev_option_token_t changes. EvdevAxesNew0 after BtnNew0 instead of before now. (This isn't the right fix.) evdev.h: EVDEV_MAXBUTTONS -> BTN_MAX. Redid evdevBtnRec with the new mapping goodness. Removed v_min and v_max from evdevAbsRec. Reworked evdev_option_token_t, no union, no is_chain. If it's a chain, it still has a string, but the chain pointer is set. EvdevParseMapToButton, EvdevParseMapToButtons, and EvdevParseMapOption. evdev_axes.c: Kill off EvdevAxesMapButton, a variant lives in evdev_btn.c now. Changes for the evdev_option_token_t changes. Use EvdevParseMapOption instead of repeating the contents twice. Disable EV_ABS_V_INVERT for the moment. (Better fix maybe needed.) evdev_btn.c: s/Ptr /Rec */g EvdevMapButton and parser. EvdevMapButtons and parser. Nuke EvdevBtnCalcRemap as a whole. Move everything but the alloc to New1 from New0. New mapping code, same guts os the axes mapping code even.
-rw-r--r--src/evdev.c63
-rw-r--r--src/evdev.h35
-rw-r--r--src/evdev_axes.c129
-rw-r--r--src/evdev_btn.c360
4 files changed, 290 insertions, 297 deletions
diff --git a/src/evdev.c b/src/evdev.c
index f2debd2..881f079 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -99,22 +99,59 @@ evdev_map_parsers_t evdev_map_parsers[] = {
.func = EvdevParseMapToAbsAxis,
},
{
+ .name = "Button",
+ .func = EvdevParseMapToButton,
+ },
+ {
+ .name = "Buttons",
+ .func = EvdevParseMapToButtons,
+ },
+ {
.name = NULL,
.func = NULL,
}
};
+Bool
+EvdevParseMapOption (InputInfoRec *pInfo, char *option, char *def, void **map_data, evdev_map_func_f *map_func)
+{
+ evdev_option_token_t *tokens;
+ const char *s;
+ int i;
+
+ s = xf86SetStrOption(pInfo->options, option, def);
+ tokens = EvdevTokenize (s, " =");
+ if (tokens->next) {
+ for (i = 0; evdev_map_parsers[i].name; i++) {
+ if (!strcasecmp (tokens->str, evdev_map_parsers[i].name)) {
+ if (!evdev_map_parsers[i].func (pInfo, option, tokens->next, map_data, map_func)) {
+ xf86Msg (X_ERROR, "%s: Unable to parse '%s' as a map specifier.\n", pInfo->name, s);
+ EvdevFreeTokens (tokens);
+ return 0;
+ }
+ return 1;
+ }
+ }
+
+ if (!evdev_map_parsers[i].name)
+ xf86Msg (X_ERROR, "%s: Unable to find parser for '%s' as a map specifier.\n", pInfo->name, s);
+ } else {
+ xf86Msg (X_ERROR, "%s: Unable to parse '%s' as a map specifier string.\n", pInfo->name, s);
+ }
+ EvdevFreeTokens (tokens);
+ return 0;
+}
+
evdev_option_token_t *
-EvdevTokenize (const char *option, const char *tokens, const char *first)
+EvdevTokenize (const char *option, const char *tokens)
{
evdev_option_token_t *head = NULL, *token = NULL, *prev = NULL;
const char *ctmp;
+ const char *first;
char *tmp = NULL;
int len;
- if (!first) {
- first = strchr (option, tokens[0]);
- }
+ first = strchr (option, tokens[0]);
while (1) {
if (first)
@@ -145,12 +182,11 @@ EvdevTokenize (const char *option, const char *tokens, const char *first)
if (tokens[1]) {
ctmp = strchr (tmp, tokens[1]);
if (ctmp) {
- token->is_chain = 1;
- token->u.chain = EvdevTokenize (tmp, tokens + 1, ctmp);
+ token->chain = EvdevTokenize (ctmp+1, tokens + 1);
} else
- token->u.str = tmp;
+ token->str = tmp;
} else
- token->u.str = tmp;
+ token->str = tmp;
if (!first)
break;
@@ -168,10 +204,9 @@ 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);
+ if (token->chain)
+ EvdevFreeTokens (token->chain);
+ free (token->str);
next = token->next;
free (token);
token = next;
@@ -191,7 +226,7 @@ EvdevReadInput(InputInfoPtr pInfo)
if (len != sizeof(ev)) {
/* The kernel promises that we always only read a complete
* event, so len != sizeof ev is an error. */
- xf86Msg(X_ERROR, "Read error: %s (%d, %d != %ld)\n",
+ xf86Msg(X_ERROR, "Read error: %s (%d, %d != %zd)\n",
strerror(errno), errno, len, sizeof (ev));
if (len < 0)
{
@@ -412,8 +447,8 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
/* XXX: Note, the order of these is (maybe) still important. */
- EvdevAxesNew0 (pInfo);
EvdevBtnNew0 (pInfo);
+ EvdevAxesNew0 (pInfo);
EvdevAxesNew1 (pInfo);
EvdevBtnNew1 (pInfo);
diff --git a/src/evdev.h b/src/evdev.h
index cfce03b..d14bba3 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -80,7 +80,7 @@
#define AXES_MAX ABS_MAX
-#define EVDEV_MAXBUTTONS 96
+#define BTN_MAX 96
struct _evdevDevice;
@@ -104,16 +104,15 @@ typedef struct {
unsigned long ff[NBITS(FF_MAX)];
} evdevBitsRec, *evdevBitsPtr;
-#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)
+#define EV_BTN_B_PRESENT (1<<0)
typedef struct {
int real_buttons;
int buttons;
- CARD8 ignore[EVDEV_MAXBUTTONS];
- CARD8 map[EVDEV_MAXBUTTONS];
- void (*callback[EVDEV_MAXBUTTONS])(InputInfoPtr pInfo, int button, int value);
+ int b_flags[BTN_MAX];
+ void *b_map_data[ABS_MAX];
+ evdev_map_func_f b_map[BTN_MAX];
+ void (*callback[BTN_MAX])(InputInfoPtr pInfo, int button, int value);
} evdevBtnRec, *evdevBtnPtr;
#define EV_ABS_V_PRESENT (1<<0)
@@ -132,8 +131,6 @@ typedef struct {
int axes;
int v[ABS_MAX];
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;
@@ -233,11 +230,8 @@ void EvdevKeyProcess (InputInfoPtr pInfo, struct input_event *ev);
*/
typedef struct evdev_option_token_s {
- int is_chain;
- union {
- const char *str;
- struct evdev_option_token_s *chain;
- } u;
+ const char *str;
+ struct evdev_option_token_s *chain;
struct evdev_option_token_s *next;
} evdev_option_token_t;
@@ -247,7 +241,7 @@ typedef Bool (*evdev_parse_map_func_f)(InputInfoPtr pInfo,
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);
+evdev_option_token_t *EvdevTokenize (const char *option, const char *tokens);
void EvdevFreeTokens (evdev_option_token_t *token);
Bool EvdevParseMapToRelAxis (InputInfoPtr pInfo,
const char *name,
@@ -257,6 +251,16 @@ Bool EvdevParseMapToAbsAxis (InputInfoPtr pInfo,
const char *name,
evdev_option_token_t *option,
void **map_data, evdev_map_func_f *map_func);
+Bool
+EvdevParseMapToButton (InputInfoRec *pInfo,
+ const char *name,
+ evdev_option_token_t *option,
+ void **map_data, evdev_map_func_f *map_func);
+Bool
+EvdevParseMapToButtons (InputInfoRec *pInfo,
+ const char *name,
+ evdev_option_token_t *option,
+ void **map_data, evdev_map_func_f *map_func);
typedef struct {
char *name;
@@ -264,5 +268,6 @@ typedef struct {
} evdev_map_parsers_t;
extern evdev_map_parsers_t evdev_map_parsers[];
+Bool EvdevParseMapOption (InputInfoRec *pInfo, char *option, char *def, void **map_data, evdev_map_func_f *map_func);
#endif /* __EVDEV_H */
diff --git a/src/evdev_axes.c b/src/evdev_axes.c
index 1443495..4abab46 100644
--- a/src/evdev_axes.c
+++ b/src/evdev_axes.c
@@ -163,36 +163,6 @@ EvdevAxesMapAxis (InputInfoPtr pInfo, int value, int mode, void *map_data)
axes->flags |= EV_AXES_UPDATED;
}
-#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)
-{
- AxisMapButton_t *map = map_data;
- int i;
-
- // 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)
{
@@ -200,14 +170,10 @@ EvdevParseRelOptions (InputInfoPtr pInfo, const char *name, evdev_option_token_t
return 0;
for (; option; option = option->next) {
- // XXX: Impossible.
- if (option->is_chain)
- continue;
-
- if (!strcasecmp (option->u.str, "invert"))
+ if (!strcasecmp (option->str, "invert"))
*flags |= EV_REL_V_INVERT;
else
- xf86Msg(X_ERROR, "%s: %s unknown relative option '%s'.\n", pInfo->name, name, option->u.str);
+ xf86Msg(X_ERROR, "%s: %s unknown relative option '%s'.\n", pInfo->name, name, option->str);
}
*flags |= EV_REL_V_PRESENT;
@@ -222,20 +188,16 @@ EvdevParseAbsOptions (InputInfoPtr pInfo, const char *name, evdev_option_token_t
return 0;
for (; option; option = option->next) {
- // XXX: Impossible.
- if (option->is_chain)
- continue;
-
- if (!strcasecmp (option->u.str, "invert"))
+ if (!strcasecmp (option->str, "invert"))
*flags |= EV_ABS_V_INVERT;
- else if (!strcasecmp (option->u.str, "use_touch"))
+ else if (!strcasecmp (option->str, "use_touch"))
*flags |= EV_ABS_V_USE_TOUCH;
- else if (!strcasecmp (option->u.str, "mode_auto"))
+ else if (!strcasecmp (option->str, "mode_auto"))
*flags |= EV_ABS_V_M_AUTO;
- else if (!strcasecmp (option->u.str, "mode_rel"))
+ else if (!strcasecmp (option->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);
+ xf86Msg(X_ERROR, "%s: %s unknown absolute option '%s'.\n", pInfo->name, name, option->str);
}
*flags |= EV_ABS_V_PRESENT;
@@ -254,14 +216,11 @@ EvdevParseMapToRelAxis (InputInfoPtr pInfo,
evdevAxesPtr axes = state->axes;
long i;
- if (!option || option->is_chain)
- return 0;
-
errno = 0;
- i = strtol (option->u.str, NULL, 0);
+ i = strtol (option->str, NULL, 0);
if (errno) {
for (i = 0; rel_axis_names[i]; i++) {
- if (!strcmp (option->u.str, rel_axis_names[i]))
+ if (!strcmp (option->str, rel_axis_names[i]))
break;
}
if (!rel_axis_names[i])
@@ -292,20 +251,15 @@ EvdevParseMapToAbsAxis (InputInfoPtr pInfo,
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);
+ i = strtol (option->str, NULL, 0);
if (errno) {
for (i = 0; abs_axis_names[i]; i++) {
- if (!strcmp (option->u.str, abs_axis_names[i]))
+ if (!strcmp (option->str, abs_axis_names[i]))
break;
}
if (!abs_axis_names[i]) {
- xf86Msg (X_ERROR, "%s: %s: No axis named '%s'.\n", pInfo->name, name, option->u.str);
+ xf86Msg (X_ERROR, "%s: %s: No axis named '%s'.\n", pInfo->name, name, option->str);
return 0;
}
}
@@ -320,28 +274,28 @@ EvdevParseMapToAbsAxis (InputInfoPtr pInfo,
}
option = option->next;
- if (!option || option->is_chain) {
+ if (!option) {
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);
+ axes->v_min[i] = strtol (option->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));
+ xf86Msg (X_ERROR, "%s: %s: Unable to parse '%s' as min. (%s)\n", pInfo->name, name, option->str, strerror(errno));
return 0;
}
option = option->next;
- if (!option || option->is_chain) {
+ if (!option) {
xf86Msg (X_ERROR, "%s: %s: No max.\n", pInfo->name, name);
return 0;
}
errno = 0;
- axes->v_max[i] = strtol (option->u.str, NULL, 0);
+ axes->v_max[i] = strtol (option->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));
+ xf86Msg (X_ERROR, "%s: %s: Unable to parse '%s' as max. (%s)\n", pInfo->name, name, option->str, strerror(errno));
return 0;
}
@@ -620,8 +574,10 @@ EvdevAxesAbsProcess (InputInfoPtr pInfo, struct input_event *ev)
if ((v_flags & EV_ABS_V_USE_TOUCH) && !(state->abs->flags & EV_ABS_TOUCH))
return;
+#if 0
if (v_flags & EV_ABS_V_INVERT)
- value = state->abs->v_max[ev->code] - value;
+ value = -value;
+#endif
if (v_flags & EV_ABS_V_M_REL)
is_rel = 1;
@@ -683,7 +639,7 @@ EvdevAxisAbsNew(InputInfoPtr pInfo)
struct input_absinfo absinfo;
char option[128], value[128];
const char *s;
- int i, j, k, real_axes;
+ int i, j, real_axes;
evdev_option_token_t *tokens;
real_axes = 0;
@@ -714,21 +670,8 @@ EvdevAxisAbsNew(InputInfoPtr pInfo)
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);
+ EvdevParseMapOption (pInfo, option, value, &abs->v_map_data[i], &abs->v_map[i]);
snprintf(option, sizeof(option), "Abs%sOptions", abs_axis_names[i]);
if (i == ABS_X || i == ABS_Y)
@@ -736,7 +679,7 @@ EvdevAxisAbsNew(InputInfoPtr pInfo)
else
s = xf86SetStrOption(pInfo->options, option, "");
if (s[0]) {
- tokens = EvdevTokenize (s, " =", NULL);
+ tokens = EvdevTokenize (s, " ");
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);
@@ -803,9 +746,9 @@ EvdevAxisRelNew(InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
- evdevRelPtr rel = state->rel;
+ evdevRelPtr rel;
char *s, option[128], value[128];
- int i, j, k, real_axes;
+ int i, j, real_axes;
evdev_option_token_t *tokens;
real_axes = 0;
@@ -816,7 +759,7 @@ EvdevAxisRelNew(InputInfoPtr pInfo)
if (!real_axes && (!state->abs || state->abs->axes < 2))
return !Success;
- state->rel = Xcalloc (sizeof (evdevRelRec));
+ state->rel = rel = Xcalloc (sizeof (evdevRelRec));
xf86Msg(X_INFO, "%s: Found %d relative axes.\n", pInfo->name,
real_axes);
@@ -837,27 +780,13 @@ EvdevAxisRelNew(InputInfoPtr pInfo)
snprintf(value, sizeof(value), "Buttons 6 7 1");
else
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;
- }
-
- }
- 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);
+ EvdevParseMapOption (pInfo, option, value, &rel->v_map_data[i], &rel->v_map[i]);
snprintf(option, sizeof(option), "Rel%sOptions", rel_axis_names[i]);
s = xf86SetStrOption(pInfo->options, option, "");
if (s[0]) {
- tokens = EvdevTokenize (s, " =", NULL);
+ tokens = EvdevTokenize (s, " ");
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);
diff --git a/src/evdev_btn.c b/src/evdev_btn.c
index 3d52e9f..63a6abf 100644
--- a/src/evdev_btn.c
+++ b/src/evdev_btn.c
@@ -151,7 +151,7 @@ static char *button_names[] = {
};
void
-EvdevBtnPostFakeClicks(InputInfoPtr pInfo, int button, int count)
+EvdevBtnPostFakeClicks(InputInfoRec *pInfo, int button, int count)
{
int i;
@@ -161,11 +161,140 @@ EvdevBtnPostFakeClicks(InputInfoPtr pInfo, int button, int count)
}
}
+typedef struct {
+ int button_plus;
+ int button_minus;
+ int step;
+ int count;
+} MapButtons_t;
+
+static void
+EvdevMapButton (InputInfoRec *pInfo, int value, int mode, void *map_data)
+{
+ long button = (long) map_data;
+
+ xf86PostButtonEvent (pInfo->dev, 0, button, value, 0, 0);
+}
+
+Bool
+EvdevParseMapToButton (InputInfoRec *pInfo,
+ const char *name,
+ evdev_option_token_t *option,
+ void **map_data, evdev_map_func_f *map_func)
+{
+ evdevDeviceRec *pEvdev = pInfo->private;
+ evdevStateRec *state = &pEvdev->state;
+ evdevBtnRec *btn = state->btn;
+ int button;
+
+ errno = 0;
+ button = strtol (option->str, NULL, 0);
+ if (errno)
+ button = EvdevBtnFind (pInfo, option->str);
+ if ((button < 0) || (button > BTN_MAX)) {
+ xf86Msg (X_ERROR, "%s: %s: Button %d out of range.\n", pInfo->name, name, button);
+ return 0;
+ }
+
+ if (btn->b_flags[button] & EV_BTN_B_PRESENT) {
+ xf86Msg (X_ERROR, "%s: %s: Button %d already claimed.\n", pInfo->name, name, button);
+ return 0;
+ }
+
+ btn->b_flags[button] = EV_BTN_B_PRESENT;
+
+ *map_data = (void *) button;
+ *map_func = EvdevMapButton;
+
+ return 1;
+}
+
+static void
+EvdevMapButtons (InputInfoRec *pInfo, int value, int mode, void *map_data)
+{
+ MapButtons_t *map = map_data;
+ int i;
+
+ 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);
+ }
+}
+
+Bool
+EvdevParseMapToButtons (InputInfoRec *pInfo,
+ const char *name,
+ evdev_option_token_t *option,
+ void **map_data, evdev_map_func_f *map_func)
+{
+ evdevDeviceRec *pEvdev = pInfo->private;
+ evdevStateRec *state = &pEvdev->state;
+ evdevBtnRec *btn = state->btn;
+ int btn_plus, btn_minus;
+ MapButtons_t *map;
+
+ errno = 0;
+ btn_plus = strtol (option->str, NULL, 0);
+ if (errno)
+ btn_plus = EvdevBtnFind (pInfo, option->str);
+ if ((btn_plus < 0) || (btn_plus > BTN_MAX)) {
+ xf86Msg (X_ERROR, "%s: %s: Button %d out of range.\n", pInfo->name, name, btn_plus);
+ return 0;
+ }
+
+ if (btn->b_flags[btn_plus] & EV_BTN_B_PRESENT) {
+ xf86Msg (X_ERROR, "%s: %s: Button %d already claimed.\n", pInfo->name, name, btn_plus);
+ return 0;
+ }
+
+ option = option->next;
+ if (!option) {
+ xf86Msg (X_ERROR, "%s: %s: No button minus.\n", pInfo->name, name);
+ return 0;
+ }
+
+ errno = 0;
+ btn_minus = strtol (option->str, NULL, 0);
+ if (errno)
+ btn_minus = EvdevBtnFind (pInfo, option->str);
+ if ((btn_minus < 0) || (btn_minus > BTN_MAX)) {
+ xf86Msg (X_ERROR, "%s: %s: Button %d out of range.\n", pInfo->name, name, btn_minus);
+ return 0;
+ }
+
+ if (btn->b_flags[btn_minus] & EV_BTN_B_PRESENT) {
+ xf86Msg (X_ERROR, "%s: %s: Button %d already claimed.\n", pInfo->name, name, btn_minus);
+ return 0;
+ }
+ errno = 0;
+
+ btn->b_flags[btn_plus] = EV_BTN_B_PRESENT;
+ btn->b_flags[btn_minus] = EV_BTN_B_PRESENT;
+
+ map = calloc(1, sizeof (MapButtons_t));
+ map->button_plus = btn_plus;
+ map->button_minus = btn_minus;
+ map->step = 1;
+
+ *map_data = (void *) map;
+ *map_func = EvdevMapButtons;
+
+ return 1;
+}
+
int
-EvdevBtnInit (DeviceIntPtr device)
+EvdevBtnInit (DeviceIntRec *device)
{
- InputInfoPtr pInfo = device->public.devicePrivate;
- evdevDevicePtr pEvdev = pInfo->private;
+ InputInfoRec *pInfo = device->public.devicePrivate;
+ evdevDeviceRec *pEvdev = pInfo->private;
CARD8 *map;
int i;
@@ -191,10 +320,10 @@ EvdevBtnInit (DeviceIntPtr device)
}
int
-EvdevBtnOn (DeviceIntPtr device)
+EvdevBtnOn (DeviceIntRec *device)
{
- InputInfoPtr pInfo = device->public.devicePrivate;
- evdevDevicePtr pEvdev = pInfo->private;
+ InputInfoRec *pInfo = device->public.devicePrivate;
+ evdevDeviceRec *pEvdev = pInfo->private;
int i, blocked;
if (!pEvdev->state.btn)
@@ -209,161 +338,74 @@ EvdevBtnOn (DeviceIntPtr device)
}
int
-EvdevBtnOff (DeviceIntPtr device)
+EvdevBtnOff (DeviceIntRec *device)
{
return Success;
}
-#if 1
-/*
- * Warning, evil lives here.
- */
-static void
-EvdevBtnCalcRemap (InputInfoPtr pInfo)
-{
- evdevDevicePtr pEvdev = pInfo->private;
- evdevStatePtr state = &pEvdev->state;
- evdevBtnPtr btn = state->btn;
- int i, j, base, clear, fake, bit;
-
- for (i = 0, base = 1, fake = 0; i < pEvdev->state.btn->real_buttons; i++) {
-#if 0
- if (state->rel) {
- do {
- clear = 1;
- for (j = 0; j < REL_MAX; j++) {
- if (state->rel->btnMap[j][0] == (i + base)) {
- base++;
- clear = 0;
- break;
- }
- if (state->rel->btnMap[j][1] == (i + base)) {
- base++;
- clear = 0;
- break;
- }
- }
- } while (!clear);
- }
-#endif
-
- if (!fake && base != 1)
- fake = i;
-
- /*
- * See if the button is ignored for mapping purposes.
- */
- if (btn->ignore[i] & EV_BTN_IGNORE_MAP)
- continue;
- /*
- * See if the button actually exists, otherwise don't bother.
- */
- bit = i;
- bit += BTN_MISC;
- if ((bit >= BTN_MOUSE) && (bit < BTN_JOYSTICK)) {
- bit -= BTN_MOUSE - BTN_MISC;
- } else if ((bit >= BTN_MISC) && (bit < BTN_MOUSE)) {
- bit += BTN_MOUSE - BTN_MISC;
- }
- if (!test_bit (bit, pEvdev->bits.key))
- continue;
-
- btn->buttons = btn->map[i] = i + base;
- }
+int
+EvdevBtnNew0(InputInfoRec *pInfo)
+{
+ evdevDeviceRec *pEvdev = pInfo->private;
+ evdevStateRec *state = &pEvdev->state;
- if ((!fake || fake >= 3) &&
- test_bit(BTN_RIGHT, pEvdev->bits.key) &&
- test_bit(BTN_MIDDLE, pEvdev->bits.key)) {
- base = btn->map[1];
- btn->map[1] = btn->map[2];
- btn->map[2] = base;
- }
+ state->btn = Xcalloc (sizeof (evdevBtnRec));
-#if 0
- if (state->rel) {
- for (i = 0; i < REL_MAX; i++) {
- if (state->rel->btnMap[i][0] > btn->buttons)
- btn->buttons = state->rel->btnMap[i][0];
- if (state->rel->btnMap[i][1] > btn->buttons)
- btn->buttons = state->rel->btnMap[i][1];
- }
- }
-#endif
+ return Success;
}
-#endif
-
int
-EvdevBtnNew0(InputInfoPtr pInfo)
+EvdevBtnNew1(InputInfoRec *pInfo)
{
- evdevDevicePtr pEvdev = pInfo->private;
- evdevStatePtr state = &pEvdev->state;
- char option[64];
- int i, j, btn;
+ evdevDeviceRec *pEvdev = pInfo->private;
+ evdevStateRec *state = &pEvdev->state;
+ evdevBtnRec *btn = state->btn;
+ char option[128], value[128];
+ int i, b, j;
- state->btn = Xcalloc (sizeof (evdevBtnRec));
+ if (!btn)
+ return !Success;
- /*
- * XXX: This is evil.
- * For reasons related to handling pathological remapping cases, and
- * differences between HID and X, pretend a middle button exists
- * whenever a right button exists.
- */
- if (test_bit (BTN_RIGHT, pEvdev->bits.key))
- set_bit (BTN_MIDDLE, pEvdev->bits.key);
-
- for (i = BTN_MISC; i < (KEY_OK - 1); i++) {
- btn = i;
- if ((btn >= BTN_MOUSE) && (btn < BTN_JOYSTICK)) {
- btn -= BTN_MOUSE - BTN_MISC;
- } else if ((btn >= BTN_MISC) && (btn < BTN_MOUSE)) {
- btn += BTN_MOUSE - BTN_MISC;
- }
- btn -= BTN_MISC;
-
- snprintf(option, sizeof(option), "%sIgnoreX", button_names[btn]);
- if (i >= BTN_DIGI && i < BTN_WHEEL)
- j = xf86SetIntOption(pInfo->options, option, 1);
- else
- j = xf86SetIntOption(pInfo->options, option, 0);
- if (j)
- state->btn->ignore[btn] |= EV_BTN_IGNORE_X;
-
- snprintf(option, sizeof(option), "%sIgnoreEvdev", button_names[btn]);
- j = xf86SetIntOption(pInfo->options, option, 0);
- if (j) {
- state->btn->ignore[btn] |= EV_BTN_IGNORE_EVDEV;
+ for (i = 0; i < BTN_MAX; i++) {
+ b = i + BTN_MISC;
+ if (!test_bit (b, pEvdev->bits.key))
continue;
- }
- if (test_bit (i, pEvdev->bits.key))
- state->btn->real_buttons = btn + 1;
+ btn->real_buttons++;
+
+ snprintf(option, sizeof(option), "Button%sMapTo", button_names[i]);
+ if (b >= BTN_DIGI && b < BTN_WHEEL)
+ snprintf (value, sizeof (value), "null");
+ else if (b == BTN_RIGHT)
+ snprintf (value, sizeof (value), "Button 3");
+ else if (b == BTN_MIDDLE)
+ snprintf (value, sizeof (value), "Button 2");
+ else if (b >= BTN_MOUSE && b < BTN_JOYSTICK)
+ snprintf (value, sizeof (value), "Button %d", 1 + i - (BTN_MOUSE - BTN_MISC));
+ else if (b >= BTN_MISC && b < BTN_MOUSE)
+ snprintf (value, sizeof (value), "Button %d", 1 + i + (BTN_MOUSE - BTN_MISC));
+ else if (btn->b_flags[i] & EV_BTN_B_PRESENT) {
+ for (j = i; j < BTN_MAX; j++)
+ if (!(btn->b_flags[j] & EV_BTN_B_PRESENT)) {
+ snprintf (value, sizeof (value), "Button %d", j + 1);
+ break;
+ }
+ } else
+ snprintf (value, sizeof (value), "Button %d", i + 1);
+
+ EvdevParseMapOption (pInfo, option, value, &btn->b_map_data[i], &btn->b_map[i]);
}
if (state->btn->real_buttons)
xf86Msg(X_INFO, "%s: Found %d mouse buttons\n", pInfo->name, state->btn->real_buttons);
- return Success;
-}
-
-int
-EvdevBtnNew1(InputInfoPtr pInfo)
-{
- evdevDevicePtr pEvdev = pInfo->private;
- evdevStatePtr state = &pEvdev->state;
-
- if (!state->btn)
- return !Success;
-
-#if 1
- EvdevBtnCalcRemap (pInfo);
-#else
- state->btn->buttons = state->btn->real_buttons;
-#endif
+ for (i = 0; i < BTN_MAX; i++)
+ if (btn->b_flags[i] & EV_BTN_B_PRESENT)
+ btn->buttons = i + 1;
if (state->btn->buttons)
- xf86Msg(X_INFO, "%s: Configured %d mouse buttons\n", pInfo->name, state->btn->buttons);
+ xf86Msg(X_INFO, "%s: Configured %d mouse buttons.\n", pInfo->name, state->btn->buttons);
else {
Xfree (state->btn);
state->btn = NULL;
@@ -381,10 +423,10 @@ EvdevBtnNew1(InputInfoPtr pInfo)
}
void
-EvdevBtnProcess (InputInfoPtr pInfo, struct input_event *ev)
+EvdevBtnProcess (InputInfoRec *pInfo, struct input_event *ev)
{
- evdevDevicePtr pEvdev = pInfo->private;
- evdevStatePtr state = &pEvdev->state;
+ evdevDeviceRec *pEvdev = pInfo->private;
+ evdevStateRec *state = &pEvdev->state;
int button;
if (!state->btn)
@@ -392,29 +434,17 @@ EvdevBtnProcess (InputInfoPtr pInfo, struct input_event *ev)
button = ev->code;
- if ((ev->code >= BTN_MOUSE) && (ev->code < BTN_JOYSTICK)) {
- button -= BTN_MOUSE - BTN_MISC;
- } else if ((ev->code >= BTN_MISC) && (ev->code < BTN_MOUSE)) {
- button += BTN_MOUSE - BTN_MISC;
- }
-
button -= BTN_MISC;
- if (state->btn->ignore[button] & EV_BTN_IGNORE_EVDEV)
- return;
-
if (state->btn->callback[button])
state->btn->callback[button](pInfo, button, ev->value);
- if (state->btn->ignore[button] & EV_BTN_IGNORE_X)
- return;
-
- button = state->btn->map[button];
- xf86PostButtonEvent (pInfo->dev, 0, button, ev->value, 0, 0);
+ if (state->btn->b_map[button])
+ state->btn->b_map[button](pInfo, ev->value, -1, state->btn->b_map_data[button]);
}
int
-EvdevBtnFind (InputInfoPtr pInfo, const char *button)
+EvdevBtnFind (InputInfoRec *pInfo, const char *button)
{
int i;
@@ -426,19 +456,13 @@ EvdevBtnFind (InputInfoPtr pInfo, const char *button)
}
int
-EvdevBtnExists (InputInfoPtr pInfo, int button)
+EvdevBtnExists (InputInfoRec *pInfo, int button)
{
- evdevDevicePtr pEvdev = pInfo->private;
-
- button += BTN_MISC;
+ evdevDeviceRec *pEvdev = pInfo->private;
- xf86Msg(X_INFO, "%s: Checking button %s (%d)\n", pInfo->name, button_names[button - BTN_MISC], button);
+ xf86Msg(X_INFO, "%s: Checking button %s (%d)\n", pInfo->name, button_names[button], button);
- if ((button >= BTN_MOUSE) && (button < BTN_JOYSTICK)) {
- button -= BTN_MOUSE - BTN_MISC;
- } else if ((button >= BTN_MISC) && (button < BTN_MOUSE)) {
- button += BTN_MOUSE - BTN_MISC;
- }
+ button += BTN_MISC;
xf86Msg(X_INFO, "%s: Checking bit %d\n", pInfo->name, button);
return test_bit(button, pEvdev->bits.key);