diff options
author | Peter Hutterer <peter@cs.unisa.edu.au> | 2007-06-13 15:26:03 +0930 |
---|---|---|
committer | Peter Hutterer <peter@cs.unisa.edu.au> | 2007-06-25 09:35:30 +0930 |
commit | b141b85c254afff3ce2221d899787fab3dc295bd (patch) | |
tree | fe97343cc118a27b07b39f62a12a5781ec8bd829 | |
parent | 19cde59c41cf167cc609debfee75bfc015beac12 (diff) |
Check for identical grabs when adding a new passive grab. If an identical grab
exists, remove the old one and prepend the new one.
X.org Bug 2738 <https://bugs.freedesktop.org/show_bug.cgi?id=2738>
-rw-r--r-- | dix/grabs.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/dix/grabs.c b/dix/grabs.c index 714fea3e5..cecd7ec39 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) { @@ -291,6 +327,17 @@ AddPassiveGrabToList(GrabPtr pGrab) FreeGrab(pGrab); return BadAlloc; } + + /* 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; + } + } + pGrab->next = pGrab->window->optional->passiveGrabs; pGrab->window->optional->passiveGrabs = pGrab; if (AddResource(pGrab->resource, RT_PASSIVEGRAB, (pointer)pGrab)) |