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:46:23 -0700 |
commit | 81c28ffd2b13a83770eadcfd7829d35d319d637f (patch) | |
tree | 3a601e33945d7d980f06d9f40f78cde4cf413941 /dix | |
parent | e332335241af28ef0ab66b102d0cbc4e5c73ac68 (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.
Diffstat (limited to 'dix')
-rw-r--r-- | dix/devices.c | 1 | ||||
-rw-r--r-- | dix/getevents.c | 37 |
2 files changed, 31 insertions, 7 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) { |