From 9dca441670d261a9a9fb6108960ed48f3d58fb7f Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 6 Sep 2010 11:32:38 +1000 Subject: [PATCH] xfree86: add a hook to replace the new console handler. This hook is only necessary for the keyboard driver to remove the race condition between drain_console() and the driver's ReadInput (Bug 29969). The idea is that a driver that needs to handle events from the console calls xf86ReplaceConsoleHandler() with it's own ReadInput (or NULL) and thus removes the drain_console call. It's the driver's responsibility to restore the previous behaviour when the driver is unloaded. Signed-off-by: Peter Hutterer CC: Thomas Hellstrom Reviewed-by: Tiago Vignatti Reviewed-by: Adam Jackson --- hw/xfree86/common/xf86.h | 1 + hw/xfree86/common/xf86Events.c | 20 ++++++++++++++++++++ hw/xfree86/os-support/linux/lnx_init.c | 4 +--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h index 886c25b13..9f0dda987 100644 --- a/hw/xfree86/common/xf86.h +++ b/hw/xfree86/common/xf86.h @@ -203,6 +203,7 @@ extern _X_EXPORT pointer xf86AddGeneralHandler(int fd, InputHandlerProc proc, po extern _X_EXPORT int xf86RemoveGeneralHandler(pointer handler); extern _X_EXPORT void xf86DisableGeneralHandler(pointer handler); extern _X_EXPORT void xf86EnableGeneralHandler(pointer handler); +extern _X_EXPORT InputHandlerProc xf86SetConsoleHandler(InputHandlerProc handler, pointer data); extern _X_EXPORT void xf86InterceptSignals(int *signo); extern _X_EXPORT void xf86InterceptSigIll(void (*sigillhandler)(void)); extern _X_EXPORT Bool xf86EnableVTSwitch(Bool new); diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 2e82848ce..fdd908abd 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -600,6 +600,26 @@ xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data) return ih; } +/** + * Set the handler for the console's fd. Replaces (and returns) the previous + * handler or NULL, whichever appropriate. + * proc may be NULL if the server should not handle events on the console. + */ +InputHandlerProc +xf86SetConsoleHandler(InputHandlerProc proc, pointer data) +{ + static InputHandlerProc handler = NULL; + InputHandlerProc old_handler = handler; + + if (old_handler) + xf86RemoveGeneralHandler(old_handler); + + xf86AddGeneralHandler(xf86Info.consoleFd, proc, data); + handler = proc; + + return old_handler; +} + static void removeInputHandler(IHPtr ih) { diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c index 92bfde48f..bf61ceb65 100644 --- a/hw/xfree86/os-support/linux/lnx_init.c +++ b/hw/xfree86/os-support/linux/lnx_init.c @@ -277,9 +277,7 @@ xf86OpenConsole(void) tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty); /* need to keep the buffer clean, else the kernel gets angry */ - if (xf86Info.allowEmptyInput) - console_handler = xf86AddGeneralHandler(xf86Info.consoleFd, - drain_console, NULL); + xf86SetConsoleHandler(drain_console, NULL); /* we really should have a InitOSInputDevices() function instead * of Init?$#*&Device(). So I just place it here */