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:
Zephaniah E. Hull
2007-06-06 04:41:54 -04:00
parent 276685fa1d
commit f15636ac52
4 changed files with 291 additions and 298 deletions

View File

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

View File

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

View File

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

View File

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