xserver: Branch 'xorg-server-1.2-apple'

Ben Byer bbyer at kemper.freedesktop.org
Fri Nov 16 04:38:20 PST 2007


 hw/darwin/darwinEvents.c   |  187 ++++++++++++++++++++++++++++++++-------------
 hw/darwin/darwinKeyboard.c |   58 ++++++++++++-
 2 files changed, 187 insertions(+), 58 deletions(-)

New commits:
commit 92024f2ed001e9a8e71d9afbddddbec4dd183d09
Author: Ben Byer <bbyer at bbyer.local>
Date:   Fri Nov 16 04:37:58 2007 -0800

    added a bunch of debugging code to help troubleshoot the stuck
    modifier key issue; much of it may be taken out later.
    Also, hopefully fixed a race condition that may have
    prevented ReleaseModifiers from working in some cases.

diff --git a/hw/darwin/darwinEvents.c b/hw/darwin/darwinEvents.c
index 7984130..0fb5c9a 100644
--- a/hw/darwin/darwinEvents.c
+++ b/hw/darwin/darwinEvents.c
@@ -71,29 +71,8 @@ typedef struct _EventQueue {
 } EventQueueRec, *EventQueuePtr;
 
 static EventQueueRec darwinEventQueue;
-extern KeyClassPtr darwinKeyc;
-#define KeyPressed(k) (darwinKeyc->down[k >> 3] & (1 << (k & 7)))
-
-/*
- * DarwinPressModifierMask
- *  Press or release the given modifier key, specified by its mask.
- */
-static void DarwinPressModifierMask(
-    xEvent *xe,     // must already have type, time and mouse location
-    int mask)       // one of NX_*MASK constants
-{
-    int key = DarwinModifierNXMaskToNXKey(mask);
-
-    DEBUG_LOG("DarwinPressModifierMask(%p, %x, %d)\n", xe, mask, key);
-    if (key != -1) {
-        int keycode = DarwinModifierNXKeyToNXKeycode(key, 0);
-        if (keycode != 0) {
-            xe->u.u.detail = keycode + MIN_KEYCODE;
-            (*darwinEventQueue.pKbd->processInputProc)(xe,
-                            (DeviceIntPtr)darwinEventQueue.pKbd, 1);
-        }
-    }
-}
+extern darwinKeyboardInfo keyInfo;
+#define KeyPressed(k) (((DeviceIntPtr)darwinEventQueue.pKbd)->key->down[k >> 3] & (1 << (k & 7)))
 
 #ifdef NX_DEVICELCTLKEYMASK
 #define CONTROL_MASK(flags) (flags & (NX_DEVICELCTLKEYMASK|NX_DEVICERCTLKEYMASK))
