summaryrefslogtreecommitdiff
path: root/dix/events.c
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2008-01-15 11:31:12 +1030
committerPeter Hutterer <peter@cs.unisa.edu.au>2008-01-15 11:31:12 +1030
commit0969a9f7497e10794a6534321c10a0e1ac680ad7 (patch)
treeae51f8c705fb1264de440d828e9ff78058d8b837 /dix/events.c
parenta83a0c5a144da67dab96a857b849a5692b73245d (diff)
dix: Emulate core events within CheckDeviceGrabs and ComputeFreezes.
This should restore the correct passive grab processing. When checking for passive grabs, the core event is emulated and we check first for XI grabs on the window, then for core grabs. Regardless of which event activates the grab, the XI event is stored in the device's EQ. When replaying the event, we take the XI event and replay it on the next window, again including the emulation of the core event.
Diffstat (limited to 'dix/events.c')
-rw-r--r--dix/events.c81
1 files changed, 46 insertions, 35 deletions
diff --git a/dix/events.c b/dix/events.c
index ca5bae52e..4de3b01b1 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1359,6 +1359,9 @@ FreezeThaw(DeviceIntPtr dev, Bool frozen)
* 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 window or delivers the events.
+ *
+ * Since the events in the EQ are always XI events, we need to emulate core
+ * events here.
*/
static void
ComputeFreezes(void)
@@ -1391,30 +1394,10 @@ ComputeFreezes(void)
replayDev->spriteInfo->sprite->spriteTrace[i])
{
if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
- /* There is no other client that gets a passive grab on
- * the event anymore. Emulate core event if necessary and
- * deliver it too.
- * However, we might get here with a core event, in which
- * case we mustn't emulate a core event.
- */
- sendCore = (replayDev->coreEvents &&
- (xE->u.u.type & EXTENSION_EVENT_BASE &&
- XItoCoreType(xE->u.u.type)));
-
-
- if (sendCore)
- {
- core = *xE;
- core.u.u.type = XItoCoreType(xE->u.u.type);
- /* * XXX: Not sure if this is correct: we need to
- * check inferior windows for core passive grabs.
- */
- if (CheckDeviceGrabs(replayDev, &core, i+1, 1))
- {
- syncEvents.playingEvents = FALSE;
- return;
- }
- }
+ sendCore = (replayDev->coreEvents && replayDev->isMaster);
+ core = *xE;
+ core.u.u.type = XItoCoreType(xE->u.u.type);
+
if (replayDev->focus)
{
if (sendCore)
@@ -3367,7 +3350,9 @@ BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin)
* @param pWin The window that may be subject to a passive grab.
* @param device Device that caused the event.
* @param xE List of events (multiple ones for DeviceMotionNotify)
- * @count number of elements in xE.
+ * @param count number of elements in xE.
+ * @param store The event that will be stored on the device (always XI)
+ * @param scount number of elements in store.
*/
static Bool
@@ -3375,7 +3360,9 @@ CheckPassiveGrabsOnWindow(
WindowPtr pWin,
DeviceIntPtr device,
xEvent *xE,
- int count)
+ int count,
+ xEvent *store,
+ int scount)
{
GrabPtr grab = wPassiveGrabs(pWin);
GrabRec tempGrab;
@@ -3494,17 +3481,18 @@ CheckPassiveGrabsOnWindow(
if (grabinfo->sync.state == FROZEN_NO_EVENT)
{
- if (grabinfo->sync.evcount < count)
+ if (grabinfo->sync.evcount < scount)
{
Must_have_memory = TRUE; /* XXX */
grabinfo->sync.event = (xEvent *)xrealloc(grabinfo->sync.event,
- count*
+ scount*
sizeof(xEvent));
Must_have_memory = FALSE; /* XXX */
}
- grabinfo->sync.evcount = count;
- for (dxE = grabinfo->sync.event; --count >= 0; dxE++, xE++)
- *dxE = *xE;
+ 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;
}
return TRUE;
@@ -3530,8 +3518,11 @@ CheckPassiveGrabsOnWindow(
*
* If a grab is activated, the event has been sent to the client already!
*
+ * The event we pass in must always be an XI event. From this, we then emulate
+ * the core event and then check for grabs.
+ *
* @param device The device that caused the event.
- * @param xE The event to handle (most likely {Device}ButtonPress).
+ * @param xE The event to handle (Device{Button|Key}Press).
* @param count Number of events in list.
* @return TRUE if a grab has been activated or false otherwise.
*/
@@ -3543,11 +3534,26 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
int i;
WindowPtr pWin = NULL;
FocusClassPtr focus = device->focus;
+ xEvent core;
+ BOOL sendCore = (device->isMaster && device->coreEvents);
- if (((xE->u.u.type == ButtonPress) || (xE->u.u.type == DeviceButtonPress))
+ if ((xE->u.u.type == DeviceButtonPress)
&& (device->button->buttonsDown != 1))
return FALSE;
+ if (xE->u.u.type < EXTENSION_EVENT_BASE)
+ {
+ ErrorF("[dix] Core event passed into CheckDeviceGrabs.\n");
+ return FALSE;
+ }
+
+
+ if (sendCore)
+ {
+ core = *xE;
+ core.u.u.type = XItoCoreType(xE->u.u.type);
+ }
+
i = checkFirst;
if (focus)
@@ -3555,8 +3561,11 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
for (; i < focus->traceGood; i++)
{
pWin = focus->trace[i];
+ /* XI grabs have precendence */
if (pWin->optional &&
- CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ (CheckPassiveGrabsOnWindow(pWin, device, xE, count, xE, count)
+ || (sendCore && CheckPassiveGrabsOnWindow(pWin, device, &core,
+ 1, xE, count))))
return TRUE;
}
@@ -3571,7 +3580,9 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
{
pWin = device->spriteInfo->sprite->spriteTrace[i];
if (pWin->optional &&
- CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ (CheckPassiveGrabsOnWindow(pWin, device, xE, count, xE, count) ||
+ (sendCore && CheckPassiveGrabsOnWindow(pWin, device, &core, 1,
+ xE, count))))
return TRUE;
}