Commit 4c68f5d3 authored by Peter Hutterer's avatar Peter Hutterer
Browse files

dix: disable all devices before shutdown

f3410b97

 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's avatarPeter Hutterer <peter.hutterer@who-t.net>
Acked-by: default avatarChase Douglas <chase.douglas@canonical.com>
Reviewed-by: default avatarChase Douglas <chase.douglas@canonical.com>
parent 9c0e8202
......@@ -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.
......
......@@ -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--) {
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment