dix: convert passive grabs to use internal events.

deviceGrab.sync.event is now an internal event, and CheckDeviceGrabs and
friends is changed over.

Note that this currently breaks some frozen grabs. See towards the end of
ComputeFreezes().

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2009-02-01 09:58:15 +10:00
parent daa3245c47
commit 8f94ec6f78
4 changed files with 82 additions and 94 deletions

View File

@ -118,27 +118,15 @@ RegisterOtherDevice(DeviceIntPtr device)
} }
Bool Bool
IsPointerEvent(xEvent* xE) IsPointerEvent(InternalEvent* event)
{ {
switch(xE->u.u.type) switch(event->u.any.type)
{ {
case ButtonPress: case ET_ButtonPress:
case ButtonRelease: case ET_ButtonRelease:
case MotionNotify: case ET_Motion:
case EnterNotify: /* XXX: enter/leave ?? */
case LeaveNotify:
return TRUE; return TRUE;
default:
if (xE->u.u.type == DeviceButtonPress ||
xE->u.u.type == DeviceButtonRelease ||
xE->u.u.type == DeviceMotionNotify ||
xE->u.u.type == DeviceEnterNotify ||
xE->u.u.type == DeviceLeaveNotify ||
xE->u.u.type == ProximityIn ||
xE->u.u.type == ProximityOut)
{
return TRUE;
}
} }
return FALSE; return FALSE;
} }
@ -955,8 +943,8 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
break; break;
} }
nevents = ConvertBackToXI((InternalEvent*)ev, xE); #if 0
/* FIXME: I'm broken. Please fix me. Thanks */
if (DeviceEventCallback) { if (DeviceEventCallback) {
DeviceEventInfoRec eventinfo; DeviceEventInfoRec eventinfo;
@ -964,11 +952,12 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
eventinfo.count = count; eventinfo.count = count;
CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
} }
#endif
switch(event->type) switch(event->type)
{ {
case ET_KeyPress: case ET_KeyPress:
if (!grab && CheckDeviceGrabs(device, xE, 0, nevents)) { if (!grab && CheckDeviceGrabs(device, event, 0)) {
device->deviceGrab.activatingKey = key; device->deviceGrab.activatingKey = key;
return; return;
} }
@ -982,10 +971,9 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
event->detail.button = b->map[key]; event->detail.button = b->map[key];
if (!event->detail.button) { /* there's no button 0 */ if (!event->detail.button) { /* there's no button 0 */
event->detail.button = key; event->detail.button = key;
xE->u.u.detail = key; /* XXX: temporary */
return; return;
} }
if (!grab && CheckDeviceGrabs(device, xE, 0, nevents)) if (!grab && CheckDeviceGrabs(device, event, 0))
{ {
/* if a passive grab was activated, the event has been sent /* if a passive grab was activated, the event has been sent
* already */ * already */
@ -995,13 +983,14 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
event->detail.button = b->map[key]; event->detail.button = b->map[key];
if (!event->detail.button) { /* there's no button 0 */ if (!event->detail.button) { /* there's no button 0 */
event->detail.button = key; event->detail.button = key;
xE->u.u.detail = key; /* XXX: temporary */
return; return;
} }
if (!b->buttonsDown && device->deviceGrab.fromPassiveGrab) if (!b->buttonsDown && device->deviceGrab.fromPassiveGrab)
deactivateDeviceGrab = TRUE; deactivateDeviceGrab = TRUE;
} }
nevents = ConvertBackToXI((InternalEvent*)ev, xE);
if (grab) if (grab)
DeliverGrabbedEvent(xE, device, deactivateDeviceGrab, count); DeliverGrabbedEvent(xE, device, deactivateDeviceGrab, count);
else if (device->focus && !IsPointerEvent(xE)) else if (device->focus && !IsPointerEvent(xE))

View File

@ -162,6 +162,7 @@ typedef const char *string;
#include "geint.h" #include "geint.h"
#include "enterleave.h" #include "enterleave.h"
#include "eventconvert.h"
/* Extension events type numbering starts at EXTENSION_EVENT_BASE. */ /* Extension events type numbering starts at EXTENSION_EVENT_BASE. */
#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */ #define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
@ -1202,9 +1203,6 @@ FreezeThaw(DeviceIntPtr dev, Bool frozen)
* runs up the sprite tree (spriteTrace) and searches for the window to replay * runs up the sprite tree (spriteTrace) and searches for the window to replay
* the events from. If it is found, it checks for passive grabs one down from * the events from. If it is found, it checks for passive grabs one down from
* the window or delivers the events. * the window or delivers the events.
*
* Since the events in the EQ are always XI events, we need to emulate core
* events here.
*/ */
static void static void
ComputeFreezes(void) ComputeFreezes(void)
@ -1212,11 +1210,13 @@ ComputeFreezes(void)
DeviceIntPtr replayDev = syncEvents.replayDev; DeviceIntPtr replayDev = syncEvents.replayDev;
int i; int i;
WindowPtr w; WindowPtr w;
xEvent *xE;
int count;
GrabPtr grab; GrabPtr grab;
DeviceIntPtr dev; DeviceIntPtr dev;
/* FIXME: temporary solution only. */
static int count;
static xEvent xE[1000]; /* enough bytes for the events we have atm */
for (dev = inputInfo.devices; dev; dev = dev->next) for (dev = inputInfo.devices; dev; dev = dev->next)
FreezeThaw(dev, dev->deviceGrab.sync.other || FreezeThaw(dev, dev->deviceGrab.sync.other ||
(dev->deviceGrab.sync.state >= FROZEN)); (dev->deviceGrab.sync.state >= FROZEN));
@ -1225,18 +1225,21 @@ ComputeFreezes(void)
syncEvents.playingEvents = TRUE; syncEvents.playingEvents = TRUE;
if (replayDev) if (replayDev)
{ {
xE = replayDev->deviceGrab.sync.event; DeviceEvent* event = replayDev->deviceGrab.sync.event;
count = replayDev->deviceGrab.sync.evcount;
/* FIXME: temporary */
count = ConvertBackToXI(replayDev->deviceGrab.sync.event);
syncEvents.replayDev = (DeviceIntPtr)NULL; syncEvents.replayDev = (DeviceIntPtr)NULL;
w = XYToWindow(replayDev, XE_KBPTR.rootX, XE_KBPTR.rootY); w = XYToWindow(replayDev, event->root_x, event->root_y);
for (i = 0; i < replayDev->spriteInfo->sprite->spriteTraceGood; i++) for (i = 0; i < replayDev->spriteInfo->sprite->spriteTraceGood; i++)
{ {
if (syncEvents.replayWin == if (syncEvents.replayWin ==
replayDev->spriteInfo->sprite->spriteTrace[i]) replayDev->spriteInfo->sprite->spriteTrace[i])
{ {
if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) { if (!CheckDeviceGrabs(replayDev, event, i+1)) {
if (replayDev->focus && !IsPointerEvent(xE)) if (replayDev->focus && !IsPointerEvent((InternalEvent*)event))
DeliverFocusedEvent(replayDev, xE, w, count); DeliverFocusedEvent(replayDev, xE, w, count);
else else
DeliverDeviceEvents(w, xE, NullGrab, NullWindow, DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
@ -1246,7 +1249,7 @@ ComputeFreezes(void)
} }
} }
/* must not still be in the same stack */ /* must not still be in the same stack */
if (replayDev->focus && !IsPointerEvent(xE)) if (replayDev->focus && !IsPointerEvent((InternalEvent*)event))
DeliverFocusedEvent(replayDev, xE, w, count); DeliverFocusedEvent(replayDev, xE, w, count);
else else
DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count); DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
@ -3139,32 +3142,35 @@ BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin)
* *
* @param pWin The window that may be subject to a passive grab. * @param pWin The window that may be subject to a passive grab.
* @param device Device that caused the event. * @param device Device that caused the event.
* @param xE List of events (multiple ones for DeviceMotionNotify) * @param event The current device event.
* @param count number of elements in xE. * @param checkCore Check for core grabs too.
* @param store The event that will be stored on the device (always XI)
* @param scount number of elements in store.
*/ */
static Bool static Bool
CheckPassiveGrabsOnWindow( CheckPassiveGrabsOnWindow(
WindowPtr pWin, WindowPtr pWin,
DeviceIntPtr device, DeviceIntPtr device,
xEvent *xE, DeviceEvent *event,
int count, BOOL checkCore)
xEvent *store,
int scount)
{ {
GrabPtr grab = wPassiveGrabs(pWin); GrabPtr grab = wPassiveGrabs(pWin);
GrabRec tempGrab; GrabRec tempGrab;
GrabInfoPtr grabinfo; GrabInfoPtr grabinfo;
xEvent *dxE; #define CORE_MATCH 0x1
#define XI_MATCH 0x2
int match = 0;
/* FIXME: temporary solution only. */
static int count;
static xEvent xE[1000]; /* enough bytes for the events we have atm */
if (!grab) if (!grab)
return FALSE; return FALSE;
/* Fill out the grab details, but leave the type for later before
* comparing */
tempGrab.window = pWin; tempGrab.window = pWin;
tempGrab.device = device; tempGrab.device = device;
tempGrab.type = xE->u.u.type; tempGrab.detail.exact = event->detail.key;
tempGrab.detail.exact = xE->u.u.detail;
tempGrab.detail.pMask = NULL; tempGrab.detail.pMask = NULL;
tempGrab.modifiersDetail.pMask = NULL; tempGrab.modifiersDetail.pMask = NULL;
tempGrab.next = NULL; tempGrab.next = NULL;
@ -3185,14 +3191,23 @@ CheckPassiveGrabsOnWindow(
xkbi= gdev->key->xkbInfo; xkbi= gdev->key->xkbInfo;
tempGrab.modifierDevice = grab->modifierDevice; tempGrab.modifierDevice = grab->modifierDevice;
tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0; tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
/* ignore the device for core events when comparing grabs */
if (GrabMatchesSecond(&tempGrab, grab, (xE->u.u.type < GenericEvent)) && /* Check for XI grabs first */
(!grab->confineTo || tempGrab.type = GetXIType((InternalEvent*)event);
if (GrabMatchesSecond(&tempGrab, grab, FALSE))
match = XI_MATCH;
/* Check for a core grab (ignore the device when comparing) */
if (!match && checkCore &&
(tempGrab.type = GetCoreType((InternalEvent*)event)) &&
(GrabMatchesSecond(&tempGrab, grab, TRUE)))
match = CORE_MATCH;
if (match && (!grab->confineTo ||
(grab->confineTo->realized && (grab->confineTo->realized &&
BorderSizeNotEmpty(device, grab->confineTo)))) BorderSizeNotEmpty(device, grab->confineTo))))
{ {
XE_KBPTR.state &= 0x1f00; event->corestate &= 0x1f00;
XE_KBPTR.state |= tempGrab.modifiersDetail.exact&(~0x1f00); event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00);
grabinfo = &device->deviceGrab; grabinfo = &device->deviceGrab;
/* A passive grab may have been created for a different device /* A passive grab may have been created for a different device
than it is assigned to at this point in time. than it is assigned to at this point in time.
@ -3201,7 +3216,7 @@ CheckPassiveGrabsOnWindow(
Since XGrabDeviceButton requires to specify the Since XGrabDeviceButton requires to specify the
modifierDevice explicitly, we don't override this choice. modifierDevice explicitly, we don't override this choice.
*/ */
if (xE->u.u.type < GenericEvent) if (tempGrab.type < GenericEvent)
{ {
grab->device = device; grab->device = device;
grab->modifierDevice = GetPairedDevice(device); grab->modifierDevice = GetPairedDevice(device);
@ -3236,6 +3251,11 @@ CheckPassiveGrabsOnWindow(
} }
/* FIXME: temporary only */
count = ConvertBackToXI((InternalEvent*)event, xE);
if (match & CORE_MATCH)
xE->u.u.type = GetCoreType(event);
(*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE); (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
FixUpEventFromWindow(device, xE, grab->window, None, TRUE); FixUpEventFromWindow(device, xE, grab->window, None, TRUE);
@ -3246,21 +3266,17 @@ CheckPassiveGrabsOnWindow(
if (grabinfo->sync.state == FROZEN_NO_EVENT) if (grabinfo->sync.state == FROZEN_NO_EVENT)
{ {
if (grabinfo->sync.evcount < scount) if (!grabinfo->sync.event)
{ grabinfo->sync.event = xcalloc(1, sizeof(InternalEvent));
grabinfo->sync.event = xrealloc(grabinfo->sync.event, *grabinfo->sync.event = *event;
scount * sizeof(xEvent));
}
grabinfo->sync.evcount = scount;
/* we always store the XI event, never the core event */
for (dxE = grabinfo->sync.event; --scount >= 0; dxE++, store++)
*dxE = *store;
grabinfo->sync.state = FROZEN_WITH_EVENT; grabinfo->sync.state = FROZEN_WITH_EVENT;
} }
return TRUE; return TRUE;
} }
} }
return FALSE; return FALSE;
#undef CORE_MATCH
#undef XI_MATCH
} }
/** /**
@ -3290,33 +3306,20 @@ CheckPassiveGrabsOnWindow(
*/ */
Bool Bool
CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE, CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, int checkFirst)
int checkFirst, int count)
{ {
int i; int i;
WindowPtr pWin = NULL; WindowPtr pWin = NULL;
FocusClassPtr focus = IsPointerEvent(xE) ? NULL : device->focus; FocusClassPtr focus = IsPointerEvent((InternalEvent*)event) ? NULL : device->focus;
xEvent core;
BOOL sendCore = (device->isMaster && device->coreEvents); BOOL sendCore = (device->isMaster && device->coreEvents);
if ((xE->u.u.type == DeviceButtonPress) if (event->type != ET_ButtonPress &&
&& (device->button->buttonsDown != 1)) event->type != ET_KeyPress)
return FALSE;
if (xE->u.u.type < EXTENSION_EVENT_BASE)
{
ErrorF("[dix] Core event passed into CheckDeviceGrabs.\n");
return FALSE; return FALSE;
}
if (event->type == ET_ButtonPress
if (sendCore) && (device->button->buttonsDown != 1))
{ return FALSE;
core = *xE;
core.u.u.type = XItoCoreType(xE->u.u.type);
if(!core.u.u.type) /* probably a Proximity event, can't grab for those */
return FALSE;
}
i = checkFirst; i = checkFirst;
@ -3325,11 +3328,8 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
for (; i < focus->traceGood; i++) for (; i < focus->traceGood; i++)
{ {
pWin = focus->trace[i]; pWin = focus->trace[i];
/* XI grabs have precendence */
if (pWin->optional && if (pWin->optional &&
(CheckPassiveGrabsOnWindow(pWin, device, xE, count, xE, count) CheckPassiveGrabsOnWindow(pWin, device, event, sendCore))
|| (sendCore && CheckPassiveGrabsOnWindow(pWin, device, &core,
1, xE, count))))
return TRUE; return TRUE;
} }
@ -3344,9 +3344,7 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
{ {
pWin = device->spriteInfo->sprite->spriteTrace[i]; pWin = device->spriteInfo->sprite->spriteTrace[i];
if (pWin->optional && if (pWin->optional &&
(CheckPassiveGrabsOnWindow(pWin, device, xE, count, xE, count) || CheckPassiveGrabsOnWindow(pWin, device, event, sendCore))
(sendCore && CheckPassiveGrabsOnWindow(pWin, device, &core, 1,
xE, count))))
return TRUE; return TRUE;
} }
@ -3566,6 +3564,8 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
case FREEZE_NEXT_EVENT: case FREEZE_NEXT_EVENT:
grabinfo->sync.state = FROZEN_WITH_EVENT; grabinfo->sync.state = FROZEN_WITH_EVENT;
FreezeThaw(thisDev, TRUE); FreezeThaw(thisDev, TRUE);
#if 0
/* FIXME: Sorry, frozen grabs are broken ATM */
if (grabinfo->sync.evcount < count) if (grabinfo->sync.evcount < count)
{ {
grabinfo->sync.event = xrealloc(grabinfo->sync.event, grabinfo->sync.event = xrealloc(grabinfo->sync.event,
@ -3574,6 +3574,7 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
grabinfo->sync.evcount = count; grabinfo->sync.evcount = count;
for (dxE = grabinfo->sync.event; --count >= 0; dxE++, xE++) for (dxE = grabinfo->sync.event; --count >= 0; dxE++, xE++)
*dxE = *xE; *dxE = *xE;
#endif
break; break;
} }
} }

View File

@ -390,9 +390,8 @@ extern _X_EXPORT void WindowHasNewCursor(
extern _X_EXPORT Bool CheckDeviceGrabs( extern _X_EXPORT Bool CheckDeviceGrabs(
DeviceIntPtr /* device */, DeviceIntPtr /* device */,
xEventPtr /* xE */, DeviceEvent* /* event */,
int /* checkFirst */, int /* checkFirst */);
int /* count */);
extern _X_EXPORT void DeliverFocusedEvent( extern _X_EXPORT void DeliverFocusedEvent(
DeviceIntPtr /* keybd */, DeviceIntPtr /* keybd */,
@ -584,7 +583,7 @@ extern _X_EXPORT int XItoCoreType(int xi_type);
extern _X_EXPORT Bool DevHasCursor(DeviceIntPtr pDev); extern _X_EXPORT Bool DevHasCursor(DeviceIntPtr pDev);
extern _X_EXPORT Bool IsPointerDevice( DeviceIntPtr dev); extern _X_EXPORT Bool IsPointerDevice( DeviceIntPtr dev);
extern _X_EXPORT Bool IsKeyboardDevice(DeviceIntPtr dev); extern _X_EXPORT Bool IsKeyboardDevice(DeviceIntPtr dev);
extern _X_EXPORT Bool IsPointerEvent(xEvent* xE); extern _X_EXPORT Bool IsPointerEvent(InternalEvent* event);
/* /*
* These are deprecated compatibility functions and will be removed soon! * These are deprecated compatibility functions and will be removed soon!

View File

@ -426,8 +426,7 @@ typedef struct _GrabInfoRec {
Bool frozen; Bool frozen;
int state; int state;
GrabPtr other; /* if other grab has this frozen */ GrabPtr other; /* if other grab has this frozen */
xEvent *event; /* saved to be replayed */ DeviceEvent *event; /* saved to be replayed */
int evcount;
} sync; } sync;
} GrabInfoRec, *GrabInfoPtr; } GrabInfoRec, *GrabInfoPtr;