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