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:
parent
007e93c869
commit
8829d966a6
168
Xi/exevents.c
168
Xi/exevents.c
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
18
dix/events.c
18
dix/events.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 */,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user