move all autorepeat logic to DIX

Move core autorepeat logic for keyboards down to the DIX, remove it from
KDrive.
This commit is contained in:
Daniel Stone 2006-08-07 16:51:39 +03:00 committed by Daniel Stone
parent 5c7001fef8
commit 98fdf874ee
2 changed files with 60 additions and 34 deletions

View File

@ -4661,18 +4661,34 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
}
}
/**
* Convenience wrapper around GetKeyboardValuatorEvents, that takes no
* valuators.
*/
int
GetKeyboardEvents(xEvent **xE, DeviceIntPtr pDev, int type, int key_code) {
return GetKeyboardValuatorEvents(xE, pDev, type, key_code, 0, NULL);
}
/**
* Returns a set of keyboard events for KeyPress/KeyRelease, optionally
* also with valuator events. Handles Xi and XKB.
*
* xE will be set to an array of events, which must be freed by the user;
* the return value is the number of events in xE, which is not
* NULL-terminated.
*
* Note that this function recurses! If called for non-XKB, a repeating
* key press will trigger a matching KeyRelease, as well as the
* KeyPresses.
*/
int GetKeyboardValuatorEvents(xEvent **xE, DeviceIntPtr pDev, int type,
int key_code, int num_valuators,
int *valuators) {
int numEvents = 0, ms = 0, first_valuator = 0;
int numEvents = 0, numRepeatEvents = 0, ms = 0, first_valuator = 0, i = 0;
deviceKeyButtonPointer *kbp = NULL;
deviceValuator *xv = NULL;
xEvent *ev = NULL;
xEvent *ev = NULL, *repeatEvents = NULL;
KeyClassPtr ckeyc;
#ifdef XKB
xkbNewKeyboardNotify nkn;
@ -4693,10 +4709,44 @@ int GetKeyboardValuatorEvents(xEvent **xE, DeviceIntPtr pDev, int type,
if (num_valuators)
numEvents += (num_valuators % 6) + 1;
/* Handle core repeating, via press/release/press/release.
* FIXME: In theory, if you're repeating with two keyboards,
* you could get unbalanced events here. */
if (type == KeyPress &&
((pDev->key->down[key_code >> 3] & (key_code & 7)) & 1)
#ifdef XKB
&& noXkbExtension
#endif
) {
if (!pDev->kbdfeed->ctrl.autoRepeat ||
pDev->key->modifierMap[key_code] ||
!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3]
& (1 << (key_code & 7))))
return 0;
numEvents += GetKeyboardValuatorEvents(&repeatEvents, pDev,
KeyRelease, key_code,
num_valuators, valuators);
}
else if (type == KeyRelease &&
!((pDev->key->down[key_code >> 3] & (key_code & 7)) & 1)
#ifdef XKB
&& noXkbExtension
#endif
) {
return;
}
ev = (xEvent *)xcalloc(sizeof(xEvent), numEvents);
if (!ev)
return 0;
if (repeatEvents) {
for (i = 0; i < numRepeatEvents; i++) {
ev = repeatEvents++;
ev++;
}
}
*xE = ev;
ms = GetTimeInMillis();
@ -4791,7 +4841,7 @@ int GetKeyboardValuatorEvents(xEvent **xE, DeviceIntPtr pDev, int type,
}
#ifdef DEBUG
ErrorF("GKE: putting out %d events with detail %d\n", numEvents, key_code);
ErrorF("GKVE: putting out %d events with detail %d\n", numEvents, key_code);
#endif
return numEvents;
@ -4855,6 +4905,13 @@ acceleratePointer(DeviceIntPtr pDev, int num_valuators, int *valuators)
}
}
/**
* Generate a series of xEvents (returned in xE) representing pointer
* motion, or button presses. Xi and XKB-aware.
*
* xE is not NULL-terminated; the return value is the number of events.
* The user is responsible for freeing these events.
*/
int
GetPointerEvents(xEvent **xE, DeviceIntPtr pDev, int type, int buttons,
int flags, int num_valuators, int *valuators) {
@ -4990,9 +5047,6 @@ GetPointerEvents(xEvent **xE, DeviceIntPtr pDev, int type, int buttons,
kbp->detail = buttons;
}
/* XXX: the spec says that Device{Key,Button}{Press,Release} events
* for relative devices shouldn't contain valuators since only the
* state field will have meaning, but I don't see why. */
if (num_valuators > 2 && (type == MotionNotify ||
flags & POINTER_ABSOLUTE)) {
kbp->deviceid |= MORE_EVENTS;

View File

@ -1943,34 +1943,6 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo *ki,
type = KeyPress;
}
/*
* Check pressed keys which are already down
*/
if (IsKeyDown (ki, key_code) && type == KeyPress) {
/*
* Check auto repeat
*/
if (!ctrl->autoRepeat || keyc->modifierMap[key_code] ||
!(ctrl->autoRepeats[key_code >> 3] & (1 << (key_code & 7))))
return;
/*
* X delivers press/release even for autorepeat
*/
nEvents = GetKeyboardEvents(&xE, ki->dixdev, KeyRelease, key_code);
for (i = 0; i < nEvents; i++)
KdQueueEvent(xE++);
nEvents = GetKeyboardEvents(&xE, ki->dixdev, KeyPress, key_code);
for (i = 0; i < nEvents; i++)
KdQueueEvent(xE++);
}
/*
* Check released keys which are already up
*/
else if (!IsKeyDown (ki, key_code) && type == KeyRelease) {
return;
}
KdCheckSpecialKeys(ki, type, key_code);
KdHandleKeyboardEvent(ki, type, key_code);
nEvents = GetKeyboardEvents(&xE, ki->dixdev, type, key_code);