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/Xproto.h>
#include <X11/extensions/XI.h> #include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h> #include <X11/extensions/XIproto.h>
#include <X11/extensions/geproto.h>
#include "inputstr.h" #include "inputstr.h"
#include "windowstr.h" #include "windowstr.h"
#include "miscstruct.h" #include "miscstruct.h"
@ -127,7 +128,7 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
ValuatorClassPtr v = device->valuator; ValuatorClassPtr v = device->valuator;
deviceValuator *xV = (deviceValuator *) xE; 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; DeviceIntPtr mouse = NULL, kbd = NULL;
GetSpritePosition(device, &rootX, &rootY); GetSpritePosition(device, &rootX, &rootY);
xE->u.keyButtonPointer.rootX = rootX; xE->u.keyButtonPointer.rootX = rootX;

View File

@ -131,6 +131,13 @@ int ExtEventIndex;
Mask ExtValidMasks[EMASKSIZE]; Mask ExtValidMasks[EMASKSIZE];
Mask ExtExclusiveMasks[EMASKSIZE]; Mask ExtExclusiveMasks[EMASKSIZE];
static Mask xi_filters[3] = {
XI_PointerKeyboardPairingChangedNotifyMask,
XI_RandomStringEventMask,
XI_RawDeviceEventMask,
};
static struct dev_type static struct dev_type
{ {
Atom type; Atom type;
@ -1158,6 +1165,9 @@ XInputExtensionInit(void)
EventSwapVector[ChangeDeviceNotify] = SEventIDispatch; EventSwapVector[ChangeDeviceNotify] = SEventIDispatch;
EventSwapVector[DeviceEnterNotify] = SEventIDispatch; EventSwapVector[DeviceEnterNotify] = SEventIDispatch;
EventSwapVector[DeviceLeaveNotify] = SEventIDispatch; EventSwapVector[DeviceLeaveNotify] = SEventIDispatch;
/* init GE events */
SetGenericFilter(IReqCode, xi_filters);
} else { } else {
FatalError("IExtensionInit: AddExtensions failed\n"); FatalError("IExtensionInit: AddExtensions failed\n");
} }

View File

