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

View File

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

View File

@ -1009,16 +1009,24 @@ NoticeEventTime(xEvent *xE)
* linked list for later delivery. * linked list for later delivery.
*/ */
void void
EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count) EnqueueEvent(xEvent *ev, DeviceIntPtr device, int count)
{ {
QdEventPtr tail = *syncEvents.pendtail; QdEventPtr tail = *syncEvents.pendtail;
QdEventPtr qe; QdEventPtr qe;
SpritePtr pSprite = device->spriteInfo->sprite; SpritePtr pSprite = device->spriteInfo->sprite;
int eventlen; 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); NoticeTime(xE);
/* Fix for key repeating bug. */ /* Fix for key repeating bug. */
if (device->key != NULL && device->key->xkbInfo != NULL && if (device->key != NULL && device->key->xkbInfo != NULL &&
xE->u.u.type == KeyRelease) xE->u.u.type == KeyRelease)
@ -1040,7 +1048,7 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
XE_KBPTR.root = XE_KBPTR.root =
WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id; WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id;
eventinfo.events = xE; eventinfo.events = xE;
eventinfo.count = count; eventinfo.count = nevents;
CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo); CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
} }
if (xE->u.u.type == DeviceMotionNotify) 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 */ if (xE->u.u.type == GenericEvent) /* count is 1 for GenericEvents */
eventlen += ((xGenericEvent*)xE)->length * 4; eventlen += ((xGenericEvent*)xE)->length * 4;
@ -1081,14 +1089,14 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
qe->pScreen = pSprite->hotPhys.pScreen; qe->pScreen = pSprite->hotPhys.pScreen;
qe->months = currentTime.months; qe->months = currentTime.months;
qe->event = (xEvent *)(qe + 1); qe->event = (xEvent *)(qe + 1);
qe->evcount = count; qe->evcount = nevents;
if (xE->u.u.type == GenericEvent) if (xE->u.u.type == GenericEvent)
{ {
memcpy(qe->event, xE, eventlen); memcpy(qe->event, xE, eventlen);
} else } else
{ {
xEvent *qxE; xEvent *qxE;
for (qxE = qe->event; --count >= 0; qxE++, xE++) for (qxE = qe->event; --nevents >= 0; qxE++, xE++)
{ {
*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.event.state |= pointer->button->state;
de->u.u.type = (IEventBase - 1) + coreEquiv; /* change to XI event */ 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); UpdateDeviceState(keybd, (xEvent*)de, 1);
#endif
de->u.u.type = *XDGAEventBase + coreEquiv; /* change back */ 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.event.state |= XkbStateFieldFromRec(&GetPairedDevice(mouse)->key->xkbInfo->state);
de->u.u.type = (IEventBase - 1) + coreEquiv; /* change to XI event */ 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); UpdateDeviceState(mouse, (xEvent*)de, 1);
#endif
de->u.u.type = *XDGAEventBase + coreEquiv; /* change back */ de->u.u.type = *XDGAEventBase + coreEquiv; /* change back */
/* /*

View File

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

View File

@ -722,19 +722,10 @@ DeviceEvent *event = (DeviceEvent*)xE;
* see. it's still steaming. told you. (whot) * 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); 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, COND_WRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr,
backupproc, xkbUnwrapProc); backupproc, xkbUnwrapProc);
}
xkbi->state.ptr_buttons = mouse->button->state; xkbi->state.ptr_buttons = mouse->button->state;

View File

@ -1211,20 +1211,10 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
else else
tmpdev = GetPairedDevice(dev); 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); 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, COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
backupproc,xkbUnwrapProc); backupproc,xkbUnwrapProc);
}
} }
else if (keyEvent) { else if (keyEvent) {
FixKeyState(event, dev); FixKeyState(event, dev);

View File

@ -177,14 +177,8 @@ ProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
/* We're only interested in key events. */ /* We're only interested in key events. */
if (!is_press && !is_release) { 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); 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, COND_WRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc,
xkbUnwrapProc); xkbUnwrapProc);
return; return;