/** * Compares two grabs and returns TRUE if the first grab matches the second * grab. * * A match is when * - the devices set for the grab are equal (this is optional). * - the event types for both grabs are equal. * - XXX * * @param ignoreDevice TRUE if the device settings on the grabs are to be * ignored. * @return TRUE if the grabs match or FALSE otherwise. */ Bool GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice) { unsigned int any_modifier = (pFirstGrab->grabtype == GRABTYPE_XI2) ? (unsigned int)XIAnyModifier : (unsigned int)AnyModifier; if (pFirstGrab->grabtype != pSecondGrab->grabtype) return FALSE; if (pFirstGrab->grabtype == GRABTYPE_XI2) { if (pFirstGrab->device == inputInfo.all_devices || pSecondGrab->device == inputInfo.all_devices) { /* do nothing */ } else if (pFirstGrab->device == inputInfo.all_master_devices) { if (pSecondGrab->device != inputInfo.all_master_devices && !IsMaster(pSecondGrab->device)) return FALSE; } else if (pSecondGrab->device == inputInfo.all_master_devices) { if (pFirstGrab->device != inputInfo.all_master_devices && !IsMaster(pFirstGrab->device)) return FALSE; } else if (pSecondGrab->device != pFirstGrab->device) return FALSE; } else if (!ignoreDevice && ((pFirstGrab->device != pSecondGrab->device) || (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice))) return FALSE; if (pFirstGrab->type != pSecondGrab->type) return FALSE; if (GrabSupersedesSecond(pFirstGrab, pSecondGrab) || GrabSupersedesSecond(pSecondGrab, pFirstGrab)) return TRUE; if (DetailSupersedesSecond(pSecondGrab->detail, pFirstGrab->detail, (unsigned int)AnyKey) && DetailSupersedesSecond(pFirstGrab->modifiersDetail, pSecondGrab->modifiersDetail, any_modifier)) return TRUE; if (DetailSupersedesSecond(pFirstGrab->detail, pSecondGrab->detail, (unsigned int)AnyKey) && DetailSupersedesSecond(pSecondGrab->modifiersDetail, pFirstGrab->modifiersDetail, any_modifier)) return TRUE; return FALSE; }
static Bool GrabMatchesSecond( register XtServerGrabPtr pFirstGrab, register XtServerGrabPtr pSecondGrab) { DetailRec firstD, firstM, secondD, secondM; if (pDisplay(pFirstGrab) != pDisplay(pSecondGrab)) return FALSE; if (GrabSupersedesSecond(pFirstGrab, pSecondGrab)) return TRUE; if (GrabSupersedesSecond(pSecondGrab, pFirstGrab)) return TRUE; firstD.exact = pFirstGrab->keybut; firstM.exact = pFirstGrab->modifiers; if (pFirstGrab->hasExt) { firstD.pMask = GRABEXT(pFirstGrab)->pKeyButMask; firstM.pMask = GRABEXT(pFirstGrab)->pModifiersMask; } else { firstD.pMask = NULL; firstM.pMask = NULL; } secondD.exact = pSecondGrab->keybut; secondM.exact = pSecondGrab->modifiers; if (pSecondGrab->hasExt) { secondD.pMask = GRABEXT(pSecondGrab)->pKeyButMask; secondM.pMask = GRABEXT(pSecondGrab)->pModifiersMask; } else { secondD.pMask = NULL; secondM.pMask = NULL; } if (DetailSupersedesSecond(&secondD, &firstD, (unsigned short)AnyKey) && DetailSupersedesSecond(&firstM, &secondM, (unsigned short)AnyModifier)) return TRUE; if (DetailSupersedesSecond(&firstD, &secondD, (unsigned short)AnyKey) && DetailSupersedesSecond(&secondM, &firstM, (unsigned short)AnyModifier)) return TRUE; return FALSE; }
Bool DeletePassiveGrabFromList(GrabPtr pMinuendGrab) { GrabPtr grab; GrabPtr *deletes, *adds; Mask ***updates, **details; int i, ndels, nadds, nups; Bool ok; unsigned int any_modifier; unsigned int any_key; #define UPDATE(mask,exact) \ if (!(details[nups] = DeleteDetailFromMask(mask, exact))) \ ok = FALSE; \ else \ updates[nups++] = &(mask) i = 0; for (grab = wPassiveGrabs(pMinuendGrab->window); grab; grab = grab->next) i++; if (!i) return TRUE; deletes = malloc(i * sizeof(GrabPtr)); adds = malloc(i * sizeof(GrabPtr)); updates = malloc(i * sizeof(Mask **)); details = malloc(i * sizeof(Mask *)); if (!deletes || !adds || !updates || !details) { free(details); free(updates); free(adds); free(deletes); return FALSE; } any_modifier = (pMinuendGrab->grabtype == XI2) ? (unsigned int) XIAnyModifier : (unsigned int) AnyModifier; any_key = (pMinuendGrab->grabtype == XI2) ? (unsigned int) XIAnyKeycode : (unsigned int) AnyKey; ndels = nadds = nups = 0; ok = TRUE; for (grab = wPassiveGrabs(pMinuendGrab->window); grab && ok; grab = grab->next) { if ((CLIENT_BITS(grab->resource) != CLIENT_BITS(pMinuendGrab->resource)) || !GrabMatchesSecond(grab, pMinuendGrab, (grab->grabtype == CORE))) continue; if (GrabSupersedesSecond(pMinuendGrab, grab)) { deletes[ndels++] = grab; } else if ((grab->detail.exact == any_key) && (grab->modifiersDetail.exact != any_modifier)) { UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact); } else if ((grab->modifiersDetail.exact == any_modifier) && (grab->detail.exact != any_key)) { UPDATE(grab->modifiersDetail.pMask, pMinuendGrab->modifiersDetail.exact); } else if ((pMinuendGrab->detail.exact != any_key) && (pMinuendGrab->modifiersDetail.exact != any_modifier)) { GrabPtr pNewGrab; GrabParameters param; UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact); memset(¶m, 0, sizeof(param)); param.ownerEvents = grab->ownerEvents; param.this_device_mode = grab->keyboardMode; param.other_devices_mode = grab->pointerMode; param.modifiers = any_modifier; pNewGrab = CreateGrab(CLIENT_ID(grab->resource), grab->device, grab->modifierDevice, grab->window, grab->grabtype, (GrabMask *) &grab->eventMask, ¶m, (int) grab->type, pMinuendGrab->detail.exact, grab->confineTo, grab->cursor); if (!pNewGrab) ok = FALSE; else if (!(pNewGrab->modifiersDetail.pMask = DeleteDetailFromMask(grab->modifiersDetail.pMask, pMinuendGrab->modifiersDetail. exact)) || (!pNewGrab->window->optional && !MakeWindowOptional(pNewGrab->window))) { FreeGrab(pNewGrab); ok = FALSE; } else if (!AddResource(pNewGrab->resource, RT_PASSIVEGRAB, (pointer) pNewGrab)) ok = FALSE; else adds[nadds++] = pNewGrab; } else if (pMinuendGrab->detail.exact == any_key) { UPDATE(grab->modifiersDetail.pMask, pMinuendGrab->modifiersDetail.exact); } else { UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact); } } if (!ok) { for (i = 0; i < nadds; i++) FreeResource(adds[i]->resource, RT_NONE); for (i = 0; i < nups; i++) free(details[i]); } else { for (i = 0; i < ndels; i++) FreeResource(deletes[i]->resource, RT_NONE); for (i = 0; i < nadds; i++) { grab = adds[i]; grab->next = grab->window->optional->passiveGrabs; grab->window->optional->passiveGrabs = grab; } for (i = 0; i < nups; i++) { free(*updates[i]); *updates[i] = details[i]; } } free(details); free(updates); free(adds); free(deletes); return ok; #undef UPDATE }
static void DeleteServerGrabFromList( XtServerGrabPtr *passiveListPtr, XtServerGrabPtr pMinuendGrab) { register XtServerGrabPtr *next; register XtServerGrabPtr grab; register XtServerGrabExtPtr ext; for (next = passiveListPtr; (grab = *next); ) { if (GrabMatchesSecond(grab, pMinuendGrab) && (pDisplay(grab) == pDisplay(pMinuendGrab))) { if (GrabSupersedesSecond(pMinuendGrab, grab)) { /* * The entry being deleted encompasses the list entry, * so delete the list entry. */ *next = grab->next; FreeGrab(grab); continue; } if (!grab->hasExt) { grab = (XtServerGrabPtr) XtRealloc((char *)grab, (sizeof(XtServerGrabRec) + sizeof(XtServerGrabExtRec))); *next = grab; grab->hasExt = True; ext = GRABEXT(grab); ext->pKeyButMask = NULL; ext->pModifiersMask = NULL; ext->confineTo = None; ext->cursor = None; } else ext = GRABEXT(grab); if ((grab->keybut == AnyKey) && (grab->modifiers != AnyModifier)) { /* * If the list entry has the key detail of AnyKey, and * a modifier detail not set to AnyModifier, then we * simply need to turn off the key detail bit in the * list entry's key detail mask. */ DeleteDetailFromMask(&ext->pKeyButMask, pMinuendGrab->keybut); } else if ((grab->modifiers == AnyModifier) && (grab->keybut != AnyKey)) { /* * The list entry has a specific key detail, but its * modifier detail is set to AnyModifier; so, we only * need to turn off the specified modifier combination * in the list entry's modifier mask. */ DeleteDetailFromMask(&ext->pModifiersMask, pMinuendGrab->modifiers); } else if ((pMinuendGrab->keybut != AnyKey) && (pMinuendGrab->modifiers != AnyModifier)) { /* * The list entry has a key detail of AnyKey and a * modifier detail of AnyModifier; the entry being * deleted has a specific key and a specific modifier * combination. Therefore, we need to mask off the * keycode from the list entry, and also create a * new entry for this keycode, which has a modifier * mask set to AnyModifier & ~(deleted modifiers). */ XtServerGrabPtr pNewGrab; DeleteDetailFromMask(&ext->pKeyButMask, pMinuendGrab->keybut); pNewGrab = CreateGrab(grab->widget, (Boolean)grab->ownerEvents, (Modifiers)AnyModifier, pMinuendGrab->keybut, (int)grab->pointerMode, (int)grab->keyboardMode, (Mask)0, (Window)0, (Cursor)0, True); GRABEXT(pNewGrab)->pModifiersMask = CopyDetailMask(ext->pModifiersMask); DeleteDetailFromMask(&GRABEXT(pNewGrab)->pModifiersMask, pMinuendGrab->modifiers); pNewGrab->next = *passiveListPtr; *passiveListPtr = pNewGrab; } else if (pMinuendGrab->keybut == AnyKey) { /* * The list entry has keycode AnyKey and modifier * AnyModifier; the entry being deleted has * keycode AnyKey and specific modifiers. So we * simply need to mask off the specified modifier * combination. */ DeleteDetailFromMask(&ext->pModifiersMask, pMinuendGrab->modifiers); } else { /* * The list entry has keycode AnyKey and modifier * AnyModifier; the entry being deleted has a * specific keycode and modifier AnyModifier. So * we simply need to mask off the specified * keycode. */ DeleteDetailFromMask(&ext->pKeyButMask, pMinuendGrab->keybut); } } next = &(*next)->next; } }