summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-11-21 11:41:12 -0800
committerPeter Hutterer <peter.hutterer@who-t.net>2011-12-09 14:56:20 +1000
commit7af23259d88f4c28ed21140f82cc03b3724c06bb (patch)
tree062e96e5e8ab9cf57c59605176a6acf2936ee040
parentfac464e310b82fadcedf790798d1016c4805640b (diff)
dix: switch the syncEvent queue to a struct list
No effective functionality change, just cleanup to make this code slightly more sane. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
-rw-r--r--dix/events.c46
-rw-r--r--include/dix.h1
-rw-r--r--include/inputstr.h6
-rw-r--r--test/input.c67
4 files changed, 92 insertions, 28 deletions
diff --git a/dix/events.c b/dix/events.c
index 4847db005..3c21a964c 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1132,12 +1132,14 @@ NoticeEventTime(InternalEvent *ev)
void
EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
{
- QdEventPtr tail = *syncEvents.pendtail;
+ QdEventPtr tail;
QdEventPtr qe;
SpritePtr pSprite = device->spriteInfo->sprite;
int eventlen;
DeviceEvent *event = &ev->device_event;
+ tail = list_last_entry(&syncEvents.pending, QdEventRec, next);
+
NoticeTime((InternalEvent*)event);
/* Fix for key repeating bug. */
@@ -1196,15 +1198,13 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
qe = malloc(sizeof(QdEventRec) + eventlen);
if (!qe)
return;
- qe->next = (QdEventPtr)NULL;
+ list_init(&qe->next);
qe->device = device;
qe->pScreen = pSprite->hotPhys.pScreen;
qe->months = currentTime.months;
qe->event = (InternalEvent *)(qe + 1);
memcpy(qe->event, event, eventlen);
- if (tail)
- syncEvents.pendtail = &tail->next;
- *syncEvents.pendtail = qe;
+ list_append(&qe->next, &syncEvents.pending);
}
/**
@@ -1216,22 +1216,20 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
* If there is none, we're done. If there is at least one device that is not
* frozen, then re-run from the beginning of the event queue.
*/
-static void
+void
PlayReleasedEvents(void)
{
- QdEventPtr *prev, qe;
+ QdEventPtr tmp;
+ QdEventPtr qe;
DeviceIntPtr dev;
DeviceIntPtr pDev;
- prev = &syncEvents.pending;
- while ( (qe = *prev) )
- {
+restart:
+ list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next) {
if (!qe->device->deviceGrab.sync.frozen)
{
- *prev = qe->next;
- pDev = qe->device;
- if (*syncEvents.pendtail == *prev)
- syncEvents.pendtail = prev;
+ list_del(&qe->next);
+ pDev = qe->device;
if (qe->event->any.type == ET_Motion)
CheckVirtualMotion(pDev, qe, NullWindow);
syncEvents.time.months = qe->months;
@@ -1268,12 +1266,11 @@ PlayReleasedEvents(void)
;
if (!dev)
break;
+
/* Playing the event may have unfrozen another device. */
/* So to play it safe, restart at the head of the queue */
- prev = &syncEvents.pending;
+ goto restart;
}
- else
- prev = &qe->next;
}
}
@@ -1314,7 +1311,8 @@ ComputeFreezes(void)
for (dev = inputInfo.devices; dev; dev = dev->next)
FreezeThaw(dev, dev->deviceGrab.sync.other ||
(dev->deviceGrab.sync.state >= FROZEN));
- if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+ if (syncEvents.playingEvents ||
+ (!replayDev && list_is_empty(&syncEvents.pending)))
return;
syncEvents.playingEvents = TRUE;
if (replayDev)
@@ -5258,6 +5256,7 @@ void
InitEvents(void)
{
int i;
+ QdEventPtr qe, tmp;
inputInfo.numDevices = 0;
inputInfo.devices = (DeviceIntPtr)NULL;
@@ -5271,13 +5270,10 @@ InitEvents(void)
syncEvents.replayDev = (DeviceIntPtr)NULL;
syncEvents.replayWin = NullWindow;
- while (syncEvents.pending)
- {
- QdEventPtr next = syncEvents.pending->next;
- free(syncEvents.pending);
- syncEvents.pending = next;
- }
- syncEvents.pendtail = &syncEvents.pending;
+ if (syncEvents.pending.next)
+ list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next)
+ free(qe);
+ list_init(&syncEvents.pending);
syncEvents.playingEvents = FALSE;
syncEvents.time.months = 0;
syncEvents.time.milliseconds = 0; /* hardly matters */
diff --git a/include/dix.h b/include/dix.h
index 34661f3b6..8e35d2cf5 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -339,6 +339,7 @@ extern _X_EXPORT void NoticeEventTime(InternalEvent *ev);
extern void EnqueueEvent(
InternalEvent * /* ev */,
DeviceIntPtr /* device */);
+extern void PlayReleasedEvents(void);
extern void ActivatePointerGrab(
DeviceIntPtr /* mouse */,
diff --git a/include/inputstr.h b/include/inputstr.h
index f482a2294..0568e0c9d 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -575,7 +575,7 @@ extern _X_EXPORT InputInfo inputInfo;
/* for keeping the events for devices grabbed synchronously */
typedef struct _QdEvent *QdEventPtr;
typedef struct _QdEvent {
- QdEventPtr next;
+ struct list next;
DeviceIntPtr device;
ScreenPtr pScreen; /* what screen the pointer was on */
unsigned long months; /* milliseconds is in the event */
@@ -591,8 +591,8 @@ typedef struct _QdEvent {
* replayed and processed as if they would come from the device directly.
*/
typedef struct _EventSyncInfo {
- QdEventPtr pending, /**< list of queued events */
- *pendtail; /**< last event in list */
+ struct list pending;
+
/** The device to replay events for. Only set in AllowEvents(), in which
* case it is set to the device specified in the request. */
DeviceIntPtr replayDev; /* kludgy rock to put flag for */
diff --git a/test/input.c b/test/input.c
index 5b4c8c193..c44e5f613 100644
--- a/test/input.c
+++ b/test/input.c
@@ -1674,8 +1674,75 @@ mieq_test(void) {
mieqFini();
}
+/* Simple check that we're replaying events in-order */
+static void
+process_input_proc(InternalEvent *ev, DeviceIntPtr device)
+{
+ static int last_evtype = -1;
+
+ if (ev->any.header == 0xac)
+ last_evtype = -1;
+
+ assert(ev->any.type == ++last_evtype);
+}
+
+static void
+dix_enqueue_events(void) {
+#define NEVENTS 5
+ DeviceIntRec dev;
+ InternalEvent ev[NEVENTS];
+ SpriteInfoRec spriteInfo;
+ SpriteRec sprite;
+ QdEventPtr qe;
+ int i;
+
+ memset(&dev, 0, sizeof(dev));
+ dev.public.processInputProc = process_input_proc;
+
+ memset(&spriteInfo, 0, sizeof(spriteInfo));
+ memset(&sprite, 0, sizeof(sprite));
+ dev.spriteInfo = &spriteInfo;
+ spriteInfo.sprite = &sprite;
+
+ InitEvents();
+ assert(list_is_empty(&syncEvents.pending));
+
+ /* this way PlayReleasedEvents really runs through all events in the
+ * queue */
+ inputInfo.devices = &dev;
+
+ /* to reset process_input_proc */
+ ev[0].any.header = 0xac;
+
+ for (i = 0; i < NEVENTS; i++)
+ {
+ ev[i].any.length = sizeof(*ev);
+ ev[i].any.type = i;
+ EnqueueEvent(&ev[i], &dev);
+ assert(!list_is_empty(&syncEvents.pending));
+ qe = list_last_entry(&syncEvents.pending, QdEventRec, next);
+ assert(memcmp(qe->event, &ev[i], ev[i].any.length) == 0);
+ qe = list_first_entry(&syncEvents.pending, QdEventRec, next);
+ assert(memcmp(qe->event, &ev[0], ev[i].any.length) == 0);
+ }
+
+ /* calls process_input_proc */
+ dev.deviceGrab.sync.frozen = 1;
+ PlayReleasedEvents();
+ assert(!list_is_empty(&syncEvents.pending));
+
+
+ dev.deviceGrab.sync.frozen = 0;
+ PlayReleasedEvents();
+ assert(list_is_empty(&syncEvents.pending));
+
+ inputInfo.devices = NULL;
+}
+
+
int main(int argc, char** argv)
{
+ dix_enqueue_events();
dix_double_fp_conversion();
dix_input_valuator_masks();
dix_input_attributes();