diff -Nurd xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c xc-patched/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c --- xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c 2003-10-10 07:06:39.000000000 -0400 +++ xc-patched/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c 2003-12-01 12:54:34.757487668 -0500 @@ -6,12 +6,21 @@ #include "X.h" #include "xf86.h" +#include "xf86Priv.h" #include "xf86Xinput.h" #include "xf86OSmouse.h" #include "xf86_OSlib.h" #include #include #include +#include "mipointer.h" +#include "lnx_evdev.h" + +/* Names of protocols that are handled internally here. */ +static const char *internalNames[] = { + "evdev", + NULL +}; static int SupportedInterfaces(void) @@ -185,6 +194,272 @@ return NULL; } +static const char ** +BuiltinNames(void) +{ + return internalNames; +} + +static Bool +CheckProtocol(const char *protocol) +{ + int i; + + for (i = 0; internalNames[i]; i++) + if (xf86NameCmp(protocol, internalNames[i]) == 0) + return TRUE; + return FALSE; +} + +typedef struct _evdevMseRec { + int packetSize; + int buttons; + Bool sync; + evdevDriver evdev; +} evdevMseRec, *evdevMsePtr; + +static void +evdevMouseReadInput(InputInfoPtr pInfo) +{ + MouseDevPtr pMse; + evdevMsePtr evdevMse; + struct input_event *ev; + int n, bit; + int dx = 0, dy = 0, dz = 0, dw = 0; + + pMse = pInfo->private; + ev = (struct input_event *) pMse->buffer; + evdevMse = pMse->mousePriv; + + if (pInfo->fd == -1) + return; + + do { + n = read(pInfo->fd, pMse->buffer, sizeof(struct input_event)); + if (n == -1) { + xf86Msg(X_ERROR, "%s: Error in reading! (%s) Disabiling.\n", + pInfo->name, strerror(errno)); + RemoveEnabledDevice(pInfo->fd); + xf86RemoveSIGIOHandler(pInfo->fd); + close (pInfo->fd); + pMse->device->public.on = FALSE; + pInfo->fd = -1; + pMse->PostEvent(pInfo, evdevMse->buttons, dx, dy, dz, dw); + return; + } + if (n != sizeof(struct input_event)) { + xf86Msg(X_WARNING, "%s: incomplete packet, size %d\n", pInfo->name, n); + pMse->PostEvent(pInfo, evdevMse->buttons, dx, dy, dz, dw); + return; + } + + switch (ev->type) { + case EV_REL: + switch (ev->code) { + case EV_REL_X: + dx += ev->value; + break; + case EV_REL_Y: + dy += ev->value; + break; + case EV_REL_Z: + case EV_REL_WHEEL: + dz -= ev->value; + break; + case EV_REL_HWHEEL: + dw -= ev->value; + break; + } + break; + case EV_KEY: + if ((ev->code < EV_BTN_MOUSE) || (ev->code >= EV_BTN_JOYSTICK)) + break; + switch (ev->code) { + case EV_BTN_RIGHT: bit = 1 << 0; break; /* 1 */ + case EV_BTN_MIDDLE: bit = 1 << 1; break; /* 2 */ + case EV_BTN_LEFT: bit = 1 << 2; break; /* 3 */ + default: bit = 1 << (ev->code - EV_BTN_MOUSE); break; + } + evdevMse->buttons &= ~bit; + if (ev->value) + evdevMse->buttons |= bit; + break; + case EV_SYN: + switch (ev->code) { + case EV_SYN_REPORT: + pMse->PostEvent(pInfo,evdevMse->buttons,dx, dy, dz, dw); + dx = dy = dz = dw = 0; + break; + } + break; + } + if (!evdevMse->sync) { + pMse->PostEvent(pInfo,evdevMse->buttons,dx, dy, dz, dw); + dx = dy = dz = dw = 0; + } + } while (xf86WaitForInput(pInfo->fd, 0)); + + pMse->PostEvent(pInfo, evdevMse->buttons, dx, dy, dz, dw); + + return; +} + +static void +evdevMouseSigioReadInput (int fd, void *closure) +{ + evdevMouseReadInput ((InputInfoPtr) closure); +} + +static int +evdevMouseProc(DeviceIntPtr pPointer, int what) +{ + InputInfoPtr pInfo; + MouseDevPtr pMse; + evdevMsePtr evdevMse; + unsigned char map[MSE_MAXBUTTONS + 1]; + int i, j, blocked; + unsigned long evtype_bits[NBITS(EV_MAX)]; + unsigned long evkey_bits[NBITS(EV_KEY_MAX)]; + + pInfo = pPointer->public.devicePrivate; + pMse = pInfo->private; + pMse->device = pPointer; + evdevMse = pMse->mousePriv; + + switch (what) { + case DEVICE_INIT: + pPointer->public.on = FALSE; + + evdevMse->evdev.name = xf86SetStrOption(pInfo->options,"Dev Name",NULL); + evdevMse->evdev.phys = xf86SetStrOption(pInfo->options,"Dev Phys",NULL); + evdevMse->evdev.cb_data = pInfo->dev; + evdevMse->evdev.callback = evdevMouseProc; + if (!evdevNewDriver (&evdevMse->evdev)) { + xf86Msg(X_ERROR, "%s: cannot register with evdev brain\n", pInfo->name); + return BadRequest; + } + if ((pInfo->fd = evdevGetFDForDriver (&evdevMse->evdev)) == -1) { + xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name); + return BadRequest; + } + + ioctl(pInfo->fd, EVIOCGBIT(0, EV_MAX), evtype_bits); + if (test_bit(EV_SYN, evtype_bits)) + evdevMse->sync = TRUE; + else + evdevMse->sync = FALSE; + + if (test_bit(EV_KEY, evtype_bits)) { + ioctl(pInfo->fd, EVIOCGBIT(EV_KEY, EV_KEY_MAX), evkey_bits); + i = EV_BTN_LEFT; + for (i = EV_BTN_LEFT, j = 0; i <= EV_BTN_BACK; i++) + if (test_bit(i, evkey_bits)) + j = i - EV_BTN_LEFT; + if (++j > pMse->buttons) pMse->buttons = j; + } + + close(pInfo->fd); + pInfo->fd = -1; + + for (i = 0; i < MSE_MAXBUTTONS; ++i) + map[i + 1] = i + 1; + + InitPointerDeviceStruct((DevicePtr)pPointer, map, + min(pMse->buttons, MSE_MAXBUTTONS), + miPointerGetMotionEvents, pMse->Ctrl, + miPointerGetMotionBufferSize()); + + /* X valuator */ + xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1); + xf86InitValuatorDefaults(pPointer, 0); + /* Y valuator */ + xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1); + xf86InitValuatorDefaults(pPointer, 1); + xf86MotionHistoryAllocate(pInfo); + break; + + case DEVICE_ON: + if (pPointer->public.on) + break; + if ((pInfo->fd = evdevGetFDForDriver (&evdevMse->evdev)) == -1) { + xf86Msg(X_ERROR, "%s: cannot open input device (name: '%s', phys: '%s')\n", pInfo->name, evdevMse->evdev.name, evdevMse->evdev.phys); + return BadRequest; + } + + xf86FlushInput(pInfo->fd); + if (!xf86InstallSIGIOHandler (pInfo->fd, evdevMouseSigioReadInput, pInfo)) + AddEnabledDevice(pInfo->fd); + pMse->lastButtons = 0; + pMse->emulateState = 0; + evdevMse->buttons = 0; + pPointer->public.on = TRUE; + /* + * send button up events for sanity. If no button down is pending + * xf86PostButtonEvent() will discard them. So we are on the safe side. + */ + blocked = xf86BlockSIGIO (); + for (i = 1; i <= 5; i++) + xf86PostButtonEvent(pPointer,0,i,0,0,0); + xf86UnblockSIGIO (blocked); + break; + + case DEVICE_OFF: + case DEVICE_CLOSE: + if (pInfo->fd != -1) { + RemoveEnabledDevice(pInfo->fd); + xf86RemoveSIGIOHandler(pInfo->fd); + close (pInfo->fd); + pInfo->fd = -1; + } + pPointer->public.on = FALSE; + usleep(300000); + break; + } + return Success; +} + + +/* This function is called when the protocol is "evdev". */ +static Bool +evdevMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags) +{ + MouseDevPtr pMse = pInfo->private; + evdevMsePtr evdevMse; + + pMse->protocol = protocol; + xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol); + + /* Collect the options, and process the common options. */ + xf86CollectInputOptions(pInfo, NULL, NULL); + xf86ProcessCommonOptions(pInfo, pInfo->options); + + if (sizeof(struct input_event) <= sizeof(pMse->protoBuf)) + pMse->buffer = pMse->protoBuf; + else + pMse->buffer = xcalloc(sizeof(struct input_event),1); + pMse->mousePriv = evdevMse = xcalloc(sizeof(evdevMseRec), 1); + if ((pMse->buffer == NULL) || (pMse->mousePriv == NULL)) { + xf86Msg(X_ERROR, "%s: cannot allocate buffer\n", pInfo->name); + xfree(pMse); + return FALSE; + } + + if (!evdevStart (pInfo->drv)) { + xf86Msg(X_ERROR, "%s: cannot start evdev brain\n", pInfo->name); + return FALSE; + } + + pMse->CommonOptions(pInfo); + + /* Setup the local procs. */ + pInfo->device_control = evdevMouseProc; + pInfo->read_input = evdevMouseReadInput; + + pInfo->flags |= XI86_CONFIGURED; + + return TRUE; +} + OSMouseInfoPtr xf86OSMouseInit(int flags) { @@ -197,6 +472,8 @@ p->DefaultProtocol = DefaultProtocol; p->FindDevice = FindDevice; p->GuessProtocol = GuessProtocol; + p->CheckProtocol = CheckProtocol; + p->BuiltinNames = BuiltinNames; + p->PreInit = evdevMousePreInit; return p; } -