/** * 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(ClientPtr client, GrabPtr pGrab) { GrabPtr grab; Mask access_mode = DixGrabAccess; int rc; for (grab = wPassiveGrabs(pGrab->window); grab; grab = grab->next) { if (GrabMatchesSecond(pGrab, grab, FALSE)) { if (CLIENT_BITS(pGrab->resource) != CLIENT_BITS(grab->resource)) { FreeGrab(pGrab); return BadAccess; } } } if (pGrab->keyboardMode == GrabModeSync||pGrab->pointerMode == GrabModeSync) access_mode |= DixFreezeAccess; rc = XaceHook(XACE_DEVICE_ACCESS, client, pGrab->device, access_mode); if (rc != Success) return rc; /* 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)) return Success; return BadAlloc; }
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 }
int ProcXFixesSetWindowShapeRegion (ClientPtr client) { #ifdef SHAPE WindowPtr pWin; ScreenPtr pScreen; RegionPtr pRegion; RegionPtr *pDestRegion; REQUEST(xXFixesSetWindowShapeRegionReq); REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); pWin = (WindowPtr) LookupIDByType (stuff->dest, RT_WINDOW); if (!pWin) { client->errorValue = stuff->dest; return BadWindow; } VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixWriteAccess); pScreen = pWin->drawable.pScreen; switch (stuff->destKind) { case ShapeBounding: case ShapeClip: case ShapeInput: break; default: client->errorValue = stuff->destKind; return BadValue; } if (pRegion) { pRegion = XFixesRegionCopy (pRegion); if (!pRegion) return BadAlloc; if (!pWin->optional) MakeWindowOptional (pWin); switch (stuff->destKind) { default: case ShapeBounding: pDestRegion = &pWin->optional->boundingShape; break; case ShapeClip: pDestRegion = &pWin->optional->clipShape; break; case ShapeInput: pDestRegion = &pWin->optional->inputShape; break; } if (stuff->xOff || stuff->yOff) REGION_TRANSLATE (0, pRegion, stuff->xOff, stuff->yOff); } else { if (pWin->optional) { switch (stuff->destKind) { default: case ShapeBounding: pDestRegion = &pWin->optional->boundingShape; break; case ShapeClip: pDestRegion = &pWin->optional->clipShape; break; case ShapeInput: pDestRegion = &pWin->optional->inputShape; break; } } else pDestRegion = &pRegion; /* a NULL region pointer */ } if (*pDestRegion) REGION_DESTROY(pScreen, *pDestRegion); *pDestRegion = pRegion; (*pScreen->SetShape) (pWin); SendShapeNotify (pWin, stuff->destKind); return (client->noClientException); #else return BadRequest; #endif }
int ProcXFixesSetWindowShapeRegion(ClientPtr client) { WindowPtr pWin; RegionPtr pRegion; RegionPtr *pDestRegion; int rc; REQUEST(xXFixesSetWindowShapeRegionReq); REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); rc = dixLookupResourceByType((void **) &pWin, stuff->dest, RT_WINDOW, client, DixSetAttrAccess); if (rc != Success) { client->errorValue = stuff->dest; return rc; } VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixWriteAccess); switch (stuff->destKind) { case ShapeBounding: case ShapeClip: case ShapeInput: break; default: client->errorValue = stuff->destKind; return BadValue; } if (pRegion) { pRegion = XFixesRegionCopy(pRegion); if (!pRegion) return BadAlloc; if (!pWin->optional) MakeWindowOptional(pWin); switch (stuff->destKind) { default: case ShapeBounding: pDestRegion = &pWin->optional->boundingShape; break; case ShapeClip: pDestRegion = &pWin->optional->clipShape; break; case ShapeInput: pDestRegion = &pWin->optional->inputShape; break; } if (stuff->xOff || stuff->yOff) RegionTranslate(pRegion, stuff->xOff, stuff->yOff); } else { if (pWin->optional) { switch (stuff->destKind) { default: case ShapeBounding: pDestRegion = &pWin->optional->boundingShape; break; case ShapeClip: pDestRegion = &pWin->optional->clipShape; break; case ShapeInput: pDestRegion = &pWin->optional->inputShape; break; } } else pDestRegion = &pRegion; /* a NULL region pointer */ } if (*pDestRegion) RegionDestroy(*pDestRegion); *pDestRegion = pRegion; (*pWin->drawable.pScreen->SetShape) (pWin, stuff->destKind); SendShapeNotify(pWin, stuff->destKind); return Success; }
static int ProcShapeCombine(ClientPtr client) { WindowPtr pSrcWin, pDestWin; REQUEST(xShapeCombineReq); RegionPtr srcRgn; RegionPtr *destRgn; CreateDftPtr createDefault; CreateDftPtr createSrc; RegionPtr tmp; int rc; REQUEST_SIZE_MATCH(xShapeCombineReq); UpdateCurrentTime(); rc = dixLookupWindow(&pDestWin, stuff->dest, client, DixSetAttrAccess); if (rc != Success) return rc; if (!pDestWin->optional) MakeWindowOptional(pDestWin); switch (stuff->destKind) { case ShapeBounding: createDefault = CreateBoundingShape; break; case ShapeClip: createDefault = CreateClipShape; break; case ShapeInput: createDefault = CreateBoundingShape; break; default: client->errorValue = stuff->destKind; return BadValue; } rc = dixLookupWindow(&pSrcWin, stuff->src, client, DixGetAttrAccess); if (rc != Success) return rc; switch (stuff->srcKind) { case ShapeBounding: srcRgn = wBoundingShape(pSrcWin); createSrc = CreateBoundingShape; break; case ShapeClip: srcRgn = wClipShape(pSrcWin); createSrc = CreateClipShape; break; case ShapeInput: srcRgn = wInputShape(pSrcWin); createSrc = CreateBoundingShape; break; default: client->errorValue = stuff->srcKind; return BadValue; } if (pSrcWin->drawable.pScreen != pDestWin->drawable.pScreen) { return BadMatch; } if (srcRgn) { tmp = RegionCreate((BoxPtr) 0, 0); RegionCopy(tmp, srcRgn); srcRgn = tmp; } else srcRgn = (*createSrc) (pSrcWin); if (!pDestWin->optional) MakeWindowOptional(pDestWin); switch (stuff->destKind) { case ShapeBounding: destRgn = &pDestWin->optional->boundingShape; break; case ShapeClip: destRgn = &pDestWin->optional->clipShape; break; case ShapeInput: destRgn = &pDestWin->optional->inputShape; break; default: return BadValue; } return RegionOperate(client, pDestWin, (int) stuff->destKind, destRgn, srcRgn, (int) stuff->op, stuff->xOff, stuff->yOff, createDefault); }
static int ProcShapeMask(ClientPtr client) { WindowPtr pWin; ScreenPtr pScreen; REQUEST(xShapeMaskReq); RegionPtr srcRgn; RegionPtr *destRgn; PixmapPtr pPixmap; CreateDftPtr createDefault; int rc; REQUEST_SIZE_MATCH(xShapeMaskReq); UpdateCurrentTime(); rc = dixLookupWindow(&pWin, stuff->dest, client, DixSetAttrAccess); if (rc != Success) return rc; switch (stuff->destKind) { case ShapeBounding: createDefault = CreateBoundingShape; break; case ShapeClip: createDefault = CreateClipShape; break; case ShapeInput: createDefault = CreateBoundingShape; break; default: client->errorValue = stuff->destKind; return BadValue; } pScreen = pWin->drawable.pScreen; if (stuff->src == None) srcRgn = 0; else { rc = dixLookupResourceByType((pointer *) &pPixmap, stuff->src, RT_PIXMAP, client, DixReadAccess); if (rc != Success) return rc; if (pPixmap->drawable.pScreen != pScreen || pPixmap->drawable.depth != 1) return BadMatch; srcRgn = BitmapToRegion(pScreen, pPixmap); if (!srcRgn) return BadAlloc; } if (!pWin->optional) MakeWindowOptional(pWin); switch (stuff->destKind) { case ShapeBounding: destRgn = &pWin->optional->boundingShape; break; case ShapeClip: destRgn = &pWin->optional->clipShape; break; case ShapeInput: destRgn = &pWin->optional->inputShape; break; default: return BadValue; } return RegionOperate(client, pWin, (int) stuff->destKind, destRgn, srcRgn, (int) stuff->op, stuff->xOff, stuff->yOff, createDefault); }
static int ProcShapeRectangles(ClientPtr client) { WindowPtr pWin; REQUEST(xShapeRectanglesReq); xRectangle *prects; int nrects, ctype, rc; RegionPtr srcRgn; RegionPtr *destRgn; CreateDftPtr createDefault; REQUEST_AT_LEAST_SIZE(xShapeRectanglesReq); UpdateCurrentTime(); rc = dixLookupWindow(&pWin, stuff->dest, client, DixSetAttrAccess); if (rc != Success) return rc; switch (stuff->destKind) { case ShapeBounding: createDefault = CreateBoundingShape; break; case ShapeClip: createDefault = CreateClipShape; break; case ShapeInput: createDefault = CreateBoundingShape; break; default: client->errorValue = stuff->destKind; return BadValue; } if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) && (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) { client->errorValue = stuff->ordering; return BadValue; } nrects = ((stuff->length << 2) - sizeof(xShapeRectanglesReq)); if (nrects & 4) return BadLength; nrects >>= 3; prects = (xRectangle *) &stuff[1]; ctype = VerifyRectOrder(nrects, prects, (int) stuff->ordering); if (ctype < 0) return BadMatch; srcRgn = RegionFromRects(nrects, prects, ctype); if (!pWin->optional) MakeWindowOptional(pWin); switch (stuff->destKind) { case ShapeBounding: destRgn = &pWin->optional->boundingShape; break; case ShapeClip: destRgn = &pWin->optional->clipShape; break; case ShapeInput: destRgn = &pWin->optional->inputShape; break; default: return BadValue; } return RegionOperate(client, pWin, (int) stuff->destKind, destRgn, srcRgn, (int) stuff->op, stuff->xOff, stuff->yOff, createDefault); }