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>
This commit is contained in:
Peter Hutterer 2011-11-21 11:41:12 -08:00
parent fac464e310
commit 7af23259d8
4 changed files with 92 additions and 28 deletions

View File

@ -1132,12 +1132,14 @@ NoticeEventTime(InternalEvent *ev)
void void
EnqueueEvent(InternalEvent *ev, DeviceIntPtr device) EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
{ {
QdEventPtr tail = *syncEvents.pendtail; QdEventPtr tail;
QdEventPtr qe; QdEventPtr qe;
SpritePtr pSprite = device->spriteInfo->sprite; SpritePtr pSprite = device->spriteInfo->sprite;
int eventlen; int eventlen;
DeviceEvent *event = &ev->device_event; DeviceEvent *event = &ev->device_event;
tail = list_last_entry(&syncEvents.pending, QdEventRec, next);
NoticeTime((InternalEvent*)event); NoticeTime((InternalEvent*)event);
/* Fix for key repeating bug. */ /* Fix for key repeating bug. */
@ -1196,15 +1198,13 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
qe = malloc(sizeof(QdEventRec) + eventlen); qe = malloc(sizeof(QdEventRec) + eventlen);
if (!qe) if (!qe)
return; return;
qe->next = (QdEventPtr)NULL; list_init(&qe->next);
qe->device = device; qe->device = device;
qe->pScreen = pSprite->hotPhys.pScreen; qe->pScreen = pSprite->hotPhys.pScreen;
qe->months = currentTime.months; qe->months = currentTime.months;
qe->event = (InternalEvent *)(qe + 1); qe->event = (InternalEvent *)(qe + 1);
memcpy(qe->event, event, eventlen); memcpy(qe->event, event, eventlen);
if (tail) list_append(&qe->next, &syncEvents.pending);
syncEvents.pendtail = &tail->next;
*syncEvents.pendtail = qe;
} }
/** /**
@ -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 * 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. * frozen, then re-run from the beginning of the event queue.
*/ */
static void void
PlayReleasedEvents(void) PlayReleasedEvents(void)
{ {
QdEventPtr *prev, qe; QdEventPtr tmp;
QdEventPtr qe;
DeviceIntPtr dev; DeviceIntPtr dev;
DeviceIntPtr pDev; DeviceIntPtr pDev;
prev = &syncEvents.pending; restart:
while ( (qe = *prev) ) list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next) {
{
if (!qe->device->deviceGrab.sync.frozen) if (!qe->device->deviceGrab.sync.frozen)
{ {
*prev = qe->next; list_del(&qe->next);
pDev = qe->device; pDev = qe->device;
if (*syncEvents.pendtail == *prev)
syncEvents.pendtail = prev;
if (qe->event->any.type == ET_Motion) if (qe->event->any.type == ET_Motion)
CheckVirtualMotion(pDev, qe, NullWindow); CheckVirtualMotion(pDev, qe, NullWindow);
syncEvents.time.months = qe->months; syncEvents.time.months = qe->months;
@ -1268,12 +1266,11 @@ PlayReleasedEvents(void)
; ;
if (!dev) if (!dev)
break; break;
/* Playing the event may have unfrozen another device. */ /* Playing the event may have unfrozen another device. */
/* So to play it safe, restart at the head of the queue */ /* 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) for (dev = inputInfo.devices; dev; dev = dev->next)
FreezeThaw(dev, dev->deviceGrab.sync.other || FreezeThaw(dev, dev->deviceGrab.sync.other ||
(dev->deviceGrab.sync.state >= FROZEN)); (dev->deviceGrab.sync.state >= FROZEN));
if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending)) if (syncEvents.playingEvents ||
(!replayDev && list_is_empty(&syncEvents.pending)))
return; return;
syncEvents.playingEvents = TRUE; syncEvents.playingEvents = TRUE;
if (replayDev) if (replayDev)
@ -5258,6 +5256,7 @@ void
InitEvents(void) InitEvents(void)
{ {
int i; int i;
QdEventPtr qe, tmp;
inputInfo.numDevices = 0; inputInfo.numDevices = 0;
inputInfo.devices = (DeviceIntPtr)NULL; inputInfo.devices = (DeviceIntPtr)NULL;
@ -5271,13 +5270,10 @@ InitEvents(void)
syncEvents.replayDev = (DeviceIntPtr)NULL; syncEvents.replayDev = (DeviceIntPtr)NULL;
syncEvents.replayWin = NullWindow; syncEvents.replayWin = NullWindow;
while (syncEvents.pending) if (syncEvents.pending.next)
{ list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next)
QdEventPtr next = syncEvents.pending->next; free(qe);
free(syncEvents.pending); list_init(&syncEvents.pending);
syncEvents.pending = next;
}
syncEvents.pendtail = &syncEvents.pending;
syncEvents.playingEvents = FALSE; syncEvents.playingEvents = FALSE;
syncEvents.time.months = 0; syncEvents.time.months = 0;
syncEvents.time.milliseconds = 0; /* hardly matters */ syncEvents.time.milliseconds = 0; /* hardly matters */

View File

@ -339,6 +339,7 @@ extern _X_EXPORT void NoticeEventTime(InternalEvent *ev);
extern void EnqueueEvent( extern void EnqueueEvent(
InternalEvent * /* ev */, InternalEvent * /* ev */,
DeviceIntPtr /* device */); DeviceIntPtr /* device */);
extern void PlayReleasedEvents(void);
extern void ActivatePointerGrab( extern void ActivatePointerGrab(
DeviceIntPtr /* mouse */, DeviceIntPtr /* mouse */,

View File

@ -575,7 +575,7 @@ extern _X_EXPORT InputInfo inputInfo;
/* for keeping the events for devices grabbed synchronously */ /* for keeping the events for devices grabbed synchronously */
typedef struct _QdEvent *QdEventPtr; typedef struct _QdEvent *QdEventPtr;
typedef struct _QdEvent { typedef struct _QdEvent {
QdEventPtr next; struct list next;
DeviceIntPtr device; DeviceIntPtr device;
ScreenPtr pScreen; /* what screen the pointer was on */ ScreenPtr pScreen; /* what screen the pointer was on */
unsigned long months; /* milliseconds is in the event */ 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. * replayed and processed as if they would come from the device directly.
*/ */
typedef struct _EventSyncInfo { typedef struct _EventSyncInfo {
QdEventPtr pending, /**< list of queued events */ struct list pending;
*pendtail; /**< last event in list */
/** The device to replay events for. Only set in AllowEvents(), in which /** The device to replay events for. Only set in AllowEvents(), in which
* case it is set to the device specified in the request. */ * case it is set to the device specified in the request. */
DeviceIntPtr replayDev; /* kludgy rock to put flag for */ DeviceIntPtr replayDev; /* kludgy rock to put flag for */

View File

@ -1674,8 +1674,75 @@ mieq_test(void) {
mieqFini(); 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) int main(int argc, char** argv)
{ {
dix_enqueue_events();
dix_double_fp_conversion(); dix_double_fp_conversion();
dix_input_valuator_masks(); dix_input_valuator_masks();
dix_input_attributes(); dix_input_attributes();