diff options
author | Daniel Stone <daniel@fooishbar.org> | 2007-09-05 17:46:23 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2007-09-05 17:47:50 -0700 |
commit | f73fd98a8636c0df3133a8b9428f3f23ecc788b4 (patch) | |
tree | f8dd02485d2abf49ad21403a9bae8107059e80da | |
parent | 3c5fe1ec377688ab2edc6137b74a7c04b3bc2e7e (diff) |
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.
(cherry picked from commit 81c28ffd2b13a83770eadcfd7829d35d319d637f)
-rw-r--r-- | dix/devices.c | 1 | ||||
-rw-r--r-- | dix/getevents.c | 37 | ||||
-rw-r--r-- | hw/xfree86/common/atKeynames.h | 2 | ||||
-rw-r--r-- | 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 162fa45f8..f92a0211a 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]; |