Sophie

Sophie

distrib > Mandriva > 2009.0 > i586 > by-pkgid > 4ae609cabfb61da81ad4dcc5f5e1d235 > files > 1

x11-driver-input-keyboard-1.3.1-2mdv2009.0.src.rpm

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