From 81c28ffd2b13a83770eadcfd7829d35d319d637f Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Wed, 5 Sep 2007 17:46:23 -0700 Subject: [PATCH] Fix key repeats during VT switch. Add keyc->postdown, which represents the key state as of the last mieqEnqueue call, and use it when we need to know the posted state, instead of the processed state (keyc->down). Add small functions to getevents.c to query and modify key state in postdown and use them all through, eliminating previously broken uses. --- dix/devices.c | 1 + dix/getevents.c | 37 +++++++++++++++++++++++++++------- hw/xfree86/common/atKeynames.h | 2 +- include/inputstr.h | 1 + 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/dix/devices.c b/dix/devices.c index 923bc0d86..9f3c57653 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -868,6 +868,7 @@ InitKeyClassDeviceStruct(DeviceIntPtr dev, KeySymsPtr pKeySyms, CARD8 pModifiers else bzero((char *)keyc->modifierMap, MAP_LENGTH); bzero((char *)keyc->down, DOWN_LENGTH); + bzero((char *)keyc->postdown, DOWN_LENGTH); for (i = 0; i < 8; i++) keyc->modifierKeyCount[i] = 0; if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc)) diff --git a/dix/getevents.c b/dix/getevents.c index 68993030d..738bd361f 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -80,6 +80,23 @@ GetMotionHistorySize(void) return MOTION_HISTORY_SIZE; } +static void +set_key_down(DeviceIntPtr pDev, int key_code) +{ + pDev->key->postdown[key_code >> 3] |= (1 << (key_code & 7)); +} + +static void +set_key_up(DeviceIntPtr pDev, int key_code) +{ + pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7)); +} + +static Bool +key_is_down(DeviceIntPtr pDev, int key_code) +{ + return pDev->key->postdown[key_code >> 3] >> (key_code & 7); +} /** * Allocate the motion history buffer. @@ -414,17 +431,15 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, case XK_Shift_Lock: if (type == KeyRelease) return 0; - else if (type == KeyPress && - (pDev->key->down[key_code >> 3] & (key_code & 7)) & 1) - type = KeyRelease; + else if (type == KeyPress && key_is_down(pDev, key_code)) + type = KeyRelease; } } /* Handle core repeating, via press/release/press/release. * FIXME: In theory, if you're repeating with two keyboards in non-XKB, * you could get unbalanced events here. */ - if (type == KeyPress && - (((pDev->key->down[key_code >> 3] & (key_code & 7))) & 1)) { + if (type == KeyPress && key_is_down(pDev, key_code)) { if (!pDev->kbdfeed->ctrl.autoRepeat || pDev->key->modifierMap[key_code] || !(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] @@ -449,6 +464,10 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, events->u.keyButtonPointer.time = ms; events->u.u.type = type; events->u.u.detail = key_code; + if (type == KeyPress) + set_key_down(inputInfo.keyboard, key_code); + else if (type == KeyRelease) + set_key_up(inputInfo.keyboard, key_code); events++; } @@ -456,10 +475,14 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, kbp->time = ms; kbp->deviceid = pDev->id; kbp->detail = key_code; - if (type == KeyPress) + if (type == KeyPress) { kbp->type = DeviceKeyPress; - else if (type == KeyRelease) + set_key_down(pDev, key_code); + } + else if (type == KeyRelease) { kbp->type = DeviceKeyRelease; + set_key_up(pDev, key_code); + } events++; if (num_valuators) { diff --git a/hw/xfree86/common/atKeynames.h b/hw/xfree86/common/atKeynames.h index f31f53377..85f13ac32 100644 --- a/hw/xfree86/common/atKeynames.h +++ b/hw/xfree86/common/atKeynames.h @@ -66,7 +66,7 @@ #define KanaMask Mod4Mask #define ScrollLockMask Mod5Mask -#define KeyPressed(k) (keyc->down[k >> 3] & (1 << (k & 7))) +#define KeyPressed(k) (keyc->postdown[k >> 3] & (1 << (k & 7))) #define ModifierDown(k) ((keyc->state & (k)) == (k)) /* diff --git a/include/inputstr.h b/include/inputstr.h index 3398949d4..d0cc85811 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -122,6 +122,7 @@ typedef struct _GrabRec { typedef struct _KeyClassRec { CARD8 down[DOWN_LENGTH]; + CARD8 postdown[DOWN_LENGTH]; KeyCode *modifierKeyMap; KeySymsRec curKeySyms; int modifierKeyCount[8];