summaryrefslogtreecommitdiff
path: root/hw/xfree86/common/xf86Xinput.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/common/xf86Xinput.c')
-rw-r--r--hw/xfree86/common/xf86Xinput.c199
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 */