From 2fc590d7b4617ea64f50aec7d0c926b31fac7b00 Mon Sep 17 00:00:00 2001 From: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br> Date: Tue, 29 Jan 2008 17:59:24 -0200 Subject: [PATCH] Add support for the SAVE_CONTEXT Mandriva patch. --- src/kbd.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 86 insertions(+), 5 deletions(-) diff --git a/src/kbd.c b/src/kbd.c index 68d29c2..ab2105c 100644 --- a/src/kbd.c +++ b/src/kbd.c @@ -51,6 +51,12 @@ #include <X11/extensions/XKBsrv.h> #endif +#ifdef SAVE_CONTEXT +extern jmp_buf clientJumpBuf; +extern jmp_buf serverJumpBuf; +extern xf86InfoRec xf86Info; +#endif + extern int XkbDfltRepeatDelay; extern int XkbDfltRepeatInterval; @@ -544,7 +550,7 @@ KbdProc(DeviceIntPtr device, int what) */ if (pInfo->fd >= 0) { xf86FlushInput(pInfo->fd); - AddEnabledDevice(pInfo->fd); + xf86AddEnabledDevice(pInfo); } device->public.on = TRUE; @@ -558,7 +564,7 @@ KbdProc(DeviceIntPtr device, int what) * Restore original keyboard directness and translation. */ if (pInfo->fd != -1) - RemoveEnabledDevice(pInfo->fd); + xf86RemoveEnabledDevice(pInfo); pKbd->KbdOff(pInfo, what); device->public.on = FALSE; break; @@ -581,6 +587,10 @@ PostKbdEvent(InputInfoPtr pInfo, unsigned int scanCode, Bool down) int keycode; unsigned long changeLock = 0; static int lockkeys = 0; +#ifdef SAVE_CONTEXT +#define TerminateMask (1 << 16) + static int state = 0; +#endif #ifdef DEBUG ErrorF("kbd driver rec scancode: 0x02%x %s\n", scanCode, down?"down":"up"); @@ -634,13 +644,18 @@ PostKbdEvent(InputInfoPtr pInfo, unsigned int scanCode, Bool down) } #ifndef TERMINATE_FALLBACK -#define TERMINATE_FALLBACK 1 +# ifndef SAVE_CONTEXT +# define TERMINATE_FALLBACK 1 +# endif #endif #ifdef XKB if (noXkbExtension -#if TERMINATE_FALLBACK +# if TERMINATE_FALLBACK || specialkey == KEY_BackSpace -#endif +# endif +# ifdef SAVE_CONTEXT + && specialkey != KEY_BackSpace +# endif ) #endif { @@ -675,6 +690,72 @@ sunKeyboards: keyc->curKeySyms.mapWidth * (keycode - keyc->curKeySyms.minKeyCode)); +#ifdef SAVE_CONTEXT + /* TODO: + * + * This code relies on X keyboard code being properly initialized. + * + * Consider checking Xkb or other source to allow using a specialkey other + * then BackSpace. This way, at least xkb Terminate action can be used + * to define the key, and possibly modifiers. + * Note that Xkb will handle the events once the queue is handled, i.e. + * if the user presses Ctrl+Alt+BackSpace during a server lock, Xkb + * data structures will not know Ctrl+Alt is pressed as the event queue + * hasn't been flushed yet. + */ + if ((serverException & SE_SERVERTRAP) && !xf86Info.dontZap) { + if (keysym[0] == XK_Control_L || keysym[0] == XK_Control_R) { + if (down) + state |= ControlMask; + else + state &= ~ControlMask; + } + else if (keysym[0] == XK_Alt_L || keysym[0] == XK_Alt_R) { + if (down) + state |= AltMask; + else + state &= ~AltMask; + } + + if (specialkey == KEY_BackSpace) { + /* Use the "TerminateMask" value to make sure the Ctrl+Alt+Backspace + * used to recovery from a server lockup doesn't end up going down + * to Xkb, that may call the Terminate action. + */ + if (state & TerminateMask) { + if (!down) + state &= ~TerminateMask; + return; + } + else if (state == (AltMask | ControlMask)) { + state |= TerminateMask; + serverException |= SE_SERVERLOCK; + if ((serverException & SE_CLIENTTRAP) && + (!xf86Info.grabInfo.disabled || xf86Info.grabInfo.allowClosedown)) { + /* Assume a Client request caused a lock, so try to kill + * the client and keep running. */ + ErrorF("Kill/terminate client.\n"); + if (serverException & SE_SIGIOBLOCKED) + /* Should always be True, unless keyboard input ins't + * being handled using SIGIO */ + xf86UnblockSIGIO(0); + siglongjmp(clientJumpBuf, 1); + } + /* Otherwise, it is a lock elsewhere, try to restore hardware + * state and exit cleanly. */ + ErrorF("Kill/terminate server.\n"); + xf86ProcessActionEvent(ACTION_TERMINATE, NULL); + siglongjmp(serverJumpBuf, 1); + } + } + else + /* Don't get confused with vt switches, if backspace wasn't pressed + * specialkey now can be a function key and this code will not + * not notice when Alt and Control are released. */ + state &= ~(AltMask | ControlMask); + } +#endif + #ifdef XKB if (pKbd->noXkb) { #endif -- 1.5.3.5