Xi: support InternalEvents in UpdateDeviceState, parts of POE and EnqueueEvent

Note that this breaks DGA. Life is tough.

EnqueueEvent is a somewhat half-baked solution, we immediately drop back into
XI and store them. But it should in theory work.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

Don't let the dcce be random data.
This commit is contained in:
Peter Hutterer 2009-01-30 13:33:55 +10:00
parent 007e93c869
commit 8829d966a6
8 changed files with 105 additions and 127 deletions

View File

@ -668,9 +668,10 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
*/
static void
ChangeMasterDeviceClasses(DeviceIntPtr device,
deviceClassesChangedEvent *dcce)
DeviceChangedEvent *dce)
{
DeviceIntPtr master = device->u.master;
deviceClassesChangedEvent *dcce;
char* classbuff;
int len = sizeof(xEvent);
int namelen = 0; /* dummy */
@ -681,19 +682,29 @@ ChangeMasterDeviceClasses(DeviceIntPtr device,
if (!master) /* if device was set floating between SIGIO and now */
return;
SizeDeviceInfo(device, &namelen, &len);
dcce = xalloc(len);
if (!dcce)
{
ErrorF("[Xi] BadAlloc in ChangeMasterDeviceClasses\n");
return;
}
dcce->type = GenericEvent;
dcce->extension = IReqCode;
dcce->evtype = XI_DeviceClassesChangedNotify;
dcce->time = GetTimeInMillis();
dcce->new_slave = device->id;
dcce->deviceid = master->id;
dcce->num_classes = 0;
SizeDeviceInfo(device, &namelen, &len);
dcce->length = (len - sizeof(xEvent))/4;
master->public.devicePrivate = device->public.devicePrivate;
DeepCopyDeviceClasses(device, master);
/* event is already correct size, see SetMinimumEventSize */
classbuff = (char*)&dcce[1];
/* we don't actually swap if there's a NullClient, swapping is done
* later when event is delivered. */
CopySwapClasses(NullClient, master, &dcce->num_classes, &classbuff);
@ -711,105 +722,78 @@ ChangeMasterDeviceClasses(DeviceIntPtr device,
#define DEFAULT 0
#define DONT_PROCESS 1
int
UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
{
int i;
int key = 0,
bit = 0;
bit = 0,
last_valuator;
KeyClassPtr k = NULL;
ButtonClassPtr b = NULL;
ValuatorClassPtr v = NULL;
deviceValuator *xV = (deviceValuator *) xE;
BYTE *kptr = NULL;
/* This event is always the first we get, before the actual events with
* the data. However, the way how the DDX is set up, "device" will
* actually be the slave device that caused the event.
*/
if (GEIsType(xE, IReqCode, XI_DeviceClassesChangedNotify))
switch(event->type)
{
ChangeMasterDeviceClasses(device, (deviceClassesChangedEvent*)xE);
return DONT_PROCESS; /* event has been sent already */
case ET_DeviceChanged:
ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event);
return DONT_PROCESS; /* event has been sent already */
case ET_ButtonPress:
case ET_ButtonRelease:
case ET_KeyPress:
case ET_KeyRelease:
case ET_ProximityIn:
case ET_ProximityOut:
break;
default:
/* other events don't update the device */
return DEFAULT;
}
/* currently no other generic event modifies the device */
if (xE->u.u.type == GenericEvent)
return DEFAULT;
k = device->key;
v = device->valuator;
b = device->button;
if (xE->u.u.type != DeviceValuator)
{
key = xE->u.u.detail;
bit = 1 << (key & 7);
}
key = event->detail.key;
bit = 1 << (key & 7);
/* Update device axis */
for (i = 1; i < count; i++) {
if ((++xV)->type == DeviceValuator) {
int *axisvals;
int first = xV->first_valuator;
BOOL change = FALSE;
if (xV->num_valuators && !v)
FatalError("Valuators reported for non-valuator device '%s'\n",
device->name);
if (first + xV->num_valuators > v->numAxes)
FatalError("Too many valuators reported for device '%s'\n",
device->name);
if (v && v->axisVal) {
/* v->axisVal is always in absolute coordinates. Only the
* delivery mode changes.
* If device is mode Absolute
* dev = event
* If device is mode Relative
* swap = (event - device)
* dev = event
* event = delta
*/
int delta;
axisvals = v->axisVal;
if (v->mode == Relative) /* device reports relative */
change = TRUE;
switch (xV->num_valuators) {
case 6:
if (change) delta = xV->valuator5 - *(axisvals + first + 5);
*(axisvals + first + 5) = xV->valuator5;
if (change) xV->valuator5 = delta;
case 5:
if (change) delta = xV->valuator4 - *(axisvals + first + 4);
*(axisvals + first + 4) = xV->valuator4;
if (change) xV->valuator4 = delta;
case 4:
if (change) delta = xV->valuator3 - *(axisvals + first + 3);
*(axisvals + first + 3) = xV->valuator3;
if (change) xV->valuator3 = delta;
case 3:
if (change) delta = xV->valuator2 - *(axisvals + first + 2);
*(axisvals + first + 2) = xV->valuator2;
if (change) xV->valuator2 = delta;
case 2:
if (change) delta = xV->valuator1 - *(axisvals + first + 1);
*(axisvals + first + 1) = xV->valuator1;
if (change) xV->valuator1 = delta;
case 1:
if (change) delta = xV->valuator0 - *(axisvals + first);
*(axisvals + first) = xV->valuator0;
if (change) xV->valuator0 = delta;
case 0:
default:
break;
}
}
}
/* Check valuators first */
last_valuator = 0;
for (i = 0; i < MAX_VALUATORS; i++)
{
if (BitIsOn(&event->valuators.mask, i))
{
if (!v)
{
ErrorF("[Xi] Valuators reported for non-valuator device '%s'. "
"Ignoring event.\n", device->name);
return DONT_PROCESS;
} else if (v->numAxes < i)
{
ErrorF("[Xi] Too many valuators reported for device '%s'. "
"Ignoring event.\n", device->name);
return DONT_PROCESS;
}
last_valuator = i;
}
}
if (xE->u.u.type == DeviceKeyPress) {
for (i = 0; i < last_valuator && i < v->numAxes; i++)
{
if (BitIsOn(&event->valuators.mask, i))
{
/* XXX: Relative/Absolute mode */
v->axisVal[i] = event->valuators.data[i];
}
}
if (event->type == ET_KeyPress) {
if (!k)
return DONT_PROCESS;
@ -819,7 +803,7 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
*kptr |= bit;
} else if (xE->u.u.type == DeviceKeyRelease) {
} else if (event->type == ET_KeyRelease) {
if (!k)
return DONT_PROCESS;
@ -829,7 +813,7 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
*kptr &= ~bit;
} else if (xE->u.u.type == DeviceButtonPress) {
} else if (event->type == ET_ButtonPress) {
Mask mask;
if (!b)
return DONT_PROCESS;
@ -852,9 +836,8 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
SetMaskForEvent(device->id, mask, DeviceMotionNotify);
mask = PointerMotionMask | b->state | b->motionMask;
SetMaskForEvent(device->id, mask, MotionNotify);
} else if (xE->u.u.type == DeviceButtonRelease) {
} else if (event->type == ET_ButtonRelease) {
Mask mask;
if (!b)
return DONT_PROCESS;
@ -891,9 +874,9 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
SetMaskForEvent(device->id, mask, DeviceMotionNotify);
mask = PointerMotionMask | b->state | b->motionMask;
SetMaskForEvent(device->id, mask, MotionNotify);
} else if (xE->u.u.type == ProximityIn)
} else if (event->type == ET_ProximityIn)
device->valuator->mode &= ~OutOfProximity;
else if (xE->u.u.type == ProximityOut)
else if (event->type == ET_ProximityOut)
device->valuator->mode |= OutOfProximity;
return DEFAULT;
@ -905,7 +888,7 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
*
*/
void
ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
{
int i;
GrabPtr grab = device->deviceGrab.grab;
@ -914,10 +897,16 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
ButtonClassPtr b;
KeyClassPtr k;
ValuatorClassPtr v;
deviceValuator *xV = (deviceValuator *) xE;
deviceValuator *xV;
int ret = 0;
int state;
DeviceIntPtr mouse = NULL, kbd = NULL;
DeviceEvent *event = (DeviceEvent*)ev;
/* FIXME: temporary solution only. */
static int nevents;
static xEvent xE[1000]; /* enough bytes for the events we have atm */
if (IsPointerDevice(device))
{
@ -937,10 +926,12 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
state = (kbd) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0;
state |= (mouse) ? (mouse->button->state) : 0;
ret = UpdateDeviceState(device, xE, count);
ret = UpdateDeviceState(device, event);
if (ret == DONT_PROCESS)
return;
nevents = ConvertBackToXI((InternalEvent*)ev, xE);
v = device->valuator;
b = device->button;
k = device->key;
@ -967,6 +958,7 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
}
/* Valuator event handling */
xV = (deviceValuator*)xE;
for (i = 1; i < count; i++) {
if ((++xV)->type == DeviceValuator)
xV->device_state = state;

View File

@ -322,11 +322,9 @@ GetXIType(InternalEvent *event)
}
/*
* FIXME: A temporary solution to make the server bisectable. This code
* allocates during SIGIO and makes a number of assumptions about what's in
* events. Will be removed soon.
* FIXME: A temporary solution to make the server bisectable. Take the event
* @event and copy it into @ev, returning the number of events in @ev.
*/
int
ConvertBackToXI(InternalEvent *event, xEvent *ev)
{

View File

@ -1009,16 +1009,24 @@ NoticeEventTime(xEvent *xE)
* linked list for later delivery.
*/
void
EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
EnqueueEvent(xEvent *ev, DeviceIntPtr device, int count)
{
QdEventPtr tail = *syncEvents.pendtail;
QdEventPtr qe;
SpritePtr pSprite = device->spriteInfo->sprite;
int eventlen;
DeviceEvent *event = (DeviceEvent*)ev;
/* FIXME: temporary solution only. */
static int nevents;
static xEvent xi[1000]; /* enough bytes for the events we have atm */
xEvent *xE = xi;
nevents = ConvertBackToXI((InternalEvent*)ev, xE);
NoticeTime(xE);
/* Fix for key repeating bug. */
if (device->key != NULL && device->key->xkbInfo != NULL &&
xE->u.u.type == KeyRelease)
@ -1040,7 +1048,7 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
XE_KBPTR.root =
WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id;
eventinfo.events = xE;
eventinfo.count = count;
eventinfo.count = nevents;
CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
}
if (xE->u.u.type == DeviceMotionNotify)
@ -1069,7 +1077,7 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
}
}
eventlen = count * sizeof(xEvent);
eventlen = nevents * sizeof(xEvent);
if (xE->u.u.type == GenericEvent) /* count is 1 for GenericEvents */
eventlen += ((xGenericEvent*)xE)->length * 4;
@ -1081,14 +1089,14 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
qe->pScreen = pSprite->hotPhys.pScreen;
qe->months = currentTime.months;
qe->event = (xEvent *)(qe + 1);
qe->evcount = count;
qe->evcount = nevents;
if (xE->u.u.type == GenericEvent)
{
memcpy(qe->event, xE, eventlen);
} else
{
xEvent *qxE;
for (qxE = qe->event; --count >= 0; qxE++, xE++)
for (qxE = qe->event; --nevents >= 0; qxE++, xE++)
{
*qxE = *xE;
}

View File

@ -1047,7 +1047,10 @@ DGAProcessKeyboardEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr keybd)
de->u.event.state |= pointer->button->state;
de->u.u.type = (IEventBase - 1) + coreEquiv; /* change to XI event */
#if 0
/* FIXME: Hello. I am broken. Please fix me. Thanks. */
UpdateDeviceState(keybd, (xEvent*)de, 1);
#endif
de->u.u.type = *XDGAEventBase + coreEquiv; /* change back */
/*
@ -1095,7 +1098,10 @@ DGAProcessPointerEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr mouse)
de->u.event.state |= XkbStateFieldFromRec(&GetPairedDevice(mouse)->key->xkbInfo->state);
de->u.u.type = (IEventBase - 1) + coreEquiv; /* change to XI event */
#if 0
/* FIXME: Hello. I am broken. Please fix me. Thanks. */
UpdateDeviceState(mouse, (xEvent*)de, 1);
#endif
de->u.u.type = *XDGAEventBase + coreEquiv; /* change back */
/*

View File

@ -48,8 +48,7 @@ extern _X_EXPORT void RegisterOtherDevice (
extern _X_EXPORT int
UpdateDeviceState (
DeviceIntPtr /* device */,
xEventPtr /* xE */,
int /* count */);
DeviceEvent* /* xE */);
extern _X_EXPORT void ProcessOtherEvent (
xEventPtr /* FIXME deviceKeyButtonPointer * xE */,

View File

@ -722,19 +722,10 @@ DeviceEvent *event = (DeviceEvent*)xE;
* see. it's still steaming. told you. (whot)
*/
{
/* FIXME: temporary solution only. */
static int nevents;
static xEvent ev[1000]; /* enough bytes for the events we have atm */
nevents = ConvertBackToXI((InternalEvent*)xE, ev);
UNWRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr, backupproc);
mouse->public.processInputProc(ev, mouse, nevents);
mouse->public.processInputProc(xE, mouse, count);
COND_WRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr,
backupproc, xkbUnwrapProc);
}
xkbi->state.ptr_buttons = mouse->button->state;

View File

@ -1211,20 +1211,10 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
else
tmpdev = GetPairedDevice(dev);
{
/* FIXME: temporary solution only. */
static int nevents;
static xEvent ev[1000]; /* enough bytes for the events we have atm */
nevents = ConvertBackToXI((InternalEvent*)event, ev);
UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc);
dev->public.processInputProc(ev, tmpdev, nevents);
dev->public.processInputProc((xEvent*)event, tmpdev, 1);
COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
backupproc,xkbUnwrapProc);
}
}
else if (keyEvent) {
FixKeyState(event, dev);

View File

@ -177,14 +177,8 @@ ProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
/* We're only interested in key events. */
if (!is_press && !is_release) {
/* FIXME: temporary solution only. */
static int nevents;
static xEvent ev[1000]; /* enough bytes for the events we have atm */
nevents = ConvertBackToXI((InternalEvent*)xE, ev);
UNWRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc);
keybd->public.processInputProc(ev, keybd, nevents);
keybd->public.processInputProc(xE, keybd, count);
COND_WRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc,
xkbUnwrapProc);
return;