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.
master
Zephaniah E. Hull 19 years ago
parent 276685fa1d
commit f15636ac52
  1. 63
      src/evdev.c
  2. 35
      src/evdev.h
  3. 129
      src/evdev_axes.c
  4. 360
      src/evdev_btn.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);

@ -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 */

@ -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);

@ -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);

Loading…
Cancel
Save