summaryrefslogtreecommitdiff
path: root/dix/events.c
diff options
context:
space:
mode:
authorDaniel Stone <daniel@fooishbar.org>2006-08-07 16:51:39 +0300
committerDaniel Stone <daniels@endtroducing.fooishbar.org>2006-08-07 16:51:39 +0300
commit98fdf874eeadd5b37413922d8afba8415d0c56bb (patch)
tree10afe0ab38dcb5438fdd40e94bfa8f2e5797780c /dix/events.c
parent5c7001fef8ffc6e3d8585a37d3f79a9495be8ed0 (diff)
move all autorepeat logic to DIX
Move core autorepeat logic for keyboards down to the DIX, remove it from KDrive.
Diffstat (limited to 'dix/events.c')
-rw-r--r--dix/events.c66
1 files changed, 60 insertions, 6 deletions
diff --git a/dix/events.c b/dix/events.c
index 5d6b28baf..f87e850ea 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -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;