summaryrefslogtreecommitdiff
path: root/dix/grabs.c
diff options
context:
space:
mode:
Diffstat (limited to 'dix/grabs.c')
-rw-r--r--dix/grabs.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/dix/grabs.c b/dix/grabs.c
index 714fea3e5..2210cd05e 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -269,6 +269,42 @@ GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
return FALSE;
}
+static Bool
+GrabsAreIdentical(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
+{
+ if (pFirstGrab->device != pSecondGrab->device ||
+ (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice) ||
+ (pFirstGrab->type != pSecondGrab->type))
+ return FALSE;
+
+ if (!(DetailSupersedesSecond(pFirstGrab->detail,
+ pSecondGrab->detail,
+ (unsigned short)AnyKey) &&
+ DetailSupersedesSecond(pSecondGrab->detail,
+ pFirstGrab->detail,
+ (unsigned short)AnyKey)))
+ return FALSE;
+
+ if (!(DetailSupersedesSecond(pFirstGrab->modifiersDetail,
+ pSecondGrab->modifiersDetail,
+ (unsigned short)AnyModifier) &&
+ DetailSupersedesSecond(pSecondGrab->modifiersDetail,
+ pFirstGrab->modifiersDetail,
+ (unsigned short)AnyModifier)))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/**
+ * Prepend the new grab to the list of passive grabs on the window.
+ * Any previously existing grab that matches the new grab will be removed.
+ * Adding a new grab that would override another client's grab will result in
+ * a BadAccess.
+ *
+ * @return Success or X error code on failure.
+ */
int
AddPassiveGrabToList(GrabPtr pGrab)
{
@@ -286,11 +322,22 @@ AddPassiveGrabToList(GrabPtr pGrab)
}
}
+ /* Remove all grabs that match the new one exactly */
+ for (grab = wPassiveGrabs(pGrab->window); grab; grab = grab->next)
+ {
+ if (GrabsAreIdentical(pGrab, grab))
+ {
+ DeletePassiveGrabFromList(grab);
+ break;
+ }
+ }
+
if (!pGrab->window->optional && !MakeWindowOptional (pGrab->window))
{
FreeGrab(pGrab);
return BadAlloc;
}
+
pGrab->next = pGrab->window->optional->passiveGrabs;
pGrab->window->optional->passiveGrabs = pGrab;
if (AddResource(pGrab->resource, RT_PASSIVEGRAB, (pointer)pGrab))