diff options
Diffstat (limited to 'hw/xfree86/common/xf86Xinput.c')
-rw-r--r-- | hw/xfree86/common/xf86Xinput.c | 199 |
1 files changed, 161 insertions, 38 deletions
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 17ffed899..c08b15f7e 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -101,7 +101,7 @@ xf86SendDragEvents(DeviceIntPtr device) { LocalDevicePtr local = (LocalDevicePtr) device->public.devicePrivate; - if (device->button->buttonsDown > 0) + if (device->button && device->button->buttonsDown > 0) return (local->flags & XI86_SEND_DRAG_EVENTS); else return (TRUE); @@ -119,10 +119,12 @@ _X_EXPORT void xf86ProcessCommonOptions(LocalDevicePtr local, pointer list) { - if (!xf86SetBoolOption(list, "AlwaysCore", 0) || - xf86SetBoolOption(list, "SendCoreEvents", 0) || - xf86SetBoolOption(list, "CorePointer", 0) || - xf86SetBoolOption(list, "CoreKeyboard", 0)) { + if (xf86SetBoolOption(list, "AlwaysCore", 0) || + !xf86SetBoolOption(list, "SendCoreEvents", 1) || + !xf86SetBoolOption(list, "CorePointer", 1) || + !xf86SetBoolOption(list, "CoreKeyboard", 1)) { + xf86Msg(X_CONFIG, "%s: doesn't report core events\n", local->name); + } else { local->flags |= XI86_ALWAYS_CORE; xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name); } @@ -315,78 +317,137 @@ AddOtherInputDevices() #endif int -NewInputDeviceRequest (InputOption *options) +NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev) { IDevRec *idev = NULL; InputDriverPtr drv = NULL; InputInfoPtr pInfo = NULL; InputOption *option = NULL; DeviceIntPtr dev = NULL; + int rval = Success; idev = xcalloc(sizeof(*idev), 1); if (!idev) return BadAlloc; for (option = options; option; option = option->next) { - if (strcmp(option->key, "driver") == 0) { - if (!xf86LoadOneModule(option->value, NULL)) - return BadName; + if (strcasecmp(option->key, "driver") == 0) { + if (idev->driver) { + rval = BadRequest; + goto unwind; + } + /* Memory leak for every attached device if we don't + * test if the module is already loaded first */ drv = xf86LookupInputDriver(option->value); + if (!drv) + if(xf86LoadOneModule(option->value, NULL)) + drv = xf86LookupInputDriver(option->value); if (!drv) { xf86Msg(X_ERROR, "No input driver matching `%s'\n", option->value); - return BadName; + rval = BadName; + goto unwind; } idev->driver = xstrdup(option->value); if (!idev->driver) { - xfree(idev); - return BadAlloc; + rval = BadAlloc; + goto unwind; } } - if (strcmp(option->key, "name") == 0 || - strcmp(option->key, "identifier") == 0) { + if (strcasecmp(option->key, "name") == 0 || + strcasecmp(option->key, "identifier") == 0) { + if (idev->identifier) { + rval = BadRequest; + goto unwind; + } idev->identifier = xstrdup(option->value); if (!idev->identifier) { - xfree(idev); - return BadAlloc; + rval = BadAlloc; + goto unwind; } } } + if(!idev->driver || !idev->identifier) { + xf86Msg(X_ERROR, "No input driver/identifier specified (ignoring)\n"); + rval = BadRequest; + goto unwind; + } if (!drv->PreInit) { xf86Msg(X_ERROR, "Input driver `%s' has no PreInit function (ignoring)\n", drv->driverName); - return BadImplementation; + rval = BadImplementation; + goto unwind; } - idev->commonOptions = NULL; - for (option = options; option; option = option->next) + for (option = options; option; option = option->next) { + /* Steal option key/value strings from the provided list. + * We need those strings, the InputOption list doesn't. */ idev->commonOptions = xf86addNewOption(idev->commonOptions, option->key, option->value); - idev->extraOptions = NULL; + option->key = NULL; + option->value = NULL; + } pInfo = drv->PreInit(drv, idev, 0); if (!pInfo) { xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n", idev->identifier); - return BadMatch; + rval = BadMatch; + goto unwind; } else if (!(pInfo->flags & XI86_CONFIGURED)) { xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n", idev->identifier); - xf86DeleteInput(pInfo, 0); - return BadMatch; + rval = BadMatch; + goto unwind; } xf86ActivateDevice(pInfo); dev = pInfo->dev; - dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success); - if (dev->inited && dev->startup) + ActivateDevice(dev); + if (dev->inited && dev->startup && xf86Screens[0]->vtSema) EnableDevice(dev); + *pdev = dev; return Success; + +unwind: + if(pInfo) { + if(drv->UnInit) + drv->UnInit(drv, pInfo, 0); + else + xf86DeleteInput(pInfo, 0); + } + if(idev->driver) + xfree(idev->driver); + if(idev->identifier) + xfree(idev->identifier); + xf86optionListFree(idev->commonOptions); + xfree(idev); + return rval; +} + +void +DeleteInputDeviceRequest(DeviceIntPtr pDev) +{ + LocalDevicePtr pInfo = (LocalDevicePtr) pDev->public.devicePrivate; + InputDriverPtr drv = pInfo->drv; + IDevRec *idev = pInfo->conf_idev; + + RemoveDevice(pDev); + + if(drv->UnInit) + drv->UnInit(drv, pInfo, 0); + else + xf86DeleteInput(pInfo, 0); + + xfree(idev->driver); + xfree(idev->identifier); + xf86optionListFree(idev->commonOptions); + xfree(idev); } /* @@ -401,25 +462,46 @@ xf86PostMotionEvent(DeviceIntPtr device, ...) { va_list var; + int i = 0; + static int *valuators = NULL; + static int n_valuators = 0; + + if (num_valuators > n_valuators) { + xfree (valuators); + valuators = NULL; + } + + if (!valuators) { + valuators = xcalloc(sizeof(int), num_valuators); + n_valuators = num_valuators; + } + + va_start(var, num_valuators); + for (i = 0; i < num_valuators; i++) + valuators[i] = va_arg(var, int); + va_end(var); + + xf86PostMotionEventP(device, is_absolute, first_valuator, num_valuators, valuators); +} + +_X_EXPORT void +xf86PostMotionEventP(DeviceIntPtr device, + int is_absolute, + int first_valuator, + int num_valuators, + int *valuators) +{ int i = 0, nevents = 0; int dx, dy; Bool drag = xf86SendDragEvents(device); - int *valuators = NULL; - int flags = 0; xEvent *xE = NULL; int index; + int flags = 0; if (is_absolute) flags = POINTER_ABSOLUTE; else flags = POINTER_RELATIVE | POINTER_ACCELERATE; - - valuators = xcalloc(sizeof(int), num_valuators); - - va_start(var, num_valuators); - for (i = 0; i < num_valuators; i++) - valuators[i] = va_arg(var, int); - va_end(var); #if XFreeXDGA if (first_valuator == 0 && num_valuators >= 2) { @@ -434,7 +516,7 @@ xf86PostMotionEvent(DeviceIntPtr device, dy = valuators[1]; } if (DGAStealMotionEvent(index, dx, dy)) - goto out; + return; } } #endif @@ -456,9 +538,6 @@ xf86PostMotionEvent(DeviceIntPtr device, mieqEnqueue(device, xf86Events + i); } } - -out: - xfree(valuators); } _X_EXPORT void @@ -705,4 +784,48 @@ xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum) } } + +/** + * Deactivate a device. Call this function from the driver if you receive a + * read error or something else that spoils your day. + * Device will be moved to the off_devices list, but it will still be there + * until you really clean up after it. + * Notifies the client about an inactive device. + * + * @param panic True if device is unrecoverable and needs to be removed. + */ +_X_EXPORT void +xf86DisableDevice(DeviceIntPtr dev, Bool panic) +{ + devicePresenceNotify ev; + DeviceIntRec dummyDev; + + if(!panic) + { + DisableDevice(dev); + } else + { + ev.type = DevicePresenceNotify; + ev.time = currentTime.milliseconds; + ev.devchange = DeviceUnrecoverable; + ev.deviceid = dev->id; + dummyDev.id = 0; + SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, + (xEvent *) &ev, 1); + + DeleteInputDeviceRequest(dev); + } +} + +/** + * Reactivate a device. Call this function from the driver if you just found + * out that the read error wasn't quite that bad after all. + * Device will be re-activated, and an event sent to the client. + */ +_X_EXPORT void +xf86EnableDevice(DeviceIntPtr dev) +{ + EnableDevice(dev); +} + /* end of xf86Xinput.c */ |