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:
parent
fac464e310
commit
7af23259d8
44
dix/events.c
44
dix/events.c
|
@ -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 */
|
||||||
|
|
|
@ -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 */,
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
67
test/input.c
67
test/input.c
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue