--- evdev.c 2006-01-12 13:06:44.793306192 -0700 +++ evdev.c 2006-01-09 13:27:26.738258008 -0700 @@ -21,6 +21,7 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Kristian Høgsberg (krh@redhat.com) + * Modified by: Brian Murray (IdleGod@gmail.com) */ #ifdef HAVE_CONFIG_H @@ -58,6 +59,11 @@ #define BTN_TASK 0x117 #endif +/* FIXME: Find a better way to grab the max mouse buttons */ +#ifndef BTN_MAX +#define BTN_MAX 8 +#endif + #ifndef EV_SYN #define EV_SYN EV_RST #endif @@ -79,10 +85,64 @@ #define MODEFLAG 8 #define COMPOSEFLAG 16 +#define MAPTOX (-2) +#define MAPTOY (-3) +#define MAPTONULL (-1) +#define MAPTO_INVERT 1 +#define MAPTO_NORMAL 0 + +typedef void (*EvdevCommonOptProc)(InputInfoPtr pInfo); + typedef struct { int kernel24; + EvdevCommonOptProc CommonOptions; + int negativeX; + int positiveX; + int negativeY; + int positiveY; + int negativeZ; + int positiveZ; + int negativeH; + int positiveH; + int negativeW; + int positiveW; + int * map; } EvdevRec, *EvdevPtr; +#ifdef XFree86LOADER +static const OptionInfoRec *EvdevAvailableOptions(void *unused); +#endif + +typedef enum { + OPTION_ALWAYS_CORE, + OPTION_SEND_CORE_EVENTS, + OPTION_CORE_POINTER, + OPTION_Z_AXIS_MAPPING, + OPTION_H_AXIS_MAPPING, + OPTION_W_AXIS_MAPPING, + OPTION_BTN_MAPPING +} EvdevOpts; + +#ifdef XFree86LOADER +static const OptionInfoRec EvdevOptions[] = { + { OPTION_ALWAYS_CORE, "AlwaysCore", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SEND_CORE_EVENTS, "SendCoreEvents", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_CORE_POINTER, "CorePointer", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_Z_AXIS_MAPPING, "ZAxisMapping", OPTV_STRING, {0}, FALSE }, + { OPTION_W_AXIS_MAPPING, "HAxisMapping", OPTV_STRING, {0}, FALSE }, + { OPTION_H_AXIS_MAPPING, "WAxisMapping", OPTV_STRING, {0}, FALSE }, + { OPTION_BTN_MAPPING, "ButtonMapping", OPTV_STRING, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +static const OptionInfoRec * +EvdevAvailableOptions(void *unused) +{ + return (EvdevOptions); +} +#endif + + static int wheel_up_button = 4; static int wheel_down_button = 5; static int wheel_left_button = 6; @@ -121,6 +181,8 @@ struct input_event ev; int len, value; int dx, dy; + EvdevPtr pEvdev; + pEvdev = pInfo->private; dx = 0; dy = 0; @@ -141,25 +203,103 @@ case EV_REL: switch (ev.code) { case REL_X: - dx += value; + if (pEvdev->positiveX == MAPTONULL) break; + if ( pEvdev->positiveX == MAPTOX ) { + if (pEvdev->negativeX == MAPTO_INVERT) + dx -= value; + else + dx += value; + } else if ( pEvdev->positiveX == MAPTOY ) { + if (pEvdev->negativeX == MAPTO_INVERT) + dy -= value; + else + dy += value; + } else { + if (value > 0) + PostButtonClicks(pInfo, pEvdev->positiveX, value); + if (value < 0) + PostButtonClicks(pInfo, pEvdev->negativeX, -value); + } break; case REL_Y: - dy += value; + if (pEvdev->positiveY == MAPTONULL) break; + if ( pEvdev->positiveY == MAPTOX ) { + if (pEvdev->negativeY == MAPTO_INVERT) + dx -= value; + else + dx += value; + } else if ( pEvdev->positiveY == MAPTOY ) { + if (pEvdev->negativeY == MAPTO_INVERT) + dy -= value; + else + dy += value; + } else { + if (value > 0) + PostButtonClicks(pInfo, pEvdev->positiveY, value); + if (value < 0) + PostButtonClicks(pInfo, pEvdev->negativeY, -value); + } break; case REL_WHEEL: - if (value > 0) - PostButtonClicks(pInfo, wheel_up_button, value); - if (value < 0) - PostButtonClicks(pInfo, wheel_down_button, -value); + if (pEvdev->positiveW == MAPTONULL) break; + if ( pEvdev->positiveW == MAPTOX ) { + if (pEvdev->negativeW == MAPTO_INVERT) + dx += value; + else + dx -= value; + } else if ( pEvdev->positiveW == MAPTOY ) { + if (pEvdev->negativeW == MAPTO_INVERT) + dy += value; + else + dy -= value; + } else { + if (value > 0) + PostButtonClicks(pInfo, pEvdev->positiveW, value); + if (value < 0) + PostButtonClicks(pInfo, pEvdev->negativeW, -value); + } + break; + + case REL_Z: + if (pEvdev->positiveZ == MAPTONULL) break; + if ( pEvdev->positiveZ == MAPTOX ) { + if (pEvdev->negativeZ == MAPTO_INVERT) + dx += value; + else + dx -= value; + } else if ( pEvdev->positiveZ == MAPTOY ) { + if (pEvdev->negativeZ == MAPTO_INVERT) + dy += value; + else + dy -= value; + } else { + if (value > 0) + PostButtonClicks(pInfo, pEvdev->positiveZ, value); + if (value < 0) + PostButtonClicks(pInfo, pEvdev->negativeZ, -value); + } break; case REL_HWHEEL: - if (value > 0) - PostButtonClicks(pInfo, wheel_right_button, value); - if (value < 0) - PostButtonClicks(pInfo, wheel_left_button, -value); + if (pEvdev->positiveH == MAPTONULL) break; + if ( pEvdev->positiveH == MAPTOX ) { + if (pEvdev->negativeZ == MAPTO_INVERT) + dx += value; + else + dx -= value; + } else if ( pEvdev->positiveH == MAPTOY ) { + if (pEvdev->negativeZ == MAPTO_INVERT) + dy += value; + else + dy -= value; + } else { + if (value > 0) + PostButtonClicks(pInfo, pEvdev->positiveH, value); + if (value < 0) + PostButtonClicks(pInfo, pEvdev->negativeH, -value); + } break; } break; @@ -172,19 +312,23 @@ case BTN_LEFT: case BTN_RIGHT: case BTN_MIDDLE: - xf86PostButtonEvent(pInfo->dev, 0, ev.code - BTN_LEFT + 1, + /* + * xf86PostButtonEvent(pInfo->dev, 0, ev.code - BTN_LEFT + 1, value, 0, 0); break; - + */ case BTN_SIDE: case BTN_EXTRA: case BTN_FORWARD: case BTN_BACK: case BTN_TASK: - xf86PostButtonEvent(pInfo->dev, 0, ev.code - BTN_LEFT + 5, + xf86PostButtonEvent(pInfo->dev, 0, pEvdev->map[ev.code - BTN_LEFT], value, 0, 0); + /* + * xf86PostButtonEvent(pInfo->dev, 0, ev.code - BTN_LEFT + 5, + value, 0, 0); + */ break; - default: PostKbdEvent(pInfo, &ev, value); } @@ -640,6 +784,184 @@ return 0; } +static void +evdevCommonOptions(InputInfoPtr pInfo) +{ + EvdevPtr pEvdev; + pEvdev = pInfo->private; + char * s; + int i = 0; + + /* FIXME: Button Max? */ + pEvdev->map = malloc(sizeof(int) * BTN_MAX); + + for (i = 0; i < 3; i++) { + pEvdev->map[i] = i + 1; + } + for (i = 3; i < BTN_MAX; i++) { + pEvdev->map[i] = i + 5; + } + + s = xf86SetStrOption(pInfo->options, "ButtonMapping", ""); + if (s) { + int b1, b2; + do { + if (s[0] == ',') s++; + if (sscanf(s, "%d=%d", &b1, &b2) == 2 && + b1 > 0 && b1 < ( BTN_MAX + 4 ) && + b2 > 0 && b2 < BTN_MAX ) + { + if (b1 > 7) + pEvdev->map[b1 - 5] = b2; + else + pEvdev->map[b1 - 1] = b2; + } + } while ((s = strstr(s, ",")) != NULL); + + } + for (i = 0; i < BTN_MAX; i++) { + xf86Msg(X_INFO, "Mod Button: %d = %d\n", i, pEvdev->map[i]); + } + + s = xf86SetStrOption(pInfo->options, "XAxisMapping", "x"); + if (s) { + int b1, b2; + if (!xf86NameCmp(s, "null")) { + pEvdev->positiveX = MAPTONULL; + } else if (!xf86NameCmp(s, "y")) { + pEvdev->positiveX = MAPTOY; + pEvdev->negativeX = MAPTO_NORMAL; + } else if (!xf86NameCmp(s, "-y")) { + pEvdev->positiveX = MAPTOY; + pEvdev->negativeX = MAPTO_INVERT; + } else if (sscanf(s, "%d %d", &b1, &b2) == 2 && + b1 > 0 && b1 < BTN_MAX && + b2 > 0 && b2 < BTN_MAX ) + { + pEvdev->positiveX = b1; + pEvdev->negativeX = b2; + } else if (!xf86NameCmp(s, "-x")) { + pEvdev->positiveX = MAPTOX; + pEvdev->negativeX = MAPTO_INVERT; + } else { + pEvdev->positiveX = MAPTOX; + pEvdev->negativeX = MAPTO_NORMAL; + } + } + s = xf86SetStrOption(pInfo->options, "YAxisMapping", "y"); + if (s) { + int b1, b2; + if (!xf86NameCmp(s, "null")) { + pEvdev->positiveY = MAPTONULL; + } else if (!xf86NameCmp(s, "x")) { + pEvdev->positiveY = MAPTOX; + pEvdev->negativeY = MAPTO_NORMAL; + } else if (!xf86NameCmp(s, "-x")) { + pEvdev->positiveY = MAPTOX; + pEvdev->negativeY = MAPTO_INVERT; + } else if (sscanf(s, "%d %d", &b1, &b2) == 2 && + b1 > 0 && b1 < BTN_MAX && + b2 > 0 && b2 < BTN_MAX ) + { + pEvdev->positiveY = b1; + pEvdev->negativeY = b2; + } else if (!xf86NameCmp(s, "-y")) { + pEvdev->positiveY = MAPTOY; + pEvdev->negativeY = MAPTO_INVERT; + } else { + pEvdev->positiveY = MAPTOY; + pEvdev->negativeY = MAPTO_NORMAL; + } + } + s = xf86SetStrOption(pInfo->options, "HAxisMapping", "6 7"); + if (s) { + int b1, b2; + if (!xf86NameCmp(s, "null")) { + pEvdev->positiveH = MAPTONULL; + } else if (!xf86NameCmp(s, "x")) { + pEvdev->positiveH = MAPTOX; + pEvdev->negativeH = MAPTO_NORMAL; + } else if (!xf86NameCmp(s, "-x")) { + pEvdev->positiveH = MAPTOX; + pEvdev->negativeH = MAPTO_INVERT; + } else if (!xf86NameCmp(s, "-y")) { + pEvdev->positiveH = MAPTOY; + pEvdev->negativeH = MAPTO_INVERT; + } else if (!xf86NameCmp(s, "y")) { + pEvdev->positiveH = MAPTOY; + pEvdev->negativeH = MAPTO_NORMAL; + } else if (sscanf(s, "%d %d", &b1, &b2) == 2 && + b1 > 0 && b1 < BTN_MAX && + b2 > 0 && b2 < BTN_MAX ) + { + pEvdev->positiveH = b1; + pEvdev->negativeH = b2; + } else { + pEvdev->positiveH = 6; + pEvdev->negativeH = 7; + } + } + s = xf86SetStrOption(pInfo->options, "WAxisMapping", "4 5"); + if (s) { + int b1, b2; + if (!xf86NameCmp(s, "null")) { + pEvdev->positiveW = MAPTONULL; + } else if (!xf86NameCmp(s, "x")) { + pEvdev->positiveW = MAPTOX; + pEvdev->negativeW = MAPTO_NORMAL; + } else if (!xf86NameCmp(s, "-x")) { + pEvdev->positiveW = MAPTOX; + pEvdev->negativeW = MAPTO_INVERT; + } else if (!xf86NameCmp(s, "y")) { + pEvdev->positiveW = MAPTOY; + pEvdev->negativeW = MAPTO_NORMAL; + } else if (!xf86NameCmp(s, "-y")) { + pEvdev->positiveW = MAPTOY; + pEvdev->negativeW = MAPTO_INVERT; + } else if (sscanf(s, "%d %d", &b1, &b2) == 2 && + b1 > 0 && b1 < BTN_MAX && + b2 > 0 && b2 < BTN_MAX ) + { + pEvdev->positiveW = b1; + pEvdev->negativeW = b2; + } else { + pEvdev->positiveW = 4; + pEvdev->negativeW = 5; + } + } + s = xf86SetStrOption(pInfo->options, "ZAxisMapping", "6 7"); + if (s) { + int b1, b2; + if (!xf86NameCmp(s, "null")) { + pEvdev->positiveZ = MAPTONULL; + } else if (!xf86NameCmp(s, "x")) { + pEvdev->positiveZ = MAPTOX; + pEvdev->negativeZ = MAPTO_NORMAL; + } else if (!xf86NameCmp(s, "-x")) { + pEvdev->positiveZ = MAPTOX; + pEvdev->negativeZ = MAPTO_INVERT; + } else if (!xf86NameCmp(s, "y")) { + pEvdev->positiveZ = MAPTOY; + pEvdev->negativeZ = MAPTO_NORMAL; + } else if (!xf86NameCmp(s, "-y")) { + pEvdev->positiveZ = MAPTOY; + pEvdev->negativeZ = MAPTO_INVERT; + } else if (sscanf(s, "%d %d", &b1, &b2) == 2 && + b1 > 0 && b1 < BTN_MAX && + b2 > 0 && b2 < BTN_MAX ) + { + pEvdev->positiveZ = b1; + pEvdev->negativeZ = b2; + } else { + pEvdev->positiveZ = 6; + pEvdev->negativeZ = 7; + } + } + + + +} + static InputInfoPtr EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags) { @@ -672,9 +994,11 @@ if (!(pEvdev = xcalloc(sizeof(*pEvdev), 1))) return pInfo; pInfo->private = pEvdev; + pEvdev->CommonOptions = evdevCommonOptions; xf86CollectInputOptions(pInfo, NULL, NULL); xf86ProcessCommonOptions(pInfo, pInfo->options); + pEvdev->CommonOptions(pInfo); device = xf86CheckStrOption(dev->commonOptions, "Device", NULL); if (!device) { @@ -691,7 +1015,7 @@ if (pInfo->fd < 0) { xf86Msg(X_ERROR, "Unable to open evdev device \"%s\".\n", device); - xfree(pEvdev); + /* xfree(pEvdev); */ return pInfo; }