@ -367,6 +367,14 @@ static Mask filters[128] =
CantBeFiltered /* MappingNotify */ 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] = static CARD8 criticalEvents[32] =
{ {
0x7c /* key and button events */ 0x7c /* key and button events */
@ -2176,6 +2184,34 @@ DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab,
} }
else else
{ {
/* 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)) if (!(filter & pWin->deliverableEvents))
return 0; return 0;
while (pWin) while (pWin)
@ -2196,6 +2232,7 @@ DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab,
pWin = pWin->parent; pWin = pWin->parent;
} }
} }
}
return 0; return 0;
} }
@ -5660,3 +5697,15 @@ IsInterferingGrab(ClientPtr client, WindowPtr win, DeviceIntPtr dev, xEvent* eve
return mayInterfere; 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 * last posted, not just x and y; otherwise relative non-x/y
* valuators, though a very narrow use case, will be broken. * valuators, though a very narrow use case, will be broken.
*/ */
static xEvent * static EventList *
getValuatorEvents(xEvent *events, DeviceIntPtr pDev, int first_valuator, getValuatorEvents(EventList *events, DeviceIntPtr pDev, int first_valuator,
int num_valuators, int *valuators) { int num_valuators, int *valuators) {
deviceValuator *xv = (deviceValuator *) events; deviceValuator *xv;
int i = 0, final_valuator = first_valuator + num_valuators; 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->type = DeviceValuator;
xv->first_valuator = i; xv->first_valuator = i;
xv->num_valuators = num_valuators; xv->num_valuators = num_valuators;
@ -353,7 +354,7 @@ getValuatorEvents(xEvent *events, DeviceIntPtr pDev, int first_valuator,
* valuators. * valuators.
*/ */
_X_EXPORT int _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); 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. * KeyPresses.
*/ */
_X_EXPORT int _X_EXPORT int
GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
int key_code, int first_valuator, int key_code, int first_valuator,
int num_valuators, int *valuators) { int num_valuators, int *valuators) {
int numEvents = 0; int numEvents = 0;
@ -448,7 +449,7 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
ms = GetTimeInMillis(); ms = GetTimeInMillis();
kbp = (deviceKeyButtonPointer *) events; kbp = (deviceKeyButtonPointer *) events->event;
kbp->time = ms; kbp->time = ms;
kbp->deviceid = pDev->id; kbp->deviceid = pDev->id;
if (type == KeyPress) if (type == KeyPress)
@ -465,31 +466,85 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
} }
if (pDev->coreEvents) { if (pDev->coreEvents) {
events->u.keyButtonPointer.time = ms; xEvent* evt = events->event;
events->u.u.type = type; evt->u.keyButtonPointer.time = ms;
events->u.u.detail = key_code; evt->u.u.type = type;
evt->u.u.detail = key_code;
} }
return numEvents; 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 * Free an event list.
* motion, or button presses. Xi and XKB-aware. *
* @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. * 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 * 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 _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 flags, int first_valuator, int num_valuators,
int *valuators) { int *valuators) {
int num_events = 0, final_valuator = 0; int num_events = 0, final_valuator = 0, i;
CARD32 ms = 0; CARD32 ms = 0;
CARD32* valptr;
deviceKeyButtonPointer *kbp = NULL; deviceKeyButtonPointer *kbp = NULL;
rawDeviceEvent* ev;
/* Thanks to a broken lib, we _always_ have to chase DeviceMotionNotifies /* Thanks to a broken lib, we _always_ have to chase DeviceMotionNotifies
* with DeviceValuators. */ * with DeviceValuators. */
Bool sendValuators = (type == MotionNotify || flags & POINTER_ABSOLUTE); Bool sendValuators = (type == MotionNotify || flags & POINTER_ABSOLUTE);
@ -506,9 +561,9 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
return 0; return 0;
if (!coreOnly && (pDev->coreEvents)) if (!coreOnly && (pDev->coreEvents))
num_events = 2; num_events = 3;
else else
num_events = 1; num_events = 2;
if (type == MotionNotify && num_valuators <= 0) { if (type == MotionNotify && num_valuators <= 0) {
return 0; return 0;
@ -529,6 +584,34 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
ms = GetTimeInMillis(); 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; pointer = pDev;
/* Set x and y based on whether this is absolute or relative, and /* 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 */ /* create Xi event */
if (!coreOnly) if (!coreOnly)
{ {
kbp = (deviceKeyButtonPointer *) events; kbp = (deviceKeyButtonPointer *) events->event;
kbp->time = ms; kbp->time = ms;
kbp->deviceid = pDev->id; kbp->deviceid = pDev->id;
@ -616,19 +699,20 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
} }
if (coreOnly || pDev->coreEvents) { if (coreOnly || pDev->coreEvents) {
events->u.u.type = type; xEvent* evt = events->event;
events->u.keyButtonPointer.time = ms; evt->u.u.type = type;
events->u.keyButtonPointer.rootX = x; evt->u.keyButtonPointer.time = ms;
events->u.keyButtonPointer.rootY = y; evt->u.keyButtonPointer.rootX = x;
evt->u.keyButtonPointer.rootY = y;
if (type == ButtonPress || type == ButtonRelease) { if (type == ButtonPress || type == ButtonRelease) {
/* We hijack SetPointerMapping to work on all core-sending /* We hijack SetPointerMapping to work on all core-sending
* devices, so we use the device-specific map here instead of * devices, so we use the device-specific map here instead of
* the core one. */ * the core one. */
events->u.u.detail = pDev->button->map[buttons]; evt->u.u.detail = pDev->button->map[buttons];
} }
else { 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. * place via GetMaximumEventsNum(), and for freeing it.
*/ */
_X_EXPORT int _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 first_valuator, int num_valuators, int *valuators)
{ {
int num_events = 0; int num_events = 0;
deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer *) events; deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer *) events->event;
/* Sanity checks. */ /* Sanity checks. */
if (type != ProximityIn && type != ProximityOut) if (type != ProximityIn && type != ProximityOut)

View File

@ -38,6 +38,7 @@
#include "xf86Privstr.h" #include "xf86Privstr.h"
#include "propertyst.h" #include "propertyst.h"
#include "input.h"
/* /*
* Parameters set ONLY from the command line options * Parameters set ONLY from the command line options
@ -202,7 +203,7 @@ void xf86UnlockServer(void);
void xf86InitXkb(void); void xf86InitXkb(void);
/* xf86Xinput.c */ /* xf86Xinput.c */
extern xEvent *xf86Events; extern EventList *xf86Events;
#endif /* _NO_XF86_PROTOTYPES */ #endif /* _NO_XF86_PROTOTYPES */

View File

@ -103,7 +103,7 @@
#include "dgaproc.h" #include "dgaproc.h"
#endif #endif
xEvent *xf86Events = NULL; EventListPtr xf86Events = NULL;
static Bool static Bool
xf86SendDragEvents(DeviceIntPtr device) xf86SendDragEvents(DeviceIntPtr device)
@ -544,7 +544,7 @@ xf86PostMotionEvent(DeviceIntPtr device,
#endif #endif
if (!xf86Events) if (!xf86Events)
xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); xf86Events = InitEventList(GetMaximumEventsNum());
if (!xf86Events) if (!xf86Events)
FatalError("Couldn't allocate event store\n"); FatalError("Couldn't allocate event store\n");
@ -553,11 +553,11 @@ xf86PostMotionEvent(DeviceIntPtr device,
valuators); valuators);
for (i = 0; i < nevents; i++) { 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 /* Don't post core motion events for devices not registered to send
* drag events. */ * drag events. */
if (xE->u.u.type != MotionNotify || drag) { 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); va_end(var);
if (!xf86Events) if (!xf86Events)
xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); xf86Events = InitEventList(GetMaximumEventsNum());
if (!xf86Events) if (!xf86Events)
FatalError("Couldn't allocate event store\n"); FatalError("Couldn't allocate event store\n");
@ -591,7 +591,7 @@ xf86PostProximityEvent(DeviceIntPtr device,
is_in ? ProximityIn : ProximityOut, is_in ? ProximityIn : ProximityOut,
first_valuator, num_valuators, valuators); first_valuator, num_valuators, valuators);
for (i = 0; i < nevents; i++) for (i = 0; i < nevents; i++)
mieqEnqueue(device, xf86Events + i); mieqEnqueue(device, (xf86Events + i)->event);
xfree(valuators); xfree(valuators);
} }
@ -625,7 +625,7 @@ xf86PostButtonEvent(DeviceIntPtr device,
va_end(var); va_end(var);
if (!xf86Events) if (!xf86Events)
xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); xf86Events = InitEventList(GetMaximumEventsNum());
if (!xf86Events) if (!xf86Events)
FatalError("Couldn't allocate event store\n"); FatalError("Couldn't allocate event store\n");
@ -635,7 +635,7 @@ xf86PostButtonEvent(DeviceIntPtr device,
first_valuator, num_valuators, valuators); first_valuator, num_valuators, valuators);
for (i = 0; i < nevents; i++) for (i = 0; i < nevents; i++)
mieqEnqueue(device, xf86Events + i); mieqEnqueue(device, (xf86Events + i)->event);
xfree(valuators); xfree(valuators);
} }
@ -658,7 +658,7 @@ xf86PostKeyEvent(DeviceIntPtr device,
"broken.\n"); "broken.\n");
if (!xf86Events) if (!xf86Events)
xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); xf86Events = InitEventList(GetMaximumEventsNum());
if (!xf86Events) if (!xf86Events)
FatalError("Couldn't allocate event store\n"); FatalError("Couldn't allocate event store\n");
@ -682,7 +682,7 @@ xf86PostKeyEvent(DeviceIntPtr device,
} }
for (i = 0; i < nevents; i++) for (i = 0; i < nevents; i++)
mieqEnqueue(device, xf86Events + i); mieqEnqueue(device, (xf86Events + i)->event);
} }
_X_EXPORT void _X_EXPORT void
@ -702,7 +702,7 @@ xf86PostKeyboardEvent(DeviceIntPtr device,
#endif #endif
if (!xf86Events) if (!xf86Events)
xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); xf86Events = InitEventList(GetMaximumEventsNum());
if (!xf86Events) if (!xf86Events)
FatalError("Couldn't allocate event store\n"); FatalError("Couldn't allocate event store\n");
@ -710,7 +710,7 @@ xf86PostKeyboardEvent(DeviceIntPtr device,
is_down ? KeyPress : KeyRelease, key_code); is_down ? KeyPress : KeyRelease, key_code);
for (i = 0; i < nevents; i++) for (i = 0; i < nevents; i++)
mieqEnqueue(device, xf86Events + i); mieqEnqueue(device, (xf86Events + i)->event);
} }
_X_EXPORT LocalDevicePtr _X_EXPORT LocalDevicePtr

