Xi: Move updating the device state from POE into separate function.

POE now only deals with processing the event and calling the appropriate
delivery methods. Actually modifying the device state is done in
UpdateDeviceState. This separation should make it easier to avoid setting the
state twice when master events are processed.
This commit is contained in:
Peter Hutterer 2007-11-14 12:18:08 +10:30
parent 0bdfeb55fc
commit 240b10fa9c

View File

@ -102,31 +102,69 @@ RegisterOtherDevice(DeviceIntPtr device)
device->public.realInputProc = ProcessOtherEvent;
}
/**
* Main device event processing function.
* Called from when processing the events from the event queue.
* Generates core events for XI events as needed.
*
* Note that these core events are then delivered first. For passive grabs, XI
* events have preference over core.
*/
void
ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
static void
ChangeMasterDeviceClasses(DeviceIntPtr device,
deviceClassesChangedEvent *dcce)
{
DeviceIntPtr master = device->u.master;
char* classbuff;
if (device->isMaster)
return;
if (!master) /* if device was set floating between SIGIO and now */
return;
dcce->deviceid = master->id;
dcce->num_classes = 0;
master->key = device->key;
master->valuator = device->valuator;
master->button = device->button;
master->focus = device->focus;
master->proximity = device->proximity;
master->absolute = device->absolute;
master->kbdfeed = device->kbdfeed;
master->ptrfeed = device->ptrfeed;
master->intfeed = device->intfeed;
master->stringfeed = device->stringfeed;
master->bell = device->bell;
master->leds = device->leds;
/* event is already correct size, see comment in GetPointerEvents */
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);
SendEventToAllWindows(master, XI_DeviceClassesChangedMask,
(xEvent*)dcce, 1);
}
/**
* Update the device state according to the data in the event.
*
* return values are
* DEFAULT ... process as normal
* DONT_PROCESS ... return immediately from caller
* IS_REPEAT .. event is a repeat event.
*/
#define DEFAULT 0
#define DONT_PROCESS 1
#define IS_REPEAT 2
static int
UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
{
BYTE *kptr;
int i;
CARD16 modifiers;
CARD16 mask;
GrabPtr grab = device->deviceGrab.grab;
Bool deactivateDeviceGrab = FALSE;
int key = 0, bit = 0, rootX, rootY;
ButtonClassPtr b = device->button;
KeyClassPtr k = device->key;
ValuatorClassPtr v = device->valuator;
deviceValuator *xV = (deviceValuator *) xE;
BOOL sendCore = FALSE;
xEvent core;
int coretype = 0;
int key = 0,
bit = 0;
KeyClassPtr k = device->key;
ButtonClassPtr b = device->button;
ValuatorClassPtr v = device->valuator;
deviceValuator *xV = (deviceValuator *) xE;
BYTE *kptr = NULL;
CARD16 modifiers = 0,
mask = 0;
/* 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
@ -134,99 +172,31 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
*/
if (GEIsType(xE, IReqCode, XI_DeviceClassesChangedNotify))
{
deviceClassesChangedEvent* dcce = (deviceClassesChangedEvent*)xE;
DeviceIntPtr master = device->u.master;
char* classbuff;
if (device->isMaster)
return;
if (!master) /* if device was set floating between SIGIO and now */
return;
dcce->deviceid = master->id;
dcce->num_classes = 0;
master->key = device->key;
master->valuator = device->valuator;
master->button = device->button;
master->focus = device->focus;
master->proximity = device->proximity;
master->absolute = device->absolute;
master->kbdfeed = device->kbdfeed;
master->ptrfeed = device->ptrfeed;
master->intfeed = device->intfeed;
master->stringfeed = device->stringfeed;
master->bell = device->bell;
master->leds = device->leds;
/* event is already correct size, see comment in GetPointerEvents */
classbuff = (char*)&xE[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);
SendEventToAllWindows(master, XI_DeviceClassesChangedMask, xE, 1);
return;
ChangeMasterDeviceClasses(device, (deviceClassesChangedEvent*)xE);
return DONT_PROCESS; /* event has been sent already */
}
coretype = XItoCoreType(xE->u.u.type);
if (device->isMaster && device->coreEvents && coretype)
sendCore = TRUE;
/* currently no other generic event modifies the device */
if (xE->u.u.type == GenericEvent)
return DEFAULT;
if (device->isMaster)
CheckMotion(xE, device);
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;
xE->u.keyButtonPointer.rootY = rootY;
key = xE->u.u.detail;
NoticeEventTime(xE);
/* If 'device' is a pointer device, we need to get the paired keyboard
* for the state. If there is none, the kbd bits of state are 0.
* If 'device' is a keyboard device, get the paired pointer and use the
* pointer's state for the button bits.
*/
if (IsPointerDevice(device))
{
kbd = GetPairedDevice(device);
mouse = device;
}
else
{
mouse = GetPairedDevice(device);
kbd = device;
}
xE->u.keyButtonPointer.state = (kbd) ? (kbd->key->state) : 0;
xE->u.keyButtonPointer.state |= (mouse) ? (mouse->button->state) : 0;
bit = 1 << (key & 7);
if (xE->u.u.type != DeviceValuator)
{
key = xE->u.u.detail;
bit = 1 << (key & 7);
}
if (DeviceEventCallback) {
DeviceEventInfoRec eventinfo;
eventinfo.events = (xEventPtr) xE;
eventinfo.count = count;
CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
}
for (i = 1; i < count; i++)
/* Update device axis */
for (i = 1; i < count; i++) {
if ((++xV)->type == DeviceValuator) {
int first = xV->first_valuator;
int *axisvals;
int first = xV->first_valuator;
if (xV->num_valuators
&& (!v
|| (xV->num_valuators
&& (first + xV->num_valuators > v->numAxes))))
if (xV->num_valuators &&
(!v || (xV->num_valuators &&
(first + xV->num_valuators > v->numAxes))))
FatalError("Bad valuators reported for device %s\n",
device->name);
xV->device_state = 0;
if (k)
xV->device_state |= k->state;
if (b)
xV->device_state |= b->state;
if (v && v->axisVal) {
axisvals = v->axisVal;
switch (xV->num_valuators) {
@ -248,22 +218,16 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
}
}
}
}
if (xE->u.u.type == DeviceKeyPress) {
if (!k)
return;
return DONT_PROCESS;
modifiers = k->modifierMap[key];
kptr = &k->down[key >> 3];
if (*kptr & bit) { /* allow ddx to generate multiple downs */
if (!modifiers) {
xE->u.u.type = DeviceKeyRelease;
ProcessOtherEvent(xE, device, count);
xE->u.u.type = DeviceKeyPress;
/* release can have side effects, don't fall through */
ProcessOtherEvent(xE, device, count);
}
return;
return IS_REPEAT;
}
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
@ -277,22 +241,13 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
modifiers &= ~mask;
}
}
/* XI grabs have priority */
core = *xE;
core.u.u.type = coretype;
if (!grab &&
(CheckDeviceGrabs(device, xE, 0, count) ||
(sendCore && CheckDeviceGrabs(device, &core, 0, 1)))) {
device->deviceGrab.activatingKey = key;
return;
}
} else if (xE->u.u.type == DeviceKeyRelease) {
if (!k)
return;
return DONT_PROCESS;
kptr = &k->down[key >> 3];
if (!(*kptr & bit)) /* guard against duplicates */
return;
return DONT_PROCESS;
modifiers = k->modifierMap[key];
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
@ -308,26 +263,167 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
modifiers &= ~mask;
}
}
if (device->deviceGrab.fromPassiveGrab &&
(key == device->deviceGrab.activatingKey))
deactivateDeviceGrab = TRUE;
} else if (xE->u.u.type == DeviceButtonPress) {
if (!b)
return;
return DONT_PROCESS;
kptr = &b->down[key >> 3];
*kptr |= bit;
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
b->buttonsDown++;
if (!device->isMaster)
b->buttonsDown++;
b->motionMask = DeviceButtonMotionMask;
if (!device->isMaster && !b->map[key]) /* bit already unset for MDs */
return DONT_PROCESS;
if (b->map[key] <= 5)
b->state |= (Button1Mask >> 1) << b->map[key];
SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify);
} else if (xE->u.u.type == DeviceButtonRelease) {
if (!b)
return DONT_PROCESS;
kptr = &b->down[key >> 3];
if (!(*kptr & bit))
return DONT_PROCESS;
*kptr &= ~bit;
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
if (!device->isMaster)
b->buttonsDown--;
if (b->buttonsDown >= 1 && !b->buttonsDown)
b->motionMask = 0;
if (!b->map[key])
return DONT_PROCESS;
if (b->map[key] <= 5)
b->state &= ~((Button1Mask >> 1) << b->map[key]);
SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify);
} else if (xE->u.u.type == ProximityIn)
device->valuator->mode &= ~OutOfProximity;
else if (xE->u.u.type == ProximityOut)
device->valuator->mode |= OutOfProximity;
return DEFAULT;
}
/**
* Main device event processing function.
* Called from when processing the events from the event queue.
* Generates core events for XI events as needed.
*
* Note that these core events are then delivered first. For passive grabs, XI
* events have preference over core.
*/
void
ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
{
int i;
CARD16 modifiers;
GrabPtr grab = device->deviceGrab.grab;
Bool deactivateDeviceGrab = FALSE;
int key = 0, rootX, rootY;
ButtonClassPtr b = device->button;
KeyClassPtr k = device->key;
ValuatorClassPtr v = device->valuator;
deviceValuator *xV = (deviceValuator *) xE;
BOOL sendCore = FALSE;
xEvent core;
int coretype = 0;
int ret = 0;
ret = UpdateDeviceState(device, xE, count);
if (ret == DONT_PROCESS)
return;
coretype = XItoCoreType(xE->u.u.type);
if (device->isMaster && device->coreEvents && coretype)
sendCore = TRUE;
if (device->isMaster)
CheckMotion(xE, device);
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;
xE->u.keyButtonPointer.rootY = rootY;
NoticeEventTime(xE);
/* If 'device' is a pointer device, we need to get the paired keyboard
* for the state. If there is none, the kbd bits of state are 0.
* If 'device' is a keyboard device, get the paired pointer and use the
* pointer's state for the button bits.
*/
if (IsPointerDevice(device))
{
kbd = GetPairedDevice(device);
mouse = device;
}
else
{
mouse = GetPairedDevice(device);
kbd = device;
}
xE->u.keyButtonPointer.state = (kbd) ? (kbd->key->state) : 0;
xE->u.keyButtonPointer.state |= (mouse) ? (mouse->button->state) : 0;
key = xE->u.u.detail;
}
if (DeviceEventCallback) {
DeviceEventInfoRec eventinfo;
eventinfo.events = (xEventPtr) xE;
eventinfo.count = count;
CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
}
/* Valuator event handling */
for (i = 1; i < count; i++) {
if ((++xV)->type == DeviceValuator) {
int first = xV->first_valuator;
if (xV->num_valuators
&& (!v
|| (xV->num_valuators
&& (first + xV->num_valuators > v->numAxes))))
FatalError("Bad valuators reported for device %s\n",
device->name);
xV->device_state = 0;
if (k)
xV->device_state |= k->state;
if (b)
xV->device_state |= b->state;
}
}
if (xE->u.u.type == DeviceKeyPress) {
if (ret == IS_REPEAT) { /* allow ddx to generate multiple downs */
modifiers = k->modifierMap[key];
if (!modifiers) {
xE->u.u.type = DeviceKeyRelease;
ProcessOtherEvent(xE, device, count);
xE->u.u.type = DeviceKeyPress;
/* release can have side effects, don't fall through */
ProcessOtherEvent(xE, device, count);
}
return;
}
/* XI grabs have priority */
core = *xE;
core.u.u.type = coretype;
if (!grab &&
(CheckDeviceGrabs(device, xE, 0, count) ||
(sendCore && CheckDeviceGrabs(device, &core, 0, 1)))) {
device->deviceGrab.activatingKey = key;
return;
}
} else if (xE->u.u.type == DeviceKeyRelease) {
if (device->deviceGrab.fromPassiveGrab &&
(key == device->deviceGrab.activatingKey))
deactivateDeviceGrab = TRUE;
} else if (xE->u.u.type == DeviceButtonPress) {
xE->u.u.detail = b->map[key];
if (xE->u.u.detail == 0)
return;
if (xE->u.u.detail <= 5)
b->state |= (Button1Mask >> 1) << xE->u.u.detail;
SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify);
if (!grab)
{
core = *xE;
@ -342,28 +438,12 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
}
} else if (xE->u.u.type == DeviceButtonRelease) {
if (!b)
return;
kptr = &b->down[key >> 3];
*kptr &= ~bit;
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
if (b->buttonsDown >= 1 && !--b->buttonsDown)
b->motionMask = 0;
xE->u.u.detail = b->map[key];
if (xE->u.u.detail == 0)
return;
if (xE->u.u.detail <= 5)
b->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify);
if (!b->state
&& device->deviceGrab.fromPassiveGrab)
if (!b->state && device->deviceGrab.fromPassiveGrab)
deactivateDeviceGrab = TRUE;
} else if (xE->u.u.type == ProximityIn)
device->valuator->mode &= ~OutOfProximity;
else if (xE->u.u.type == ProximityOut)
device->valuator->mode |= OutOfProximity;
}
if (sendCore)
{