@@ -119,6 +98,104 @@ static void DarwinPressModifierMask(
 #define ALTERNATE_MASK(flags) (NX_ALTERNATEMASK)
 #endif /* NX_DEVICELALTKEYMASK */
 
+#define KEYBOARD_MASK (NX_COMMANDMASK | NX_CONTROLMASK | NX_ALTERNATEMASK | NX_SHIFTMASK | \
+                       NX_SECONDARYFNMASK | NX_ALPHASHIFTMASK | NX_NUMERICPADMASK | \
+                       NX_HELPMASK | NX_DEVICELCTLKEYMASK | NX_DEVICELSHIFTKEYMASK | \
+		       NX_DEVICERSHIFTKEYMASK | NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK | \
+		       NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK | NX_DEVICERCTLKEYMASK)
+                      
+char * decode_event_flags(unsigned int modifiers) {
+  char buf[1024];
+  buf[0]='\0';
+  if (modifiers & NX_DEVICELCTLKEYMASK)   strcat(buf, "NX_DEVICELCTLKEYMASK | ");
+  if (modifiers & NX_DEVICELSHIFTKEYMASK) strcat(buf, "NX_DEVICELSHIFTKEYMASK | ");
+  if (modifiers & NX_DEVICERSHIFTKEYMASK) strcat(buf, "NX_DEVICERSHIFTKEYMASK | ");
+  if (modifiers & NX_DEVICELCMDKEYMASK)   strcat(buf, "NX_DEVICELCMDKEYMASK | ");
+  if (modifiers & NX_DEVICERCMDKEYMASK)   strcat(buf, "NX_DEVICERCMDKEYMASK | ");
+  if (modifiers & NX_DEVICELALTKEYMASK)   strcat(buf, "NX_DEVICELALTKEYMASK | ");
+  if (modifiers & NX_DEVICERALTKEYMASK)   strcat(buf, "NX_DEVICERALTKEYMASK | ");
+  if (modifiers & NX_DEVICERCTLKEYMASK)   strcat(buf, "NX_DEVICERCTLKEYMASK | ");
+
+  if (modifiers & NX_ALPHASHIFTMASK)      strcat(buf, "NX_ALPHASHIFTMASK | ");
+  if (modifiers & NX_SHIFTMASK)           strcat(buf, "NX_SHIFTMASK | ");
+  if (modifiers & NX_CONTROLMASK)         strcat(buf, "NX_CONTROLMASK | ");
+  if (modifiers & NX_ALTERNATEMASK)       strcat(buf, "NX_ALTERNATEMASK | ");
+  if (modifiers & NX_COMMANDMASK)         strcat(buf, "NX_COMMANDMASK | ");
+  if (modifiers & NX_NUMERICPADMASK)      strcat(buf, "NX_NUMERICPADMASK | ");
+  if (modifiers & NX_HELPMASK)            strcat(buf, "NX_HELPMASK | ");
+  if (modifiers & NX_SECONDARYFNMASK)     strcat(buf, "NX_SECONDARYFNMASK | ");
+
+  if (modifiers & NX_STYLUSPROXIMITYMASK) strcat(buf, "NX_STYLUSPROXIMITYMASK | ");
+  if (modifiers & NX_NONCOALSESCEDMASK)   strcat(buf, "NX_NONCOALSESCEDMASK | ");
+  if (modifiers & NX_NULLEVENTMASK)       strcat(buf, "NX_NULLEVENTMASK | ");
+  //  if (modifiers & NX_LMOUSEDOWNMASK)      strcat(buf, "NX_LMOUSEDOWNMASK | ");
+  //  if (modifiers & NX_LMOUSEUPMASK)        strcat(buf, "NX_LMOUSEUPMASK | ");
+  //  if (modifiers & NX_RMOUSEDOWNMASK)      strcat(buf, "NX_RMOUSEDOWNMASK | ");
+  //  if (modifiers & NX_RMOUSEUPMASK)        strcat(buf, "NX_RMOUSEUPMASK | ");
+  //  if (modifiers & NX_OMOUSEDOWNMASK)      strcat(buf, "NX_OMOUSEDOWNMASK | ");
+  //  if (modifiers & NX_OMOUSEUPMASK)        strcat(buf, "NX_OMOUSEUPMASK | ");
+  //  if (modifiers & NX_MOUSEMOVEDMASK)      strcat(buf, "NX_MOUSEMOVEDMASK | ");
+  // if (modifiers & NX_LMOUSEDRAGGEDMASK)   strcat(buf, "NX_LMOUSEDRAGGEDMASK | ");
+  //if (modifiers & NX_RMOUSEDRAGGEDMASK)   strcat(buf, "NX_RMOUSEDRAGGEDMASK | ");
+  //if (modifiers & NX_OMOUSEDRAGGEDMASK)   strcat(buf, "NX_OMOUSEDRAGGEDMASK | ");
+  //if (modifiers & NX_MOUSEENTEREDMASK)    strcat(buf, "NX_MOUSEENTEREDMASK | ");
+  //if (modifiers & NX_MOUSEEXITEDMASK)     strcat(buf, "NX_MOUSEEXITEDMASK | ");
+  if (modifiers & NX_KEYDOWNMASK)         strcat(buf, "NX_KEYDOWNMASK | ");
+  if (modifiers & NX_KEYUPMASK)           strcat(buf, "NX_KEYUPMASK | ");
+  if (modifiers & NX_FLAGSCHANGEDMASK)    strcat(buf, "NX_FLAGSCHANGEDMASK | ");
+  if (modifiers & NX_KITDEFINEDMASK)      strcat(buf, "NX_KITDEFINEDMASK | ");
+  if (modifiers & NX_SYSDEFINEDMASK)      strcat(buf, "NX_SYSDEFINEDMASK | ");
+  if (modifiers & NX_APPDEFINEDMASK)      strcat(buf, "NX_APPDEFINEDMASK | ");
+  
+  if (strlen(buf) < 5) strcpy(buf, "(empty)");
+  else buf[strlen(buf)-3]='\0';
+  return strdup(buf);
+}
+
+char * get_keysym_name(int ks) {
+  switch(ks) {
+  case XK_Alt_L: return "XK_Alt_L";
+  case XK_Alt_R: return "XK_Alt_R";
+  case XK_Meta_L: return "XK_Meta_L";
+  case XK_Meta_R: return "XK_Meta_R";
+  case XK_Control_L: return "XK_Control_L";
+  case XK_Control_R: return "XK_Control_R";
+  case XK_Shift_L: return "XK_Shift_L";
+  case XK_Shift_R: return "XK_Shift_R";
+  case XK_Mode_switch: return "XK_Mode_switch";
+  case XK_Caps_Lock: return "XK_Caps_Lock";
+  }
+  return "???";
+}
+
+/*
+ * DarwinPressModifierMask
+ *  Press or release the given modifier key, specified by its mask.
+ */
+static void DarwinPressModifierMask(
+    xEvent *xe,     // must already have type, time and mouse location
+    int mask)       // one of NX_*MASK constants
+{
+  int key, keycode;
+  key = DarwinModifierNXMaskToNXKey(mask);
+  if (key == -1) {
+    ErrorF("DarwinPressModifierMask: can't find key for mask %x\n", mask);
+    return;
+  }
+  keycode = DarwinModifierNXKeyToNXKeycode(key, 0);    
+  if (keycode == 0) {
+    ErrorF("DarwinPressModifierMask: can't find keycode for mask %x\n", mask);
+    return;
+  }
+  
+  DEBUG_LOG("%x: %s %s\n", mask, xe->u.u.type==KeyPress?"pressing":"releasing",
+	    decode_event_flags(mask));
+  
+  xe->u.u.detail = keycode + MIN_KEYCODE;
+  (*darwinEventQueue.pKbd->processInputProc)(xe,
+           (DeviceIntPtr)darwinEventQueue.pKbd, 1);
+}
+
 /*
  * DarwinUpdateModifiers
  *  Send events to update the modifier state.
@@ -126,23 +203,27 @@ static void DarwinPressModifierMask(
 static void DarwinUpdateModifiers(
     xEvent *xe,         // event template with time and mouse position set
     int pressed,        // KeyPress or KeyRelease
-    int flags )         // modifier flags that have changed
+    unsigned int flags )         // modifier flags that have changed
 {
-    DEBUG_LOG("DarwinUpdateModifiers(%p, %d, %x)\n", xe, pressed, flags);
-    xe->u.u.type = pressed;
-    if (flags & NX_COMMANDMASK) DarwinPressModifierMask(xe, COMMAND_MASK(flags));
-    if (flags & NX_CONTROLMASK) DarwinPressModifierMask(xe, CONTROL_MASK(flags));
-    if (flags & NX_ALTERNATEMASK) DarwinPressModifierMask(xe, ALTERNATE_MASK(flags));
-    if (flags & NX_SHIFTMASK)  DarwinPressModifierMask(xe, SHIFT_MASK(flags));
-    if (flags & NX_SECONDARYFNMASK) DarwinPressModifierMask(xe, NX_SECONDARYFNMASK);
-    if (flags & NX_ALPHASHIFTMASK) {
-		// Alpha shift only sees KeyDown when enabled and KeyUp when disabled,
-		// but X11 wants to see a up/down pair to enable, and again to disable
-		xe->u.u.type = KeyPress;
-        DarwinPressModifierMask(xe, NX_ALPHASHIFTMASK);
-		xe->u.u.type = KeyRelease;
-        DarwinPressModifierMask(xe, NX_ALPHASHIFTMASK);
-    }
+  int i;
+  DEBUG_LOG("DarwinUpdateModifiers(%p, %d, %x, %s)\n", xe, pressed, flags, decode_event_flags(flags));
+  xe->u.u.type = pressed;
+  /* If we have "device specific" flags -- meaning, left or right -- then strip out the generic flag */
+  if (flags & (NX_DEVICELCTLKEYMASK | NX_DEVICERCTLKEYMASK)) flags &= ~NX_CONTROLMASK;
+  if (flags & (NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK)) flags &= ~NX_ALTERNATEMASK;
+  if (flags & (NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK)) flags &= ~NX_COMMANDMASK;
+  if (flags & (NX_DEVICELSHIFTKEYMASK | NX_DEVICERSHIFTKEYMASK)) flags &= ~NX_SHIFTMASK;
+  if (flags == NX_ALPHASHIFTMASK) {
+    // Alpha shift only sees KeyDown when enabled and KeyUp when disabled,
+    // but X11 wants to see a up/down pair to enable, and again to disable
+    xe->u.u.type = KeyPress;
+    DarwinPressModifierMask(xe, NX_ALPHASHIFTMASK);
+    xe->u.u.type = KeyRelease;
+    DarwinPressModifierMask(xe, NX_ALPHASHIFTMASK);
+    flags &= ~NX_ALPHASHIFTMASK;
+  }
+  for(i=0; i < (sizeof(flags)*8); i++) 
+    if (flags & (1 << i)) DarwinPressModifierMask(xe, flags & (1 << i));
 }
 
 /*
@@ -151,18 +232,16 @@ static void DarwinUpdateModifiers(
  * is deactivated (kXDarwinDeactivate) to prevent modifiers from getting stuck if they
  * are held down during a "context" switch -- otherwise, we would miss the KeyUp.
  */
