diff --git a/Xi/exevents.c b/Xi/exevents.c index d00dc2994..2ecec968d 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -61,6 +61,7 @@ SOFTWARE. #include #include #include +#include #include "inputstr.h" #include "windowstr.h" #include "miscstruct.h" @@ -127,7 +128,7 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count) ValuatorClassPtr v = device->valuator; deviceValuator *xV = (deviceValuator *) xE; - if (xE->u.u.type != DeviceValuator) { + if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) { DeviceIntPtr mouse = NULL, kbd = NULL; GetSpritePosition(device, &rootX, &rootY); xE->u.keyButtonPointer.rootX = rootX; diff --git a/Xi/extinit.c b/Xi/extinit.c index c58a10f16..beac426ee 100644 --- a/Xi/extinit.c +++ b/Xi/extinit.c @@ -131,6 +131,13 @@ int ExtEventIndex; Mask ExtValidMasks[EMASKSIZE]; Mask ExtExclusiveMasks[EMASKSIZE]; + +static Mask xi_filters[3] = { + XI_PointerKeyboardPairingChangedNotifyMask, + XI_RandomStringEventMask, + XI_RawDeviceEventMask, +}; + static struct dev_type { Atom type; @@ -1158,6 +1165,9 @@ XInputExtensionInit(void) EventSwapVector[ChangeDeviceNotify] = SEventIDispatch; EventSwapVector[DeviceEnterNotify] = SEventIDispatch; EventSwapVector[DeviceLeaveNotify] = SEventIDispatch; + + /* init GE events */ + SetGenericFilter(IReqCode, xi_filters); } else { FatalError("IExtensionInit: AddExtensions failed\n"); } diff --git a/dix/events.c b/dix/events.c index dc7bbfba7..c8b0eb235 100644 --- a/dix/events.c +++ b/dix/events.c @@ -367,6 +367,14 @@ static Mask filters[128] = CantBeFiltered /* MappingNotify */ }; + +/** + * same principle as filters, but one set of filters for each extension. + * The extension is responsible for setting the filters by calling + * SetGenericFilter(). + */ +static Mask* generic_filters[MAXEXTENSIONS]; + static CARD8 criticalEvents[32] = { 0x7c /* key and button events */ @@ -2176,24 +2184,53 @@ DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab, } else { - if (!(filter & pWin->deliverableEvents)) - return 0; - while (pWin) - { - if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter) - { - FixUpEventFromWindow(dev, xE, pWin, child, FALSE); - deliveries = DeliverEventsToWindow(dev, pWin, xE, count, filter, - grab, 0); - if (deliveries > 0) - return deliveries; - } - if ((deliveries < 0) || - (pWin == stopAt) || - (filter & wDontPropagateMask(pWin))) - return 0; - child = pWin->drawable.id; - pWin = pWin->parent; + /* handle generic events */ + if (type == GenericEvent) + { + xGenericEvent* ge = (xGenericEvent*)xE; + + if (count > 1) + { + ErrorF("Do not send more than one GenericEvent at a time!\n"); + return 0; + } + filter = generic_filters[GEEXTIDX(xE)][ge->evtype]; + + while(pWin) + { + if (GEMaskIsSet(pWin, GEEXT(xE), filter)) + { + deliveries = DeliverEventsToWindow(dev, pWin, xE, count, + filter, grab, 0); + if (deliveries > 0) + return deliveries; + } + + pWin = pWin->parent; + } + } + else + { + /* core protocol events */ + if (!(filter & pWin->deliverableEvents)) + return 0; + while (pWin) + { + if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter) + { + FixUpEventFromWindow(dev, xE, pWin, child, FALSE); + deliveries = DeliverEventsToWindow(dev, pWin, xE, count, filter, + grab, 0); + if (deliveries > 0) + return deliveries; + } + if ((deliveries < 0) || + (pWin == stopAt) || + (filter & wDontPropagateMask(pWin))) + return 0; + child = pWin->drawable.id; + pWin = pWin->parent; + } } } return 0; @@ -5660,3 +5697,15 @@ IsInterferingGrab(ClientPtr client, WindowPtr win, DeviceIntPtr dev, xEvent* eve return mayInterfere; } +/** + * Set the filters for a extension. + * The filters array needs to contain the Masks that are applicable for each + * event type for the given extension. + * e.g. if generic event type 2 should be let through for windows with + * MyExampleMask set, make sure that filters[2] == MyExampleMask. + */ +_X_EXPORT void +SetGenericFilter(int extension, Mask* filters) +{ + generic_filters[extension & 0x7f] = filters; +} diff --git a/dix/getevents.c b/dix/getevents.c index 116bab9f2..4f7993f0a 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -314,13 +314,14 @@ clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators, * last posted, not just x and y; otherwise relative non-x/y * valuators, though a very narrow use case, will be broken. */ -static xEvent * -getValuatorEvents(xEvent *events, DeviceIntPtr pDev, int first_valuator, +static EventList * +getValuatorEvents(EventList *events, DeviceIntPtr pDev, int first_valuator, int num_valuators, int *valuators) { - deviceValuator *xv = (deviceValuator *) events; + deviceValuator *xv; int i = 0, final_valuator = first_valuator + num_valuators; - for (i = first_valuator; i < final_valuator; i += 6, xv++, events++) { + for (i = first_valuator; i < final_valuator; i += 6, events++) { + xv = (deviceValuator*)events->event; xv->type = DeviceValuator; xv->first_valuator = i; xv->num_valuators = num_valuators; @@ -353,7 +354,7 @@ getValuatorEvents(xEvent *events, DeviceIntPtr pDev, int first_valuator, * valuators. */ _X_EXPORT int -GetKeyboardEvents(xEvent *events, DeviceIntPtr pDev, int type, int key_code) { +GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) { return GetKeyboardValuatorEvents(events, pDev, type, key_code, 0, 0, NULL); } @@ -376,7 +377,7 @@ GetKeyboardEvents(xEvent *events, DeviceIntPtr pDev, int type, int key_code) { * KeyPresses. */ _X_EXPORT int -GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, +GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code, int first_valuator, int num_valuators, int *valuators) { int numEvents = 0; @@ -448,7 +449,7 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, ms = GetTimeInMillis(); - kbp = (deviceKeyButtonPointer *) events; + kbp = (deviceKeyButtonPointer *) events->event; kbp->time = ms; kbp->deviceid = pDev->id; if (type == KeyPress) @@ -465,31 +466,85 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, } if (pDev->coreEvents) { - events->u.keyButtonPointer.time = ms; - events->u.u.type = type; - events->u.u.detail = key_code; + xEvent* evt = events->event; + evt->u.keyButtonPointer.time = ms; + evt->u.u.type = type; + evt->u.u.detail = key_code; } return numEvents; } +/** + * Initialize an event list and fill with 32 byte sized events. + * This event list is to be passed into GetPointerEvents() and + * GetKeyboardEvents(). + * + * @param num_events Number of elements in list. + */ +_X_EXPORT EventListPtr +InitEventList(int num_events) +{ + EventListPtr events; + int i; + + events = (EventListPtr)xcalloc(num_events, sizeof(EventList)); + if (!events) + return NULL; + + for (i = 0; i < num_events; i++) + { + events[i].evlen = sizeof(xEvent); + events[i].event = xcalloc(1, sizeof(xEvent)); + if (!events[i].event) + { + /* rollback */ + while(i--) + xfree(events[i].event); + xfree(events); + events = NULL; + break; + } + } + + return events; +} /** - * Generate a series of xEvents (returned in xE) representing pointer - * motion, or button presses. Xi and XKB-aware. + * Free an event list. + * + * @param list The list to be freed. + * @param num_events Number of elements in list. + */ +_X_EXPORT void +FreeEventList(EventListPtr list, int num_events) +{ + if (!list) + return; + while(num_events--) + xfree(list[num_events].event); + xfree(list); +} + +/** + * Generate a series of xEvents (filled into the EventList) representing + * pointer motion, or button presses. Xi and XKB-aware. * * events is not NULL-terminated; the return value is the number of events. * The DDX is responsible for allocating the event structure in the first - * place via GetMaximumEventsNum(), and for freeing it. + * place via InitEventList() and GetMaximumEventsNum(), and for freeing it. * */ _X_EXPORT int -GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, +GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, int flags, int first_valuator, int num_valuators, int *valuators) { - int num_events = 0, final_valuator = 0; + int num_events = 0, final_valuator = 0, i; CARD32 ms = 0; + CARD32* valptr; deviceKeyButtonPointer *kbp = NULL; + rawDeviceEvent* ev; + /* Thanks to a broken lib, we _always_ have to chase DeviceMotionNotifies * with DeviceValuators. */ Bool sendValuators = (type == MotionNotify || flags & POINTER_ABSOLUTE); @@ -506,9 +561,9 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, return 0; if (!coreOnly && (pDev->coreEvents)) - num_events = 2; + num_events = 3; else - num_events = 1; + num_events = 2; if (type == MotionNotify && num_valuators <= 0) { return 0; @@ -529,6 +584,34 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, ms = GetTimeInMillis(); + + /* fill up the raw event, after checking that it is large enough to + * accommodate all valuators. + */ + if (events->evlen < + (sizeof(xEvent) + ((num_valuators - 4) * sizeof(CARD32)))) + { + events->evlen = sizeof(xEvent) + + ((num_valuators - 4) * sizeof(CARD32)); + events->event = realloc(events->event, events->evlen); + if (!events->event) + FatalError("Could not allocate event storage.\n"); + } + + ev = (rawDeviceEvent*)events->event; + ev->type = GenericEvent; + ev->evtype = XI_RawDeviceEvent; + ev->extension = IReqCode; + ev->length = (num_valuators > 4) ? (num_valuators - 4) : 0; + ev->buttons = buttons; + ev->num_valuators = num_valuators; + ev->first_valuator = first_valuator; + ev->deviceid = pDev->id; + valptr = &(ev->valuator0); + for (i = 0; i < num_valuators; i++, valptr++) + *valptr = valuators[i]; + + events++; pointer = pDev; /* Set x and y based on whether this is absolute or relative, and @@ -588,7 +671,7 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, /* create Xi event */ if (!coreOnly) { - kbp = (deviceKeyButtonPointer *) events; + kbp = (deviceKeyButtonPointer *) events->event; kbp->time = ms; kbp->deviceid = pDev->id; @@ -616,19 +699,20 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, } if (coreOnly || pDev->coreEvents) { - events->u.u.type = type; - events->u.keyButtonPointer.time = ms; - events->u.keyButtonPointer.rootX = x; - events->u.keyButtonPointer.rootY = y; + xEvent* evt = events->event; + evt->u.u.type = type; + evt->u.keyButtonPointer.time = ms; + evt->u.keyButtonPointer.rootX = x; + evt->u.keyButtonPointer.rootY = y; if (type == ButtonPress || type == ButtonRelease) { /* We hijack SetPointerMapping to work on all core-sending * devices, so we use the device-specific map here instead of * the core one. */ - events->u.u.detail = pDev->button->map[buttons]; + evt->u.u.detail = pDev->button->map[buttons]; } else { - events->u.u.detail = 0; + evt->u.u.detail = 0; } } @@ -644,11 +728,11 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, * place via GetMaximumEventsNum(), and for freeing it. */ _X_EXPORT int -GetProximityEvents(xEvent *events, DeviceIntPtr pDev, int type, +GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, int first_valuator, int num_valuators, int *valuators) { int num_events = 0; - deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer *) events; + deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer *) events->event; /* Sanity checks. */ if (type != ProximityIn && type != ProximityOut) diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index 59ce8da86..0a2f28e84 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -38,6 +38,7 @@ #include "xf86Privstr.h" #include "propertyst.h" +#include "input.h" /* * Parameters set ONLY from the command line options @@ -202,7 +203,7 @@ void xf86UnlockServer(void); void xf86InitXkb(void); /* xf86Xinput.c */ -extern xEvent *xf86Events; +extern EventList *xf86Events; #endif /* _NO_XF86_PROTOTYPES */ diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 6bf18f148..1cce1368a 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -103,7 +103,7 @@ #include "dgaproc.h" #endif -xEvent *xf86Events = NULL; +EventListPtr xf86Events = NULL; static Bool xf86SendDragEvents(DeviceIntPtr device) @@ -544,7 +544,7 @@ xf86PostMotionEvent(DeviceIntPtr device, #endif if (!xf86Events) - xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + xf86Events = InitEventList(GetMaximumEventsNum()); if (!xf86Events) FatalError("Couldn't allocate event store\n"); @@ -553,11 +553,11 @@ xf86PostMotionEvent(DeviceIntPtr device, valuators); for (i = 0; i < nevents; i++) { - xE = xf86Events + i; + xE = (xf86Events + i)->event; /* Don't post core motion events for devices not registered to send * drag events. */ if (xE->u.u.type != MotionNotify || drag) { - mieqEnqueue(device, xf86Events + i); + mieqEnqueue(device, (xf86Events + i)->event); } } @@ -583,7 +583,7 @@ xf86PostProximityEvent(DeviceIntPtr device, va_end(var); if (!xf86Events) - xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + xf86Events = InitEventList(GetMaximumEventsNum()); if (!xf86Events) FatalError("Couldn't allocate event store\n"); @@ -591,7 +591,7 @@ xf86PostProximityEvent(DeviceIntPtr device, is_in ? ProximityIn : ProximityOut, first_valuator, num_valuators, valuators); for (i = 0; i < nevents; i++) - mieqEnqueue(device, xf86Events + i); + mieqEnqueue(device, (xf86Events + i)->event); xfree(valuators); } @@ -625,7 +625,7 @@ xf86PostButtonEvent(DeviceIntPtr device, va_end(var); if (!xf86Events) - xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + xf86Events = InitEventList(GetMaximumEventsNum()); if (!xf86Events) FatalError("Couldn't allocate event store\n"); @@ -635,7 +635,7 @@ xf86PostButtonEvent(DeviceIntPtr device, first_valuator, num_valuators, valuators); for (i = 0; i < nevents; i++) - mieqEnqueue(device, xf86Events + i); + mieqEnqueue(device, (xf86Events + i)->event); xfree(valuators); } @@ -658,7 +658,7 @@ xf86PostKeyEvent(DeviceIntPtr device, "broken.\n"); if (!xf86Events) - xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + xf86Events = InitEventList(GetMaximumEventsNum()); if (!xf86Events) FatalError("Couldn't allocate event store\n"); @@ -682,7 +682,7 @@ xf86PostKeyEvent(DeviceIntPtr device, } for (i = 0; i < nevents; i++) - mieqEnqueue(device, xf86Events + i); + mieqEnqueue(device, (xf86Events + i)->event); } _X_EXPORT void @@ -702,7 +702,7 @@ xf86PostKeyboardEvent(DeviceIntPtr device, #endif if (!xf86Events) - xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + xf86Events = InitEventList(GetMaximumEventsNum()); if (!xf86Events) FatalError("Couldn't allocate event store\n"); @@ -710,7 +710,7 @@ xf86PostKeyboardEvent(DeviceIntPtr device, is_down ? KeyPress : KeyRelease, key_code); for (i = 0; i < nevents; i++) - mieqEnqueue(device, xf86Events + i); + mieqEnqueue(device, (xf86Events + i)->event); } _X_EXPORT LocalDevicePtr diff --git a/include/dix.h b/include/dix.h index 93472e832..1828f43f6 100644 --- a/include/dix.h +++ b/include/dix.h @@ -691,4 +691,8 @@ extern Bool DevHasCursor(DeviceIntPtr pDev); extern Bool IsPointerDevice( DeviceIntPtr dev); extern Bool IsKeyboardDevice(DeviceIntPtr dev); + +/* GE stuff */ +void SetGenericFilter(int extension, Mask* filters); + #endif /* DIX_H */ diff --git a/include/input.h b/include/input.h index 401fcece8..6443a58f6 100644 --- a/include/input.h +++ b/include/input.h @@ -85,6 +85,15 @@ typedef struct _OtherClients *OtherClientsPtr; typedef struct _InputClients *InputClientsPtr; typedef struct _DeviceIntRec *DeviceIntPtr; +typedef struct _EventList { + xEvent* event; + int evlen; /* length of allocated memory for event in bytes. This is not + the actual length of the event. The event's actual length is + 32 for standard events or 32 + + ((xGenericEvent*)event)->length * 4 for GenericEvents */ +} EventList, *EventListPtr; + + typedef int (*DeviceProc)( DeviceIntPtr /*device*/, int /*what*/); @@ -390,8 +399,11 @@ extern void InitInput( extern int GetMaximumEventsNum(void); +extern EventListPtr InitEventList(int num_events); +extern void FreeEventList(EventListPtr list, int num_events); + extern int GetPointerEvents( - xEvent *events, + EventListPtr events, DeviceIntPtr pDev, int type, int buttons, @@ -401,13 +413,13 @@ extern int GetPointerEvents( int *valuators); extern int GetKeyboardEvents( - xEvent *events, + EventListPtr events, DeviceIntPtr pDev, int type, int key_code); extern int GetKeyboardValuatorEvents( - xEvent *events, + EventListPtr events, DeviceIntPtr pDev, int type, int key_code, @@ -416,7 +428,7 @@ extern int GetKeyboardValuatorEvents( int *valuators); extern int GetProximityEvents( - xEvent *events, + EventListPtr events, DeviceIntPtr pDev, int type, int first_valuator, diff --git a/mi/mieq.c b/mi/mieq.c index 2eeb21eea..06fdffc93 100644 --- a/mi/mieq.c +++ b/mi/mieq.c @@ -56,6 +56,7 @@ in this Software without prior written authorization from The Open Group. # include "scrnintstr.h" # include # include +# include # include "extinit.h" # include "exglobals.h" @@ -71,7 +72,7 @@ in this Software without prior written authorization from The Open Group. #define DequeueScreen(dev) dev->spriteInfo->sprite->pDequeueScreen typedef struct _Event { - xEvent event[7]; + EventListPtr events; int nevents; ScreenPtr pScreen; DeviceIntPtr pDev; /* device this event _originated_ from */ @@ -97,6 +98,13 @@ mieqInit(void) miEventQueue.lastMotion = FALSE; for (i = 0; i < 128; i++) miEventQueue.handlers[i] = NULL; + for (i = 0; i < QUEUE_SIZE; i++) + { + EventListPtr evlist = InitEventList(7); /* 1 + MAX_VALUATOR_EVENTS */ + if (!evlist) + FatalError("Could not allocate event queue.\n"); + miEventQueue.events[i].events = evlist; + } SetInputCheck(&miEventQueue.head, &miEventQueue.tail); return TRUE; } @@ -112,23 +120,26 @@ void mieqEnqueue(DeviceIntPtr pDev, xEvent *e) { HWEventQueueType oldtail = miEventQueue.tail, newtail; + EventListPtr evt; int isMotion = 0; - deviceValuator *v = (deviceValuator *) e; - EventPtr laste = &miEventQueue.events[oldtail - 1]; - deviceKeyButtonPointer *lastkbp = (deviceKeyButtonPointer *) - &laste->event[0]; + int evlen; /* avoid merging events from different devices */ if (e->u.u.type == MotionNotify) isMotion = pDev->id; - else if (e->u.u.type == MotionNotify) - isMotion = inputInfo.pointer->id; else if (e->u.u.type == DeviceMotionNotify) isMotion = pDev->id | (1 << 8); /* flag to indicate DeviceMotion */ /* We silently steal valuator events: just tack them on to the last * motion event they need to be attached to. Sigh. */ if (e->u.u.type == DeviceValuator) { + deviceValuator *v = (deviceValuator *) e; + EventPtr laste; + deviceKeyButtonPointer *lastkbp; + + laste = &miEventQueue.events[(oldtail ? oldtail : QUEUE_SIZE)- 1]; + lastkbp = (deviceKeyButtonPointer *) laste->events->event; + if (laste->nevents > 6) { ErrorF("mieqEnqueue: more than six valuator events; dropping.\n"); return; @@ -142,7 +153,8 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e) ErrorF("mieqEnequeue: out-of-order valuator event; dropping.\n"); return; } - memcpy(&(laste->event[laste->nevents++]), e, sizeof(xEvent)); + + memcpy((laste->events[laste->nevents++].event), e, sizeof(xEvent)); return; } @@ -166,18 +178,27 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e) miEventQueue.tail = newtail; } - memcpy(&(miEventQueue.events[oldtail].event[0]), e, sizeof(xEvent)); + evlen = sizeof(xEvent); + if (e->u.u.type == GenericEvent) + evlen += ((xGenericEvent*)e)->length * 4; + + evt = miEventQueue.events[oldtail].events; + if (evt->evlen < evlen) + { + evt->evlen = evlen; + evt->event = xrealloc(evt->event, evt->evlen); + } + + memcpy(evt->event, e, evlen); miEventQueue.events[oldtail].nevents = 1; /* Make sure that event times don't go backwards - this * is "unnecessary", but very useful. */ if (e->u.keyButtonPointer.time < miEventQueue.lastEventTime && miEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000) - miEventQueue.events[oldtail].event[0].u.keyButtonPointer.time = - miEventQueue.lastEventTime; + evt->event->u.keyButtonPointer.time = miEventQueue.lastEventTime; - miEventQueue.lastEventTime = - miEventQueue.events[oldtail].event[0].u.keyButtonPointer.time; + miEventQueue.lastEventTime = evt->event->u.keyButtonPointer.time; miEventQueue.events[oldtail].pScreen = EnqueueScreen(pDev); miEventQueue.events[oldtail].pDev = pDev; @@ -209,6 +230,7 @@ mieqProcessInputEvents(void) EventRec *e = NULL; int x = 0, y = 0; DeviceIntPtr dev = NULL; + xEvent* event; while (miEventQueue.head != miEventQueue.tail) { if (screenIsSaved == SCREEN_SAVER_ON) @@ -225,8 +247,8 @@ mieqProcessInputEvents(void) /* Assumption - screen switching can only occur on motion events. */ if (e->pScreen != DequeueScreen(e->pDev)) { DequeueScreen(e->pDev) = e->pScreen; - x = e->event[0].u.keyButtonPointer.rootX; - y = e->event[0].u.keyButtonPointer.rootY; + x = e->events[0].event->u.keyButtonPointer.rootX; + y = e->events[0].event->u.keyButtonPointer.rootY; if (miEventQueue.head == QUEUE_SIZE - 1) miEventQueue.head = 0; else @@ -241,39 +263,60 @@ mieqProcessInputEvents(void) /* If someone's registered a custom event handler, let them * steal it. */ - if (miEventQueue.handlers[e->event->u.u.type]) { - miEventQueue.handlers[e->event->u.u.type]( - DequeueScreen(e->pDev)->myNum, - e->event, dev, - e->nevents); + if (miEventQueue.handlers[e->events->event->u.u.type]) { + miEventQueue.handlers[e->events->event->u.u.type]( + DequeueScreen(e->pDev)->myNum, + e->events->event, dev, + e->nevents); return; } /* If this is a core event, make sure our keymap, et al, is * changed to suit. */ - if (e->event[0].u.u.type == KeyPress || - e->event[0].u.u.type == KeyRelease) { + if (e->events->event[0].u.u.type == KeyPress || + e->events->event[0].u.u.type == KeyRelease) { SwitchCoreKeyboard(e->pDev); dev = inputInfo.keyboard; } - else if (e->event[0].u.u.type == MotionNotify || - e->event[0].u.u.type == ButtonPress || - e->event[0].u.u.type == ButtonRelease) { + else if (e->events->event[0].u.u.type == MotionNotify || + e->events->event[0].u.u.type == ButtonPress || + e->events->event[0].u.u.type == ButtonRelease) { dev = inputInfo.pointer; } else { dev = e->pDev; } + + /* FIXME: Bad hack. The only event where we actually get multiple + * events at once is a DeviceMotionNotify followed by + * DeviceValuators. For now it's save enough to just take the + * event directly or copy the bunch of events and pass in the + * copy. Eventually the interface for the processInputProc needs + * to be changed. (whot) + */ + if (e->nevents > 1) + { + int i; + event = xcalloc(e->nevents, sizeof(xEvent)); + for (i = 0; i < e->nevents; i++) + memcpy(&event[i], e->events[i].event, sizeof(xEvent)); + } + else + event = e->events->event; + /* MPX devices send both core and Xi events. * Use dev to get the correct processing function but supply * e->pDev to pass the correct device */ - dev->public.processInputProc(e->event, e->pDev, e->nevents); + dev->public.processInputProc(event, e->pDev, e->nevents); + + if (e->nevents > 1) + xfree(event); } /* Update the sprite now. Next event may be from different device. */ - if (e->event[0].u.u.type == MotionNotify && e->pDev->coreEvents) + if (e->events->event[0].u.u.type == MotionNotify && e->pDev->coreEvents) { miPointerUpdateSprite(e->pDev); } diff --git a/mi/mipointer.c b/mi/mipointer.c index b14c2c7d3..8dc7c7f5f 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -86,7 +86,7 @@ static Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen); static void miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen); -static xEvent* events; /* for WarpPointer MotionNotifies */ +static EventList* events; /* for WarpPointer MotionNotifies */ _X_EXPORT Bool miPointerInitialize (pScreen, spriteFuncs, screenFuncs, waitForUpdate) @@ -175,7 +175,7 @@ miPointerCloseScreen (index, pScreen) pScreen->CloseScreen = pScreenPriv->CloseScreen; xfree ((pointer) pScreenPriv); - xfree ((pointer) events); + FreeEventList(events, GetMaximumEventsNum()); events = NULL; return (*pScreen->CloseScreen) (index, pScreen); } @@ -624,7 +624,7 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, unsigned long if (!events) { - events = (xEvent*)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + events = InitEventList(GetMaximumEventsNum()); if (!events) { @@ -635,6 +635,8 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, unsigned long nevents = GetPointerEvents(events, pDev, MotionNotify, 0, POINTER_ABSOLUTE, 0, 2, valuators); + OsBlockSignals(); for (i = 0; i < nevents; i++) - mieqEnqueue(pDev, &events[i]); + mieqEnqueue(pDev, events[i].event); + OsReleaseSignals(); }