mirror of
https://github.com/X11Libre/xf86-input-evdev.git
synced 2026-04-14 11:44:16 +00:00
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.
This commit is contained in:
63
src/evdev.c
63
src/evdev.c
@@ -98,23 +98,60 @@ evdev_map_parsers_t evdev_map_parsers[] = {
|
||||
.name = "AbsAxis",
|
||||
.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);
|
||||
|
||||
35
src/evdev.h
35
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 */
|
||||
|
||||
129
src/evdev_axes.c
129
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);
|
||||
|
||||
362
src/evdev_btn.c
362
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)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
EvdevBtnInit (DeviceIntPtr device)
|
||||
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)
|
||||
{
|
||||
InputInfoPtr pInfo = device->public.devicePrivate;
|
||||
evdevDevicePtr pEvdev = pInfo->private;
|
||||
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 (DeviceIntRec *device)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
EvdevBtnNew0(InputInfoPtr pInfo)
|
||||
EvdevBtnNew0(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;
|
||||
|
||||
state->btn = Xcalloc (sizeof (evdevBtnRec));
|
||||
|
||||
/*
|
||||
* 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);
|
||||
return Success;
|
||||
}
|
||||
|
||||
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;
|
||||
int
|
||||
EvdevBtnNew1(InputInfoRec *pInfo)
|
||||
{
|
||||
evdevDeviceRec *pEvdev = pInfo->private;
|
||||
evdevStateRec *state = &pEvdev->state;
|
||||
evdevBtnRec *btn = state->btn;
|
||||
char option[128], value[128];
|
||||
int i, b, j;
|
||||
|
||||
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;
|
||||
if (!btn)
|
||||
return !Success;
|
||||
|
||||
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,20 +456,14 @@ EvdevBtnFind (InputInfoPtr pInfo, const char *button)
|
||||
}
|
||||
|
||||
int
|
||||
EvdevBtnExists (InputInfoPtr pInfo, int button)
|
||||
EvdevBtnExists (InputInfoRec *pInfo, int button)
|
||||
{
|
||||
evdevDevicePtr pEvdev = pInfo->private;
|
||||
evdevDeviceRec *pEvdev = pInfo->private;
|
||||
|
||||
xf86Msg(X_INFO, "%s: Checking button %s (%d)\n", pInfo->name, button_names[button], button);
|
||||
|
||||
button += BTN_MISC;
|
||||
|
||||
xf86Msg(X_INFO, "%s: Checking button %s (%d)\n", pInfo->name, button_names[button - BTN_MISC], 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;
|
||||
}
|
||||
|
||||
xf86Msg(X_INFO, "%s: Checking bit %d\n", pInfo->name, button);
|
||||
return test_bit(button, pEvdev->bits.key);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user