-static void DarwinReleaseModifiers(void) {
+void DarwinReleaseModifiers(void) {
   KeySym *map = NULL;
   xEvent ke;
   int i = 0, j = 0, nevents = 0; 
  
-  DEBUG_LOG("DarwinReleaseModifiers(%p)\n", darwinKeyc);
-  if (!darwinKeyc) return;
-  map = darwinKeyc->curKeySyms.map;
+  DEBUG_LOG("DarwinReleaseModifiers(%p)\n", &keyInfo.keyMap);
   
-  for (i = darwinKeyc->curKeySyms.minKeyCode, map = darwinKeyc->curKeySyms.map;
-       i < darwinKeyc->curKeySyms.maxKeyCode;
-       i++, map += darwinKeyc->curKeySyms.mapWidth) {
+  for (i = MIN_KEYCODE, map =keyInfo.keyMap;
+       i < MAX_KEYCODE;
+       i++, map += GLYPHS_PER_KEY) {
     if (KeyPressed(i)) {
       switch (*map) {
 	/* Don't release the lock keys */
@@ -173,7 +252,7 @@ static void DarwinReleaseModifiers(void) {
       case XK_Kana_Lock:
 	break;
       default:
-	DEBUG_LOG("DarwinReleaseModifiers: releasing key %d\n", i);
+	DEBUG_LOG("DarwinReleaseModifiers: releasing key %d (%s)\n", i, get_keysym_name(*map));
 	  ke.u.keyButtonPointer.time = GetTimeInMillis();
 	  ke.u.keyButtonPointer.rootX = 0;
 	  ke.u.keyButtonPointer.rootY = 0;
@@ -452,12 +531,14 @@ void ProcessInputEvents(void)
             {
                 // Update modifier state.
                 // Any amount of modifiers may have changed.
-                int flags = xe.u.clientMessage.u.l.longs0;
-		DEBUG_LOG("kxDarwinUpdateModifiers(%x, %x)\n", old_flags, flags);
-                DarwinUpdateModifiers(&xe, KeyRelease,
-                                      old_flags & ~flags);
-                DarwinUpdateModifiers(&xe, KeyPress,
-                                      ~old_flags & flags);
+	      unsigned int flags = xe.u.clientMessage.u.l.longs0 & ~NX_NONCOALSESCEDMASK; // ignore that one
+		DEBUG_LOG("kxDarwinUpdateModifiers(%x, %x, %s)\n", old_flags, flags, decode_event_flags(flags));
+		//		DEBUG_LOG("Ignoring these flags: %x %s\n", flags & ~KEYBOARD_MASK, decode_event_flags(flags & ~KEYBOARD_MASK));
+		flags &= KEYBOARD_MASK;
+                if (old_flags & ~flags) DarwinUpdateModifiers(&xe, KeyRelease,
+							      old_flags & ~flags);
+                if (~old_flags & flags) DarwinUpdateModifiers(&xe, KeyPress,
+							      ~old_flags & flags);
                 old_flags = flags;
                 break;
             }
diff --git a/hw/darwin/darwinKeyboard.c b/hw/darwin/darwinKeyboard.c
index 3685bff..111c98a 100644
--- a/hw/darwin/darwinKeyboard.c
+++ b/hw/darwin/darwinKeyboard.c
@@ -217,10 +217,9 @@ static void DarwinChangeKeyboardControl( DeviceIntPtr device, KeybdCtrl *ctrl )
     // keyclick, bell volume / pitch, autorepead, LED's
 }
 
-static darwinKeyboardInfo keyInfo;
+darwinKeyboardInfo keyInfo;
 static FILE *fref = NULL;
 static char *inBuffer = NULL;
-KeyClassPtr darwinKeyc = NULL;
 
 //-----------------------------------------------------------------------------
 // Data Stream Object
@@ -817,7 +816,7 @@ void DarwinKeyboardInit(
     assert( darwinParamConnect = NXOpenEventStatus() );
 
     DarwinLoadKeyboardMapping(&keySyms);
-
+    //    DarwinKeyboardReload(pDev);
     /* Initialize the seed, so we don't reload the keymap unnecessarily
        (and possibly overwrite xinitrc changes) */
     DarwinModeSystemKeymapSeed();
@@ -836,7 +835,7 @@ InitModMap(register KeyClassPtr keyc)
     CARD8 keysPerModifier[8];
     CARD8 mask;
 
-    darwinKeyc = keyc;
+    //    darwinKeyc = keyc;
     if (keyc->modifierKeyMap != NULL)
         xfree (keyc->modifierKeyMap);
 
@@ -888,7 +887,7 @@ DarwinKeyboardReload(DeviceIntPtr pDev)
 
         memmove(pDev->key->modifierMap, keyInfo.modMap, MAP_LENGTH);
         InitModMap(pDev->key);
-    }
+    } else DEBUG_LOG("SetKeySymsMap=0\n");
 
     SendMappingNotify(MappingKeyboard, MIN_KEYCODE, NUM_KEYCODES, 0);
     SendMappingNotify(MappingModifier, 0, 0, 0);
@@ -938,6 +937,32 @@ int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide)
 }
 
 /*
+ * DarwinModifierNXMaskToNXKeyCode
+ *      Returns 0 if mask is not a known modifier mask.
+ */
+int DarwinModifierNXMaskToNXKeyCode(int mask)
+{
+  switch (mask) {
+  case NX_ALPHASHIFTMASK:       return XK_Caps_Lock;
+  case NX_SHIFTMASK: ErrorF("Warning: Received NX_SHIFTMASK, treating as NX_DEVICELSHIFTKEYMASK\n");
+  case NX_DEVICELSHIFTKEYMASK:  return NX_MODIFIERKEY_SHIFT; //XK_Shift_L;
+  case NX_DEVICERSHIFTKEYMASK:  return NX_MODIFIERKEY_RSHIFT; //XK_Shift_R;
+  case NX_CONTROLMASK: ErrorF("Warning: Received NX_CONTROLMASK, treating as NX_DEVICELCTLKEYMASK\n");
+  case NX_DEVICELCTLKEYMASK:    return XK_Control_L;
+  case NX_DEVICERCTLKEYMASK:    return XK_Control_R;
+  case NX_ALTERNATEMASK: ErrorF("Warning: Received NX_ALTERNATEMASK, treating as NX_DEVICELALTKEYMASK\n");
+  case NX_DEVICELALTKEYMASK:    return XK_Alt_L;
+  case NX_DEVICERALTKEYMASK:    return XK_Alt_R;
+  case NX_COMMANDMASK: ErrorF("Warning: Received NX_COMMANDMASK, treating as NX_DEVICELCMDKEYMASK\n");
+  case NX_DEVICELCMDKEYMASK:    return XK_Meta_L;
+  case NX_DEVICERCMDKEYMASK:    return XK_Meta_R;
+  case NX_NUMERICPADMASK:       return XK_Num_Lock;
+  case NX_HELPMASK:             return XK_Help;
+  case NX_SECONDARYFNMASK:      return XK_Control_L; // this seems very wrong, but is what the old code did
+    }
+}
+
+/*
  * DarwinModifierNXMaskToNXKey
  *      Returns -1 if mask is not a known modifier mask.
  */
@@ -972,6 +997,29 @@ int DarwinModifierNXMaskToNXKey(int mask)
     return -1;
 }
 
+char * DarwinModifierNXMaskTostring(int mask)
+{
+    switch (mask) {
+    case NX_ALPHASHIFTMASK: return "NX_ALPHASHIFTMASK";
+    case NX_SHIFTMASK: return "NX_SHIFTMASK";
+    case NX_DEVICELSHIFTKEYMASK: return "NX_DEVICELSHIFTKEYMASK";
+    case NX_DEVICERSHIFTKEYMASK: return "NX_DEVICERSHIFTKEYMASK";
+    case NX_CONTROLMASK: return "NX_CONTROLMASK";
+    case NX_DEVICELCTLKEYMASK: return "NX_DEVICELCTLKEYMASK";
+    case NX_DEVICERCTLKEYMASK: return "NX_DEVICERCTLKEYMASK";
+    case NX_ALTERNATEMASK: return "NX_ALTERNATEMASK";
+    case NX_DEVICELALTKEYMASK: return "NX_DEVICELALTKEYMASK";
+    case NX_DEVICERALTKEYMASK: return "NX_DEVICERALTKEYMASK";
+    case NX_COMMANDMASK: return "NX_COMMANDMASK";
+    case NX_DEVICELCMDKEYMASK: return "NX_DEVICELCMDKEYMASK";
+    case NX_DEVICERCMDKEYMASK: return "NX_DEVICERCMDKEYMASK";
+    case NX_NUMERICPADMASK: return "NX_NUMERICPADMASK";
+    case NX_HELPMASK: return "NX_HELPMASK";
+    case NX_SECONDARYFNMASK: return "NX_SECONDARYFNMASK";
+    }
+    return "unknown mask";
+}
+
 /*
  * DarwinModifierNXKeyToNXMask
  *      Returns 0 if key is not a known modifier key.


More information about the xorg-commit mailing list