From 12f9aaff38ac2cf528387ce610e41fbd448698e2 Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Fri, 6 Apr 2012 12:44:07 -0700 Subject: [PATCH 01/14] test/touch: Initialize device name Without this change, the test will segfault when we switch to signal- safe logging. Signed-off-by: Chase Douglas Reviewed-by: Peter Hutterer --- test/touch.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/touch.c b/test/touch.c index 2ec535b43..df1db11de 100644 --- a/test/touch.c +++ b/test/touch.c @@ -40,6 +40,7 @@ touch_grow_queue(void) int i; memset(&dev, 0, sizeof(dev)); + dev.name = "test device"; dev.id = 2; dev.valuator = &val; val.numAxes = 5; @@ -94,6 +95,7 @@ touch_find_ddxid(void) int i; memset(&dev, 0, sizeof(dev)); + dev.name = "test device"; dev.id = 2; dev.valuator = &val; val.numAxes = 5; @@ -162,6 +164,7 @@ touch_begin_ddxtouch(void) int size = 5; memset(&dev, 0, sizeof(dev)); + dev.name = "test device"; dev.id = 2; dev.valuator = &val; val.numAxes = 5; @@ -209,6 +212,7 @@ touch_begin_touch(void) screenInfo.screens[0] = &screen; memset(&dev, 0, sizeof(dev)); + dev.name = "test device"; dev.id = 2; memset(&sprite, 0, sizeof(sprite)); @@ -247,6 +251,7 @@ touch_init(void) screenInfo.screens[0] = &screen; memset(&dev, 0, sizeof(dev)); + dev.name = "test device"; memset(&sprite, 0, sizeof(sprite)); dev.spriteInfo = &sprite; From ff41753b1bee414b16c0f1e8d183776e87c94065 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 6 Jun 2012 14:38:49 +1000 Subject: [PATCH 02/14] xkb: warn if XKB SlowKeys have been automatically enabled Slow keys are enabled when the XKB AccessX features are generally enabled (ctrls->enabled_ctrls & XkbAccessXKeysMask) and either shift key is held for 8 seconds. For the unsuspecting user this appears as if the keyboard suddenly stops working. Print a warning to the log, so we can later tell them "told you so". Signed-off-by: Peter Hutterer Reviewed-by: Dan Nicholson --- xkb/xkbAccessX.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c index 95e28e789..fe28e12d7 100644 --- a/xkb/xkbAccessX.c +++ b/xkb/xkbAccessX.c @@ -295,10 +295,15 @@ AccessXKRGExpire(OsTimerPtr timer, CARD32 now, pointer arg) cn.eventType = 0; cn.requestMajor = 0; cn.requestMinor = 0; - if (xkbi->desc->ctrls->enabled_ctrls & XkbSlowKeysMask) + if (xkbi->desc->ctrls->enabled_ctrls & XkbSlowKeysMask) { AccessXKRGTurnOff((DeviceIntPtr) arg, &cn); - else + LogMessage(X_INFO, "XKB SlowKeys are disabled.\n"); + } + else { AccessXKRGTurnOn((DeviceIntPtr) arg, XkbSlowKeysMask, &cn); + LogMessage(X_INFO, "XKB SlowKeys are now enabled. Hold shift to disable.\n"); + } + return 0; } From 11ecfb8884b7c4def0863a57868a6b9fa1b63ae5 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 May 2012 11:48:05 +1000 Subject: [PATCH 03/14] include: add BUG_RETURN_* macros Helper functions to avoid things like if (foo) { BUG_WARN(foo); return 1; } Signed-off-by: Peter Hutterer Reviewed-by: Chase Douglas Reviewed-by: Alan Coopersmith --- include/misc.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/misc.h b/include/misc.h index 41c13332a..fea74b86c 100644 --- a/include/misc.h +++ b/include/misc.h @@ -381,4 +381,16 @@ extern _X_EXPORT unsigned long serverGeneration; #define BUG_WARN(cond) __BUG_WARN_MSG(cond, 0, NULL) +#define BUG_RETURN(cond) \ + do { if (cond) { __BUG_WARN_MSG(cond, 0, NULL); return; } } while(0) + +#define BUG_RETURN_MSG(cond, ...) \ + do { if (cond) { __BUG_WARN_MSG(cond, 1, __VA_ARGS__); return; } } while(0) + +#define BUG_RETURN_VAL(cond, val) \ + do { if (cond) { __BUG_WARN_MSG(cond, 0, NULL); return (val); } } while(0) + +#define BUG_RETURN_VAL_MSG(cond, val, ...) \ + do { if (cond) { __BUG_WARN_MSG(cond, 1, __VA_ARGS__); return (val); } } while(0) + #endif /* MISC_H */ From 642569fc79a1814acca1c8f529539b054bf36907 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 May 2012 12:11:57 +1000 Subject: [PATCH 04/14] Replace a few BUG_WARN with BUG_RETURN_VAL Signed-off-by: Peter Hutterer Reviewed-by: Chase Douglas --- Xi/exevents.c | 25 ++++++++++--------------- dix/getevents.c | 5 +---- dix/touch.c | 17 ++++++----------- 3 files changed, 17 insertions(+), 30 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 4aad52734..e99bf6c20 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -926,10 +926,10 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent *event) else if (event->type == ET_ProximityOut) device->proximity->in_proximity = FALSE; else if (event->type == ET_TouchBegin) { - BUG_WARN(!b || !v); - BUG_WARN(!t); + BUG_RETURN_VAL(!b || !v, DONT_PROCESS); + BUG_RETURN_VAL(!t, DONT_PROCESS); - if (!b || !t || !b->map[key]) + if (!b->map[key]) return DONT_PROCESS; if (!(event->flags & TOUCH_POINTER_EMULATED) || @@ -941,10 +941,10 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent *event) UpdateDeviceMotionMask(device, t->state, DeviceButtonMotionMask); } else if (event->type == ET_TouchEnd) { - BUG_WARN(!b || !v); - BUG_WARN(!t); + BUG_RETURN_VAL(!b || !v, DONT_PROCESS); + BUG_RETURN_VAL(!t, DONT_PROCESS); - if (!b || !t || t->buttonsDown <= 0 || !b->map[key]) + if (t->buttonsDown <= 0 || !b->map[key]) return DONT_PROCESS; if (!(event->flags & TOUCH_POINTER_EMULATED)) @@ -1356,9 +1356,8 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti, wOtherInputMasks(*win)->inputClients, next) if (xi2mask_isset(iclients->xi2mask, dev, evtype)) break; - BUG_WARN(!iclients); - if (!iclients) - return FALSE; + + BUG_RETURN_VAL(!iclients, FALSE); *mask = iclients->xi2mask; *client = rClient(iclients); @@ -1371,9 +1370,7 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti, wOtherInputMasks(*win)->inputClients, next) if (iclients->mask[dev->id] & xi_filter) break; - BUG_WARN(!iclients); - if (!iclients) - return FALSE; + BUG_RETURN_VAL(!iclients, FALSE); *client = rClient(iclients); } @@ -1414,9 +1411,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, return Success; nevents = TouchConvertToPointerEvent(ev, &motion, &button); - BUG_WARN(nevents == 0); - if (nevents == 0) - return BadValue; + BUG_RETURN_VAL(nevents == 0, BadValue); if (nevents > 1) ptrev = &button; diff --git a/dix/getevents.c b/dix/getevents.c index 4fbaa6c94..baa26c4b8 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -1821,10 +1821,7 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid, if (flags & TOUCH_CLIENT_ID) { /* A DIX-submitted TouchEnd */ touchpoint.dix_ti = TouchFindByClientID(dev, ddx_touchid); - BUG_WARN(!touchpoint.dix_ti); - - if (!touchpoint.dix_ti) - return 0; + BUG_RETURN_VAL(!touchpoint.dix_ti, 0); if (!mask_in || !valuator_mask_isset(mask_in, 0) || diff --git a/dix/touch.c b/dix/touch.c index 401cb981a..082e8f603 100644 --- a/dix/touch.c +++ b/dix/touch.c @@ -598,8 +598,8 @@ TouchConvertToPointerEvent(const InternalEvent *event, int ptrtype; int nevents = 0; - BUG_WARN(!event); - BUG_WARN(!motion_event); + BUG_RETURN_VAL(!event, 0); + BUG_RETURN_VAL(!motion_event, 0); switch (event->any.type) { case ET_TouchUpdate: @@ -627,7 +627,7 @@ TouchConvertToPointerEvent(const InternalEvent *event, motion_event->device_event.flags = XIPointerEmulated; if (nevents > 1) { - BUG_WARN(!button_event); + BUG_RETURN_VAL(!button_event, 0); *button_event = *event; button_event->any.type = ptrtype; button_event->device_event.flags = XIPointerEmulated; @@ -966,10 +966,8 @@ TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener, int nev; int i; - BUG_WARN(listener < 0); - BUG_WARN(listener >= ti->num_listeners); - if (listener < 0 || listener >= ti->num_listeners) - return BadMatch; + BUG_RETURN_VAL(listener < 0, BadMatch); + BUG_RETURN_VAL(listener >= ti->num_listeners, BadMatch); if (listener > 0) { if (mode == XIRejectTouch) @@ -981,10 +979,7 @@ TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener, } events = InitEventList(GetMaximumEventsNum()); - if (!events) { - BUG_WARN_MSG(TRUE, "Failed to allocate touch ownership events\n"); - return BadAlloc; - } + BUG_RETURN_VAL_MSG(!events, BadAlloc, "Failed to allocate touch ownership events\n"); nev = GetTouchOwnershipEvents(events, dev, ti, mode, ti->listeners[0].listener, 0); From 4bcf43919a14cd2cd20af4099cd213ce25792edb Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 May 2012 15:32:47 +1000 Subject: [PATCH 05/14] dix: use BUG_RETURN_VAL for pairing errors Signed-off-by: Peter Hutterer Reviewed-by: Chase Douglas Reviewed-by: Alan Coopersmith --- dix/devices.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dix/devices.c b/dix/devices.c index 0c62a012d..bbb4fa2a9 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -365,13 +365,12 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent) /* mode doesn't matter */ EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor); } - else if ((other = NextFreePointerDevice()) == NULL) { - ErrorF("[dix] cannot find pointer to pair with. " - "This is a bug.\n"); - return FALSE; - } - else + else { + other = NextFreePointerDevice(); + BUG_RETURN_VAL_MSG(other == NULL, FALSE, + "[dix] cannot find pointer to pair with.\n"); PairDevices(NULL, other, dev); + } } else { if (dev->coreEvents) From a86f3ef511db16be5ddc723bf14e770dad23ee45 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 May 2012 11:55:21 +1000 Subject: [PATCH 06/14] dix: change "still paired warning" to use BUG_RETURN_VAL Signed-off-by: Peter Hutterer Reviewed-by: Chase Douglas --- dix/devices.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/dix/devices.c b/dix/devices.c index bbb4fa2a9..c6fd3aa09 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -457,13 +457,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) } if (IsMaster(dev) && dev->spriteInfo->sprite) { - for (other = inputInfo.devices; other; other = other->next) { - if (other->spriteInfo->paired == dev) { - ErrorF("[dix] cannot disable device, still paired. " - "This is a bug. \n"); - return FALSE; - } - } + for (other = inputInfo.devices; other; other = other->next) + BUG_RETURN_VAL_MSG(other->spriteInfo->paired == dev, FALSE, + "%s still paired with %s", dev->name, other->spriteInfo->paired->name); } (void) (*dev->deviceProc) (dev, DEVICE_OFF); From d034605f3914e41e0d636eafff9278be1c041b2c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 May 2012 14:13:20 +1000 Subject: [PATCH 07/14] dix: rename shadowing loop variable in TouchResizeQueue second 'i' shadows the function-wide one, rename to 'j' Signed-off-by: Peter Hutterer Reviewed-by: Chase Douglas --- dix/touch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dix/touch.c b/dix/touch.c index 082e8f603..aa17faf28 100644 --- a/dix/touch.c +++ b/dix/touch.c @@ -103,11 +103,11 @@ TouchResizeQueue(ClientPtr client, pointer closure) tmp = realloc(dev->last.touches, size * sizeof(*dev->last.touches)); if (tmp) { - int i; + int j; dev->last.touches = tmp; - for (i = dev->last.num_touches; i < size; i++) - TouchInitDDXTouchPoint(dev, &dev->last.touches[i]); + for (j = dev->last.num_touches; j < size; j++) + TouchInitDDXTouchPoint(dev, &dev->last.touches[j]); dev->last.num_touches = size; } From 076f9d3a6660fa7fef4ae9decaffd2feebdd32c4 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 May 2012 12:20:37 +1000 Subject: [PATCH 08/14] dix: drop client argument from PairDevices - unused This is a leftover from early MPX days where any keyboard could be paired with any pointer (before the device hierarchy). Signed-off-by: Peter Hutterer Reviewed-by: Chase Douglas --- dix/devices.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/dix/devices.c b/dix/devices.c index c6fd3aa09..df464970f 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -178,12 +178,9 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, /* Pair the keyboard to the pointer device. Keyboard events will follow the * pointer sprite. Only applicable for master devices. - * If the client is set, the request to pair comes from some client. In this - * case, we need to check for access. If the client is NULL, it's from an - * internal automatic pairing, we must always permit this. */ static int -PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd) +PairDevices(DeviceIntPtr ptr, DeviceIntPtr kbd) { if (!ptr) return BadDevice; @@ -369,7 +366,7 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent) other = NextFreePointerDevice(); BUG_RETURN_VAL_MSG(other == NULL, FALSE, "[dix] cannot find pointer to pair with.\n"); - PairDevices(NULL, other, dev); + PairDevices(other, dev); } } else { From 46adcefb0e08515195d8e49985a4e210395700b3 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 May 2012 12:10:12 +1000 Subject: [PATCH 09/14] dix: return early from DisableDevice if the device is already disabled Signed-off-by: Peter Hutterer Reviewed-by: Chase Douglas --- dix/devices.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dix/devices.c b/dix/devices.c index df464970f..6acff4f71 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -428,6 +428,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) BOOL enabled; int flags[MAXDEVICES] = { 0 }; + if (!dev->enabled) + return TRUE; + for (prev = &inputInfo.devices; *prev && (*prev != dev); prev = &(*prev)->next); if (*prev != dev) From e57d6a89027c55fef987cdc259668c48a8b4ea1b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 May 2012 15:32:20 +1000 Subject: [PATCH 10/14] dix: move freeing the sprite into a function Signed-off-by: Peter Hutterer Reviewed-by: Chase Douglas --- dix/devices.c | 7 +------ dix/events.c | 12 ++++++++++++ include/dix.h | 2 ++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/dix/devices.c b/dix/devices.c index 6acff4f71..a280dee28 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -918,12 +918,7 @@ CloseDevice(DeviceIntPtr dev) free(classes); } - if (DevHasCursor(dev) && dev->spriteInfo->sprite) { - if (dev->spriteInfo->sprite->current) - FreeCursor(dev->spriteInfo->sprite->current, None); - free(dev->spriteInfo->sprite->spriteTrace); - free(dev->spriteInfo->sprite); - } + FreeSprite(dev); /* a client may have the device set as client pointer */ for (j = 0; j < currentMaxClients; j++) { diff --git a/dix/events.c b/dix/events.c index 83ae5c965..49894fa26 100644 --- a/dix/events.c +++ b/dix/events.c @@ -3192,6 +3192,18 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin) #endif } +void FreeSprite(DeviceIntPtr dev) +{ + if (DevHasCursor(dev) && dev->spriteInfo->sprite) { + if (dev->spriteInfo->sprite->current) + FreeCursor(dev->spriteInfo->sprite->current, None); + free(dev->spriteInfo->sprite->spriteTrace); + free(dev->spriteInfo->sprite); + } + dev->spriteInfo->sprite = NULL; +} + + /** * Update the mouse sprite info when the server switches from a pScreen to another. * Otherwise, the pScreen of the mouse sprite is never updated when we switch diff --git a/include/dix.h b/include/dix.h index 5dc2ac568..3d8b0e575 100644 --- a/include/dix.h +++ b/include/dix.h @@ -395,6 +395,8 @@ DeliverTouchEvents(DeviceIntPtr /* dev */ , extern void InitializeSprite(DeviceIntPtr /* pDev */ , WindowPtr /* pWin */ ); +extern void +FreeSprite(DeviceIntPtr pDev); extern void UpdateSpriteForScreen(DeviceIntPtr /* pDev */ , From df1704365e700d3cf1d36a241bdfc479159a8df7 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 May 2012 15:33:15 +1000 Subject: [PATCH 11/14] dix: free the sprite when disabling the device Disabled devices don't need sprites (they can't send events anyway) and the device init process is currently geared to check for whether sprite is present to check if the device should be paired/attached. Signed-off-by: Peter Hutterer Reviewed-by: Chase Douglas --- dix/devices.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dix/devices.c b/dix/devices.c index a280dee28..f134f31f9 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -465,6 +465,8 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) (void) (*dev->deviceProc) (dev, DEVICE_OFF); dev->enabled = FALSE; + FreeSprite(dev); + /* now that the device is disabled, we can reset the signal handler's * last.slave */ OsBlockSignals(); From e433d1046c222f9d969c2c28a4651ff9097614f4 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 May 2012 12:42:59 +1000 Subject: [PATCH 12/14] dix: disable non-sprite-owners first when disabling paired devices If a sprite-owner is to be disabled but still paired, disable the paired device first. i.e. disabling a master pointer will disable the master keyboard first. Signed-off-by: Peter Hutterer Reviewed-by: Chase Douglas --- dix/devices.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dix/devices.c b/dix/devices.c index f134f31f9..c5a713f08 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -458,10 +458,13 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) if (IsMaster(dev) && dev->spriteInfo->sprite) { for (other = inputInfo.devices; other; other = other->next) - BUG_RETURN_VAL_MSG(other->spriteInfo->paired == dev, FALSE, - "%s still paired with %s", dev->name, other->spriteInfo->paired->name); + if (other->spriteInfo->paired == dev && !other->spriteInfo->spriteOwner) + DisableDevice(other, sendevent); } + if (dev->spriteInfo->paired) + dev->spriteInfo->paired = NULL; + (void) (*dev->deviceProc) (dev, DEVICE_OFF); dev->enabled = FALSE; From 9c0e820216cd1631f75b037b7908d55ac091692c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 May 2012 12:55:44 +1000 Subject: [PATCH 13/14] Xi: drop forced unpairing when changing the hierarchy Devices are unpaired as needed on DisableDevice now. Signed-off-by: Peter Hutterer Reviewed-by: Chase Douglas --- Xi/xichangehierarchy.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c index 756aaac06..89f16d8be 100644 --- a/Xi/xichangehierarchy.c +++ b/Xi/xichangehierarchy.c @@ -293,12 +293,6 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES]) } } - /* can't disable until we removed pairing */ - keybd->spriteInfo->paired = NULL; - ptr->spriteInfo->paired = NULL; - XTestptr->spriteInfo->paired = NULL; - XTestkeybd->spriteInfo->paired = NULL; - /* disable the remove the devices, XTest devices must be done first else the sprites they rely on will be destroyed */ DisableDevice(XTestptr, FALSE); From 4c68f5d395c66f28b56e488cb3cd12f36820357b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 9 May 2012 09:21:28 +1000 Subject: [PATCH 14/14] dix: disable all devices before shutdown f3410b97cf9b48a47bee3d15d232f8a88e75f4ef introduced a regression on server shutdown. If any button or key was held on shutdown (ctrl, alt, backspace are usually still down) sending a raw event will segfault the server. The the root windows are set to NULL before calling CloseDownDevices(). Avoid this by disabling all devices first when shutting down. Disabled devices won't send events anymore. Master keyboards must be disabled first, otherwise disabling the pointer will trigger DisableDevice(keyboard) and the keyboard is removed from the inputInfo.devices list and moved to inputInfo.off_devices. A regular loop through inputInfo.devices would thus jump to off_devices and not recover. Signed-off-by: Peter Hutterer Acked-by: Chase Douglas Reviewed-by: Chase Douglas --- dix/devices.c | 20 ++++++++++++++++++++ dix/main.c | 4 ++++ include/input.h | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/dix/devices.c b/dix/devices.c index c5a713f08..08875bc3a 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -501,6 +501,26 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) return TRUE; } +void +DisableAllDevices(void) +{ + DeviceIntPtr dev, tmp; + + nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { + if (!IsMaster(dev)) + DisableDevice(dev, FALSE); + } + /* master keyboards need to be disabled first */ + nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { + if (dev->enabled && IsMaster(dev) && IsKeyboardDevice(dev)) + DisableDevice(dev, FALSE); + } + nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { + if (dev->enabled) + DisableDevice(dev, FALSE); + } +} + /** * Initialise a new device through the driver and tell all clients about the * new device. diff --git a/dix/main.c b/dix/main.c index 70dcc946e..df9023e97 100644 --- a/dix/main.c +++ b/dix/main.c @@ -104,6 +104,7 @@ Equipment Corporation. #include "privates.h" #include "registry.h" #include "client.h" +#include "exevents.h" #ifdef PANORAMIX #include "panoramiXsrv.h" #else @@ -295,6 +296,7 @@ main(int argc, char *argv[], char *envp[]) #endif UndisplayDevices(); + DisableAllDevices(); /* Now free up whatever must be freed */ if (screenIsSaved == SCREEN_SAVER_ON) @@ -318,7 +320,9 @@ main(int argc, char *argv[], char *envp[]) for (i = 0; i < screenInfo.numScreens; i++) screenInfo.screens[i]->root = NullWindow; + CloseDownDevices(); + CloseDownEvents(); for (i = screenInfo.numScreens - 1; i >= 0; i--) { diff --git a/include/input.h b/include/input.h index bcf98a63e..5747f3cd2 100644 --- a/include/input.h +++ b/include/input.h @@ -264,7 +264,7 @@ extern _X_EXPORT Bool ActivateDevice(DeviceIntPtr /*device */ , extern _X_EXPORT Bool DisableDevice(DeviceIntPtr /*device */ , BOOL /* sendevent */ ); - +extern void DisableAllDevices(void); extern int InitAndStartDevices(void); extern void CloseDownDevices(void);