File xf86-input-evdev-xf86DeleteInput.diff of Package xorg-x11-driver-input
>From 1a2019f741cf2d00b2182d4887aaa8a5e39b05fa Mon Sep 17 00:00:00 2001
From: Luc Verhaegen <lverhaegen@ridcully.suse.de>
Date: Thu, 13 Nov 2008 15:37:08 +0100
Subject: [PATCH] Add Driver Uninit to wrap around xf86DeleteInput ourselves.
This solves the double calling of xf86DeleteInput when cleaning up.
Double freeing the same pointer twice makes the kernel SIGABRT us,
killing the X server uglily.
---
src/evdev.c | 21 +++++++++++++++++----
src/evdev.h | 2 +-
src/evdev_brain.c | 43 +++++++++++++++++++++----------------------
3 files changed, 39 insertions(+), 27 deletions(-)
diff --git a/src/evdev.c b/src/evdev.c
index a9bcbb9..765968f 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -214,9 +214,6 @@ EvdevProc(DeviceIntPtr device, int what)
EvdevKeyOff (device);
}
- if (what == DEVICE_CLOSE)
- evdevRemoveDevice(pEvdev);
-
device->public.on = FALSE;
break;
}
@@ -464,6 +461,22 @@ EvdevCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
return NULL;
}
+/*
+ *
+ * Wrap around xf86DeleteInput since we track some things statically
+ * in the driver.
+ *
+ */
+static void
+evdevCoreUnInit(struct _InputDriverRec *drv, struct _LocalDeviceRec *localdev,
+ int flags)
+{
+ InputInfoPtr pInfo = localdev;
+
+ evBrainRemoveDevice(pInfo);
+
+ xf86DeleteInput(pInfo, flags);
+}
_X_EXPORT InputDriverRec EVDEV = {
@@ -471,7 +484,7 @@ _X_EXPORT InputDriverRec EVDEV = {
"evdev",
NULL,
EvdevCorePreInit,
- NULL,
+ evdevCoreUnInit,
NULL,
0
};
diff --git a/src/evdev.h b/src/evdev.h
index c6e9188..1fba2cf 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -255,7 +255,7 @@ int evdevGetFDForDevice (evdevDevicePtr driver);
Bool evdevStart (InputDriverPtr drv);
Bool evdevNewDriver (evdevDriverPtr driver);
Bool evdevGetBits (int fd, evdevBitsPtr bits);
-void evdevRemoveDevice (evdevDevicePtr device);
+void evBrainRemoveDevice(InputInfoPtr pInfo);
int EvdevBtnInit (DeviceIntPtr device);
int EvdevBtnOn (DeviceIntPtr device);
diff --git a/src/evdev_brain.c b/src/evdev_brain.c
index d0d1ac6..28ac4fd 100644
--- a/src/evdev_brain.c
+++ b/src/evdev_brain.c
@@ -48,7 +48,6 @@
#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
#endif
-static Bool evdev_alive = FALSE;
static InputInfoPtr evdev_pInfo = NULL;
static evdevDriverPtr evdev_drivers = NULL;
static int evdev_seq;
@@ -496,14 +492,12 @@ evdevStart (InputDriverPtr drv)
{
InputInfoRec *pInfo;
- if (evdev_alive)
+ if (evdev_pInfo)
return TRUE;
if (!(pInfo = xf86AllocateInput(drv, 0)))
return FALSE;
- evdev_alive = TRUE;
-
pInfo->name = "evdev brain";
pInfo->type_name = "evdev brain";
pInfo->device_control = evdevControl;
@@ -526,7 +520,7 @@ evdevStart (InputDriverPtr drv)
Bool
evdevNewDriver (evdevDriverPtr driver)
{
- if (!evdev_alive)
+ if (!evdev_pInfo)
return FALSE;
/* FIXME: Make this check valid given all the ways to look. */
#if 0
@@ -553,20 +547,26 @@ evdevNewDriver (evdevDriverPtr driver)
}
void
-evdevRemoveDevice (evdevDevicePtr pEvdev)
+evBrainRemoveDevice(InputInfoPtr pInfo)
{
- evdevDriverPtr driver;
- evdevDevicePtr *device;
-
- for (driver = evdev_drivers; driver; driver = driver->next) {
- for (device = &driver->devices; *device; device = &(*device)->next) {
- if (*device == pEvdev) {
- *device = pEvdev->next;
- xf86DeleteInput(pEvdev->pInfo, 0);
- pEvdev->next = NULL;
- return;
- }
- }
+ if (evdev_pInfo == pInfo)
+ evdev_pInfo = NULL;
+ else {
+ evdevDriverPtr driver;
+ evdevDevicePtr device = NULL, prev = NULL;
+
+ for (driver = evdev_drivers; driver; driver = driver->next)
+ for (device = driver->devices; device; prev = device, device = device->next)
+ if (device->pInfo == pInfo)
+ break;
+
+ if (device) {
+ if (prev)
+ prev->next = device->next;
+ else
+ driver->devices = device->next;
+ xfree(device);
+ }
}
}
--
1.5.2.4