View File

@ -691,4 +691,8 @@ extern Bool DevHasCursor(DeviceIntPtr pDev);
extern Bool IsPointerDevice( DeviceIntPtr dev); extern Bool IsPointerDevice( DeviceIntPtr dev);
extern Bool IsKeyboardDevice(DeviceIntPtr dev); extern Bool IsKeyboardDevice(DeviceIntPtr dev);
/* GE stuff */
void SetGenericFilter(int extension, Mask* filters);
#endif /* DIX_H */ #endif /* DIX_H */

View File

@ -85,6 +85,15 @@ typedef struct _OtherClients *OtherClientsPtr;
typedef struct _InputClients *InputClientsPtr; typedef struct _InputClients *InputClientsPtr;
typedef struct _DeviceIntRec *DeviceIntPtr; 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)( typedef int (*DeviceProc)(
DeviceIntPtr /*device*/, DeviceIntPtr /*device*/,
int /*what*/); int /*what*/);
@ -390,8 +399,11 @@ extern void InitInput(
extern int GetMaximumEventsNum(void); extern int GetMaximumEventsNum(void);
extern EventListPtr InitEventList(int num_events);
extern void FreeEventList(EventListPtr list, int num_events);
extern int GetPointerEvents( extern int GetPointerEvents(
xEvent *events, EventListPtr events,
DeviceIntPtr pDev, DeviceIntPtr pDev,
int type, int type,
int buttons, int buttons,
@ -401,13 +413,13 @@ extern int GetPointerEvents(
int *valuators); int *valuators);
extern int GetKeyboardEvents( extern int GetKeyboardEvents(
xEvent *events, EventListPtr events,
DeviceIntPtr pDev, DeviceIntPtr pDev,
int type, int type,
int key_code); int key_code);
extern int GetKeyboardValuatorEvents( extern int GetKeyboardValuatorEvents(
xEvent *events, EventListPtr events,
DeviceIntPtr pDev, DeviceIntPtr pDev,
int type, int type,
int key_code, int key_code,
@ -416,7 +428,7 @@ extern int GetKeyboardValuatorEvents(
int *valuators); int *valuators);
extern int GetProximityEvents( extern int GetProximityEvents(
xEvent *events, EventListPtr events,
DeviceIntPtr pDev, DeviceIntPtr pDev,
int type, int type,
int first_valuator, int first_valuator,

View File

@ -56,6 +56,7 @@ in this Software without prior written authorization from The Open Group.
# include "scrnintstr.h" # include "scrnintstr.h"
# include <X11/extensions/XI.h> # include <X11/extensions/XI.h>
# include <X11/extensions/XIproto.h> # include <X11/extensions/XIproto.h>
# include <X11/extensions/geproto.h>
# include "extinit.h" # include "extinit.h"
# include "exglobals.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 #define DequeueScreen(dev) dev->spriteInfo->sprite->pDequeueScreen
typedef struct _Event { typedef struct _Event {
xEvent event[7]; EventListPtr events;
int nevents; int nevents;
ScreenPtr pScreen; ScreenPtr pScreen;
DeviceIntPtr pDev; /* device this event _originated_ from */ DeviceIntPtr pDev; /* device this event _originated_ from */
@ -97,6 +98,13 @@ mieqInit(void)
miEventQueue.lastMotion = FALSE; miEventQueue.lastMotion = FALSE;
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++)
miEventQueue.handlers[i] = NULL; 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); SetInputCheck(&miEventQueue.head, &miEventQueue.tail);
return TRUE; return TRUE;
} }
@ -112,23 +120,26 @@ void
mieqEnqueue(DeviceIntPtr pDev, xEvent *e) mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
{ {
HWEventQueueType oldtail = miEventQueue.tail, newtail; HWEventQueueType oldtail = miEventQueue.tail, newtail;
EventListPtr evt;
int isMotion = 0; int isMotion = 0;
deviceValuator *v = (deviceValuator *) e; int evlen;
EventPtr laste = &miEventQueue.events[oldtail - 1];
deviceKeyButtonPointer *lastkbp = (deviceKeyButtonPointer *)
&laste->event[0];
/* avoid merging events from different devices */ /* avoid merging events from different devices */
if (e->u.u.type == MotionNotify) if (e->u.u.type == MotionNotify)
isMotion = pDev->id; isMotion = pDev->id;
else if (e->u.u.type == MotionNotify)
isMotion = inputInfo.pointer->id;
else if (e->u.u.type == DeviceMotionNotify) else if (e->u.u.type == DeviceMotionNotify)
isMotion = pDev->id | (1 << 8); /* flag to indicate DeviceMotion */ isMotion = pDev->id | (1 << 8); /* flag to indicate DeviceMotion */
/* We silently steal valuator events: just tack them on to the last /* We silently steal valuator events: just tack them on to the last
* motion event they need to be attached to. Sigh. */ * motion event they need to be attached to. Sigh. */
if (e->u.u.type == DeviceValuator) { 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) { if (laste->nevents > 6) {
ErrorF("mieqEnqueue: more than six valuator events; dropping.\n"); ErrorF("mieqEnqueue: more than six valuator events; dropping.\n");
return; return;
@ -142,7 +153,8 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
ErrorF("mieqEnequeue: out-of-order valuator event; dropping.\n"); ErrorF("mieqEnequeue: out-of-order valuator event; dropping.\n");
return; return;
} }
memcpy(&(laste->event[laste->nevents++]), e, sizeof(xEvent));
memcpy((laste->events[laste->nevents++].event), e, sizeof(xEvent));
return; return;
} }
@ -166,18 +178,27 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
miEventQueue.tail = newtail; 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; miEventQueue.events[oldtail].nevents = 1;
/* Make sure that event times don't go backwards - this /* Make sure that event times don't go backwards - this
* is "unnecessary", but very useful. */ * is "unnecessary", but very useful. */
if (e->u.keyButtonPointer.time < miEventQueue.lastEventTime && if (e->u.keyButtonPointer.time < miEventQueue.lastEventTime &&
miEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000) miEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000)
miEventQueue.events[oldtail].event[0].u.keyButtonPointer.time = evt->event->u.keyButtonPointer.time = miEventQueue.lastEventTime;
miEventQueue.lastEventTime;
miEventQueue.lastEventTime = miEventQueue.lastEventTime = evt->event->u.keyButtonPointer.time;
miEventQueue.events[oldtail].event[0].u.keyButtonPointer.time;
miEventQueue.events[oldtail].pScreen = EnqueueScreen(pDev); miEventQueue.events[oldtail].pScreen = EnqueueScreen(pDev);
miEventQueue.events[oldtail].pDev = pDev; miEventQueue.events[oldtail].pDev = pDev;
@ -209,6 +230,7 @@ mieqProcessInputEvents(void)
EventRec *e = NULL; EventRec *e = NULL;
int x = 0, y = 0; int x = 0, y = 0;
DeviceIntPtr dev = NULL; DeviceIntPtr dev = NULL;
xEvent* event;
while (miEventQueue.head != miEventQueue.tail) { while (miEventQueue.head != miEventQueue.tail) {
if (screenIsSaved == SCREEN_SAVER_ON) if (screenIsSaved == SCREEN_SAVER_ON)
@ -225,8 +247,8 @@ mieqProcessInputEvents(void)
/* Assumption - screen switching can only occur on motion events. */ /* Assumption - screen switching can only occur on motion events. */
if (e->pScreen != DequeueScreen(e->pDev)) { if (e->pScreen != DequeueScreen(e->pDev)) {
DequeueScreen(e->pDev) = e->pScreen; DequeueScreen(e->pDev) = e->pScreen;
x = e->event[0].u.keyButtonPointer.rootX; x = e->events[0].event->u.keyButtonPointer.rootX;
y = e->event[0].u.keyButtonPointer.rootY; y = e->events[0].event->u.keyButtonPointer.rootY;
if (miEventQueue.head == QUEUE_SIZE - 1) if (miEventQueue.head == QUEUE_SIZE - 1)
miEventQueue.head = 0; miEventQueue.head = 0;
else else
@ -241,39 +263,60 @@ mieqProcessInputEvents(void)
/* If someone's registered a custom event handler, let them /* If someone's registered a custom event handler, let them
* steal it. */ * steal it. */
if (miEventQueue.handlers[e->event->u.u.type]) { if (miEventQueue.handlers[e->events->event->u.u.type]) {
miEventQueue.handlers[e->event->u.u.type]( miEventQueue.handlers[e->events->event->u.u.type](
DequeueScreen(e->pDev)->myNum, DequeueScreen(e->pDev)->myNum,
e->event, dev, e->events->event, dev,
e->nevents); e->nevents);
return; return;
} }
/* If this is a core event, make sure our keymap, et al, is /* If this is a core event, make sure our keymap, et al, is
* changed to suit. */ * changed to suit. */
if (e->event[0].u.u.type == KeyPress || if (e->events->event[0].u.u.type == KeyPress ||
e->event[0].u.u.type == KeyRelease) { e->events->event[0].u.u.type == KeyRelease) {
SwitchCoreKeyboard(e->pDev); SwitchCoreKeyboard(e->pDev);
dev = inputInfo.keyboard; dev = inputInfo.keyboard;
} }
else if (e->event[0].u.u.type == MotionNotify || else if (e->events->event[0].u.u.type == MotionNotify ||
e->event[0].u.u.type == ButtonPress || e->events->event[0].u.u.type == ButtonPress ||
e->event[0].u.u.type == ButtonRelease) { e->events->event[0].u.u.type == ButtonRelease) {
dev = inputInfo.pointer; dev = inputInfo.pointer;
} }
else { else {
dev = e->pDev; 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. /* MPX devices send both core and Xi events.
* Use dev to get the correct processing function but supply * Use dev to get the correct processing function but supply
* e->pDev to pass the correct device * 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. */ /* 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); miPointerUpdateSprite(e->pDev);
} }

View File

@ -86,7 +86,7 @@ static Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen);
static void miPointerDeviceCleanup(DeviceIntPtr pDev, static void miPointerDeviceCleanup(DeviceIntPtr pDev,
ScreenPtr pScreen); ScreenPtr pScreen);
static xEvent* events; /* for WarpPointer MotionNotifies */ static EventList* events; /* for WarpPointer MotionNotifies */
_X_EXPORT Bool _X_EXPORT Bool
miPointerInitialize (pScreen, spriteFuncs, screenFuncs, waitForUpdate) miPointerInitialize (pScreen, spriteFuncs, screenFuncs, waitForUpdate)
@ -175,7 +175,7 @@ miPointerCloseScreen (index, pScreen)
pScreen->CloseScreen = pScreenPriv->CloseScreen; pScreen->CloseScreen = pScreenPriv->CloseScreen;
xfree ((pointer) pScreenPriv); xfree ((pointer) pScreenPriv);
xfree ((pointer) events); FreeEventList(events, GetMaximumEventsNum());
events = NULL; events = NULL;
return (*pScreen->CloseScreen) (index, pScreen); return (*pScreen->CloseScreen) (index, pScreen);
} }
@ -624,7 +624,7 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, unsigned long
if (!events) if (!events)
{ {
events = (xEvent*)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); events = InitEventList(GetMaximumEventsNum());
if (!events) 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); nevents = GetPointerEvents(events, pDev, MotionNotify, 0, POINTER_ABSOLUTE, 0, 2, valuators);
OsBlockSignals();
for (i = 0; i < nevents; i++) for (i = 0; i < nevents; i++)
mieqEnqueue(pDev, &events[i]); mieqEnqueue(pDev, events[i].event);
OsReleaseSignals();
} }