Adjust EQ to support long events.

Add RawDeviceEvent (pointers only for now).

This commit changes the event queue to use EventLists instead of xEvent
arrays. Only EQ is affected, event delivery still uses xEvent* (look for
comment in mieqProcessInputEvent).

RawDeviceEvents deliver driver information to the client, without clipping or
acceleration.
This commit is contained in:
Peter Hutterer 2007-05-02 13:50:09 +09:30
parent 0214d0b96a
commit 58c0fd2927
10 changed files with 299 additions and 93 deletions

View File

@ -61,6 +61,7 @@ SOFTWARE.
#include <X11/Xproto.h>
#include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h>
#include <X11/extensions/geproto.h>
#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;

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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,

View File

@ -56,6 +56,7 @@ in this Software without prior written authorization from The Open Group.
# include "scrnintstr.h"
# include <X11/extensions/XI.h>
# include <X11/extensions/XIproto.h>
# include <X11/extensions/geproto.h>
# 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);
}

View File

@ -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();
}