diff options
author | Peter Hutterer <peter@cs.unisa.edu.au> | 2008-04-28 11:37:52 +0930 |
---|---|---|
committer | Peter Hutterer <peter@cs.unisa.edu.au> | 2008-04-28 11:37:52 +0930 |
commit | 53dba5381fdd8f644e16aaa0ecb05df4dc615b23 (patch) | |
tree | 28e24f1c6847f7af3343b4b32c1001a66f3e38e2 | |
parent | 1fab51edfc82e1ef60dfa29fd5d93478066a3998 (diff) |
dix: if alloc of a master keyboard fails, remove the master pointer.
-rw-r--r-- | dix/devices.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/dix/devices.c b/dix/devices.c index b3c9efcc2..37feb34a3 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -863,6 +863,11 @@ UndisplayDevices() * resources. * Removes both enabled and disabled devices and notifies all devices about * the removal of the device. + * + * No PresenceNotify is sent for device that the client never saw. This can + * happen if a malloc fails during the addition of master devices. If + * dev->init is FALSE it means the client never received a DeviceAdded event, + * so let's not send a DeviceRemoved event either. */ int RemoveDevice(DeviceIntPtr dev) @@ -873,12 +878,14 @@ RemoveDevice(DeviceIntPtr dev) DeviceIntRec dummyDev; ScreenPtr screen = screenInfo.screens[0]; int deviceid; + int initialized; DebugF("(dix) removing device %d\n", dev->id); if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer) return BadImplementation; + initialized = dev->inited; screen->UndisplayCursor(dev, screen); deviceid = dev->id; @@ -914,7 +921,7 @@ RemoveDevice(DeviceIntPtr dev) } } - if (ret == Success) { + if (ret == Success && initialized) { inputInfo.numDevices--; ev.type = DevicePresenceNotify; ev.time = currentTime.milliseconds; @@ -2587,7 +2594,10 @@ AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr* keyboard = AddInputDevice(client, CoreKeyboardProc, TRUE); if (!keyboard) + { + RemoveDevice(pointer); return BadAlloc; + } keyboard->name = xcalloc(strlen(name) + strlen(" keyboard") + 1, sizeof(char)); strcpy(keyboard->name, name); |