Esempio n. 1
0
/**
 * 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;
}
Esempio n. 2
0
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(&param, 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,
                                  &param, (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
}
Esempio n. 3
0
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
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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);
}