diff options
author | Peter Hutterer <peter@cs.unisa.edu.au> | 2007-08-12 15:31:10 +0930 |
---|---|---|
committer | Peter Hutterer <peter@cs.unisa.edu.au> | 2007-08-12 15:31:10 +0930 |
commit | f367285fd5825e0adc271982a529c9904ad65c89 (patch) | |
tree | 4e7081da773c51cc9448cefe17c2c3639f33ad6d /dix/grabs.c | |
parent | b1272eefd9a3e340d65c14903f337747ec82d021 (diff) | |
parent | ff4bd3addb48df3eacc4b121cc249a7f38eb981a (diff) |
Merge branch 'master' into mpx
Conflicts:
Xi/exevents.c
dix/devices.c
dix/getevents.c
include/dix.h
mi/mieq.c
Diffstat (limited to 'dix/grabs.c')
-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 01f4b6439..f1d00867e 100644 --- a/dix/grabs.c +++ b/dix/grabs.c @@ -287,6 +287,42 @@ GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice) 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) { @@ -304,11 +340,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)) |