[PATCH] xephyr: Re-enabled Xnest fix for focus in + modifier bug.

Xiaoyang Yu (Max) max.a.yu at intel.com
Sun Jun 6 19:24:26 PDT 2010


> -----Original Message-----
> From: Mikhail Gusarov [mailto:dottedmag at dottedmag.net] 
> Sent: 2010年6月4日 17:32
> To: Yu, Max A
> Cc: xorg-devel at lists.x.org
> Subject: Re: [PATCH] xephyr: Re-enabled Xnest fix for focus in + modifier bug.
> 
> 
> Twas brillig at 17:26:46 04.06.2010 UTC+08 when max.a.yu at intel.com did gyre and gimble:
> 
>  XY> This patch is to re-enable it based on current Xnest code.
> 
> I have tried to figure out what's going on in this patch and review it,
> but failed due to line wrapping by your mail client and changes in
> indentation.
> 
> Please split this patch into two: fixing indentation and then functional
> changes, and send them by using something which does not wrap lines,
> like git-send-email(1)

Thanks for your feedback. Seems there is no subcommand "send-email" in
the git version I am using (git 1.7.0.4 on Ubuntu 10.04). I was using
evolution as the mail client. I changed an option in it and hope there
is no wrap-line this time. I also attached a copy of the patch in case
it doesn't work.

The patch actually removed the disabled code from function
ephyrUpdateModifierState() and replaced it with code of function
xnestUpdateModifierState() in source file hw/xnest/Keyboard.c, and
changed it slightly. So I did not change indentation intentionally. The
patch can be applied to my git tree, so I am not sure why it can not be
applied to your git tree due to changes in indentation. 

Please let me know if there is any further issue. Thanks a lot!

--Max


>From 1f66f708da4fa3cd7b379d33b7ed227fb75750d1 Mon Sep 17 00:00:00 2001
From: Xiaoyang Yu (Max) <max.a.yu at intel.com>
Date: Fri, 4 Jun 2010 17:17:53 +0800
Subject: [PATCH] Re-enabled Xnest fix for focus in + modifier bug.
  * See https://bugs.freedesktop.org/show_bug.cgi?id=3030

Signed-off-by: Xiaoyang Yu (Max) <max.a.yu at intel.com>
---
 hw/kdrive/ephyr/ephyr.c |  107 ++++++++++++++++++++---------------------------
 1 files changed, 45 insertions(+), 62 deletions(-)

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index b968516..e734522 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -38,6 +38,8 @@
 #include "ephyrglxext.h"
 #endif /* XF86DRI */
 
+#include "xkbsrv.h"
+
 extern int KdTsPhyScreen;
 #ifdef GLXEXT
 extern Bool noGlxVisualInit;
@@ -748,75 +750,55 @@ ephyrScreenFini (KdScreenInfo *screen)
 void
 ephyrUpdateModifierState(unsigned int state)
 {
-#if 0
-  DeviceIntPtr pkeydev;
-  KeyClassPtr  keyc;
-  int          i;
-  CARD8        mask;
-
-  pkeydev = inputInfo.keyboard;
 
-  if (!pkeydev)
-    return;
+  DeviceIntPtr pDev = inputInfo.keyboard;
+  KeyClassPtr keyc = pDev->key;
+  int i;
+  CARD8 mask;
+  int xkb_state;
   
-/* This is pretty broken.
- *
- * What should happen is that focus out should do as a VT switch does in
- * traditional servers: fake releases for all keys (and buttons too, come
- * to think of it) currently down.  Then, on focus in, get the state from
- * the host, and fake keypresses for everything currently down.
- *
- * So I'm leaving this broken for a little while.  Sorry, folks.
- *
- * -daniels
- */
+  if (!pDev)
+      return;
 
-  keyc = pkeydev->key;
-  
+  xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
   state = state & 0xff;
-  
-  if (keyc->state == state)
+
+  if (xkb_state == state)
     return;
-  
-  for (i = 0, mask = 1; i < 8; i++, mask <<= 1) 
-    {
-      int key;
       
-      /* Modifier is down, but shouldn't be   */
-      if ((keyc->state & mask) && !(state & mask)) 
-	{
-	  int count = keyc->modifierKeyCount[i];
-	  
-	  for (key = 0; key < MAP_LENGTH; key++)
-	    if (keyc->xkbInfo->desc->map->modmap[key] & mask)
-	      {
-		int bit;
-		BYTE *kptr;
-		
-		kptr = &keyc->down[key >> 3];
-		bit = 1 << (key & 7);
-		
-		if (*kptr & bit && ephyrKbd &&
-                    ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
-		  KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */
-		
-		if (--count == 0)
-		  break;
-	      }
-	}
-       
-      /* Modifier shoud be down, but isn't   */
-      if (!(keyc->state & mask) && (state & mask))
-	for (key = 0; key < MAP_LENGTH; key++)
-	  if (keyc->xkbInfo->desc->map->modmap[key] & mask)
-	    {
-              if (keyc->xkbInfo->desc->map->modmap[key] & mask && ephyrKbd &&
-                  ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
-	          KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */
-	      break;
-	    }
+  for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
+    int key;
+
+    /* Modifier is down, but shouldn't be
+     */
+    if ((xkb_state & mask) && !(state & mask)) {
+      int count = keyc->modifierKeyCount[i];
+
+      for (key = 0; key < MAP_LENGTH; key++)
+        if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
+          int bit;
+          BYTE *kptr;
+
+          kptr = &keyc->down[key >> 3];
+          bit = 1 << (key & 7);
+
+          if (*kptr & bit)
+	        KdEnqueueKeyboardEvent (ephyrKbd, key, TRUE);
+
+          if (--count == 0)
+            break;
+        }
     }
-#endif
+
+    /* Modifier shoud be down, but isn't
+     */
+    if (!(xkb_state & mask) && (state & mask))
+      for (key = 0; key < MAP_LENGTH; key++)
+        if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
+	        KdEnqueueKeyboardEvent (ephyrKbd, key, FALSE);
+          break;
+        }
+  }
 }
 
 static void
@@ -998,6 +980,7 @@ ephyrPoll(void)
           if (!ephyrKbd ||
               !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
               continue;
+      ephyrUpdateModifierState(ev.key_state);
 	  KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
 	  break;
 
-- 
1.7.0





More information about the xorg-devel mailing list