From 4b4ee0dc63abddffdc64355429e4ea9ccaa4d36d Mon Sep 17 00:00:00 2001 From: marha Date: Sun, 9 May 2010 21:30:23 +0000 Subject: svn merge -r577:HEAD ^/branches/released . --- xorg-server/xfixes/region.c | 1712 +++++++++++++++++++++---------------------- 1 file changed, 855 insertions(+), 857 deletions(-) (limited to 'xorg-server/xfixes/region.c') diff --git a/xorg-server/xfixes/region.c b/xorg-server/xfixes/region.c index 795caf013..dc050c9fc 100644 --- a/xorg-server/xfixes/region.c +++ b/xorg-server/xfixes/region.c @@ -1,857 +1,855 @@ -/* - * Copyright © 2003 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "xfixesint.h" -#include "scrnintstr.h" -#include -extern int RenderErrBase; -#include -#include -#include - -RESTYPE RegionResType; - -static int -RegionResFree (pointer data, XID id) -{ - RegionPtr pRegion = (RegionPtr) data; - - REGION_DESTROY (0, pRegion); - return Success; -} - -RegionPtr -XFixesRegionCopy (RegionPtr pRegion) -{ - RegionPtr pNew = REGION_CREATE (0, REGION_EXTENTS(0, pRegion), - REGION_NUM_RECTS(pRegion)); - if (!pNew) - return 0; - if (!REGION_COPY (0, pNew, pRegion)) - { - REGION_DESTROY (0, pNew); - return 0; - } - return pNew; -} - -Bool -XFixesRegionInit (void) -{ - RegionResType = CreateNewResourceType(RegionResFree, "XFixesRegion"); - - return (RegionResType != 0); -} - -int -ProcXFixesCreateRegion (ClientPtr client) -{ - int things; - RegionPtr pRegion; - REQUEST (xXFixesCreateRegionReq); - - REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq); - LEGAL_NEW_RESOURCE (stuff->region, client); - - things = (client->req_len << 2) - sizeof (xXFixesCreateRegionReq); - if (things & 4) - return BadLength; - things >>= 3; - - pRegion = RECTS_TO_REGION(0, things, (xRectangle *) (stuff + 1), CT_UNSORTED); - if (!pRegion) - return BadAlloc; - if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) - return BadAlloc; - - return(client->noClientException); -} - -int -SProcXFixesCreateRegion (ClientPtr client) -{ - register int n; - REQUEST(xXFixesCreateRegionReq); - - swaps(&stuff->length, n); - REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq); - swapl(&stuff->region, n); - SwapRestS(stuff); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesCreateRegionFromBitmap (ClientPtr client) -{ - RegionPtr pRegion; - PixmapPtr pPixmap; - int rc; - REQUEST (xXFixesCreateRegionFromBitmapReq); - - REQUEST_SIZE_MATCH (xXFixesCreateRegionFromBitmapReq); - LEGAL_NEW_RESOURCE (stuff->region, client); - - rc = dixLookupResourceByType((pointer *)&pPixmap, stuff->bitmap, RT_PIXMAP, - client, DixReadAccess); - if (rc != Success) - { - client->errorValue = stuff->bitmap; - return (rc == BadValue) ? BadPixmap : rc; - } - if (pPixmap->drawable.depth != 1) - return BadMatch; - - pRegion = BITMAP_TO_REGION(pPixmap->drawable.pScreen, pPixmap); - - if (!pRegion) - return BadAlloc; - - if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) - return BadAlloc; - - return(client->noClientException); -} - -int -SProcXFixesCreateRegionFromBitmap (ClientPtr client) -{ - int n; - REQUEST (xXFixesCreateRegionFromBitmapReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH (xXFixesCreateRegionFromBitmapReq); - swapl(&stuff->region, n); - swapl(&stuff->bitmap, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesCreateRegionFromWindow (ClientPtr client) -{ - RegionPtr pRegion; - Bool copy = TRUE; - WindowPtr pWin; - int rc; - REQUEST (xXFixesCreateRegionFromWindowReq); - - REQUEST_SIZE_MATCH (xXFixesCreateRegionFromWindowReq); - LEGAL_NEW_RESOURCE (stuff->region, client); - rc = dixLookupResourceByType((pointer *)&pWin, stuff->window, RT_WINDOW, - client, DixGetAttrAccess); - if (rc != Success) - { - client->errorValue = stuff->window; - return (rc == BadValue) ? BadWindow : rc; - } - switch (stuff->kind) { - case WindowRegionBounding: - pRegion = wBoundingShape(pWin); - if (!pRegion) - { - pRegion = CreateBoundingShape (pWin); - copy = FALSE; - } - break; - case WindowRegionClip: - pRegion = wClipShape(pWin); - if (!pRegion) - { - pRegion = CreateClipShape (pWin); - copy = FALSE; - } - break; - default: - client->errorValue = stuff->kind; - return BadValue; - } - if (copy && pRegion) - pRegion = XFixesRegionCopy (pRegion); - if (!pRegion) - return BadAlloc; - if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) - return BadAlloc; - - return(client->noClientException); -} - -int -SProcXFixesCreateRegionFromWindow (ClientPtr client) -{ - int n; - REQUEST (xXFixesCreateRegionFromWindowReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH (xXFixesCreateRegionFromWindowReq); - swapl(&stuff->region, n); - swapl(&stuff->window, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesCreateRegionFromGC (ClientPtr client) -{ - RegionPtr pRegion, pClip; - GCPtr pGC; - int rc; - REQUEST (xXFixesCreateRegionFromGCReq); - - REQUEST_SIZE_MATCH (xXFixesCreateRegionFromGCReq); - LEGAL_NEW_RESOURCE (stuff->region, client); - - rc = dixLookupGC(&pGC, stuff->gc, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - switch (pGC->clientClipType) { - case CT_PIXMAP: - pRegion = BITMAP_TO_REGION(pGC->pScreen, (PixmapPtr) pGC->clientClip); - if (!pRegion) - return BadAlloc; - break; - case CT_REGION: - pClip = (RegionPtr) pGC->clientClip; - pRegion = XFixesRegionCopy (pClip); - if (!pRegion) - return BadAlloc; - break; - default: - return BadImplementation; /* assume sane server bits */ - } - - if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) - return BadAlloc; - - return(client->noClientException); -} - -int -SProcXFixesCreateRegionFromGC (ClientPtr client) -{ - int n; - REQUEST (xXFixesCreateRegionFromGCReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH (xXFixesCreateRegionFromGCReq); - swapl(&stuff->region, n); - swapl(&stuff->gc, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesCreateRegionFromPicture (ClientPtr client) -{ - RegionPtr pRegion; - PicturePtr pPicture; - REQUEST (xXFixesCreateRegionFromPictureReq); - - REQUEST_SIZE_MATCH (xXFixesCreateRegionFromPictureReq); - LEGAL_NEW_RESOURCE (stuff->region, client); - - VERIFY_PICTURE(pPicture, stuff->picture, client, DixGetAttrAccess, - RenderErrBase + BadPicture); - - switch (pPicture->clientClipType) { - case CT_PIXMAP: - pRegion = BITMAP_TO_REGION(pPicture->pDrawable->pScreen, - (PixmapPtr) pPicture->clientClip); - if (!pRegion) - return BadAlloc; - break; - case CT_REGION: - pRegion = XFixesRegionCopy ((RegionPtr) pPicture->clientClip); - if (!pRegion) - return BadAlloc; - break; - default: - return BadImplementation; /* assume sane server bits */ - } - - if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) - return BadAlloc; - - return(client->noClientException); -} - -int -SProcXFixesCreateRegionFromPicture (ClientPtr client) -{ - int n; - REQUEST (xXFixesCreateRegionFromPictureReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH (xXFixesCreateRegionFromPictureReq); - swapl(&stuff->region, n); - swapl(&stuff->picture, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesDestroyRegion (ClientPtr client) -{ - REQUEST (xXFixesDestroyRegionReq); - RegionPtr pRegion; - - REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq); - VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); - FreeResource (stuff->region, RT_NONE); - return(client->noClientException); -} - -int -SProcXFixesDestroyRegion (ClientPtr client) -{ - int n; - REQUEST (xXFixesDestroyRegionReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq); - swapl (&stuff->region, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesSetRegion (ClientPtr client) -{ - int things; - RegionPtr pRegion, pNew; - REQUEST (xXFixesSetRegionReq); - - REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq); - VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); - - things = (client->req_len << 2) - sizeof (xXFixesCreateRegionReq); - if (things & 4) - return BadLength; - things >>= 3; - - pNew = RECTS_TO_REGION(0, things, (xRectangle *) (stuff + 1), CT_UNSORTED); - if (!pNew) - return BadAlloc; - if (!REGION_COPY (0, pRegion, pNew)) - { - REGION_DESTROY (0, pNew); - return BadAlloc; - } - REGION_DESTROY (0, pNew); - return(client->noClientException); -} - -int -SProcXFixesSetRegion (ClientPtr client) -{ - int n; - REQUEST (xXFixesSetRegionReq); - - swaps (&stuff->length, n); - REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq); - swapl (&stuff->region, n); - SwapRestS(stuff); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesCopyRegion (ClientPtr client) -{ - RegionPtr pSource, pDestination; - REQUEST (xXFixesCopyRegionReq); - - VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); - VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); - - if (!REGION_COPY(pScreen, pDestination, pSource)) - return BadAlloc; - - return(client->noClientException); -} - -int -SProcXFixesCopyRegion (ClientPtr client) -{ - int n; - REQUEST (xXFixesCopyRegionReq); - - swaps (&stuff->length, n); - REQUEST_AT_LEAST_SIZE(xXFixesCopyRegionReq); - swapl (&stuff->source, n); - swapl (&stuff->destination, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesCombineRegion (ClientPtr client) -{ - RegionPtr pSource1, pSource2, pDestination; - int ret = Success; - REQUEST (xXFixesCombineRegionReq); - - REQUEST_SIZE_MATCH (xXFixesCombineRegionReq); - VERIFY_REGION(pSource1, stuff->source1, client, DixReadAccess); - VERIFY_REGION(pSource2, stuff->source2, client, DixReadAccess); - VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); - - switch (stuff->xfixesReqType) { - case X_XFixesUnionRegion: - if (!REGION_UNION (0, pDestination, pSource1, pSource2)) - ret = BadAlloc; - break; - case X_XFixesIntersectRegion: - if (!REGION_INTERSECT (0, pDestination, pSource1, pSource2)) - ret = BadAlloc; - break; - case X_XFixesSubtractRegion: - if (!REGION_SUBTRACT (0, pDestination, pSource1, pSource2)) - ret = BadAlloc; - break; - } - - if (ret == Success) - ret = client->noClientException; - return ret; -} - -int -SProcXFixesCombineRegion (ClientPtr client) -{ - int n; - REQUEST (xXFixesCombineRegionReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH (xXFixesCombineRegionReq); - swapl (&stuff->source1, n); - swapl (&stuff->source2, n); - swapl (&stuff->destination, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesInvertRegion (ClientPtr client) -{ - RegionPtr pSource, pDestination; - BoxRec bounds; - int ret = Success; - REQUEST(xXFixesInvertRegionReq); - - REQUEST_SIZE_MATCH(xXFixesInvertRegionReq); - VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); - VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); - - /* Compute bounds, limit to 16 bits */ - bounds.x1 = stuff->x; - bounds.y1 = stuff->y; - if ((int) stuff->x + (int) stuff->width > MAXSHORT) - bounds.x2 = MAXSHORT; - else - bounds.x2 = stuff->x + stuff->width; - - if ((int) stuff->y + (int) stuff->height > MAXSHORT) - bounds.y2 = MAXSHORT; - else - bounds.y2 = stuff->y + stuff->height; - - if (!REGION_INVERSE(0, pDestination, pSource, &bounds)) - ret = BadAlloc; - - if (ret == Success) - ret = client->noClientException; - return ret; -} - -int -SProcXFixesInvertRegion (ClientPtr client) -{ - int n; - REQUEST(xXFixesInvertRegionReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXFixesInvertRegionReq); - swapl (&stuff->source, n); - swaps (&stuff->x, n); - swaps (&stuff->y, n); - swaps (&stuff->width, n); - swaps (&stuff->height, n); - swapl (&stuff->destination, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesTranslateRegion (ClientPtr client) -{ - RegionPtr pRegion; - REQUEST(xXFixesTranslateRegionReq); - - REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq); - VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); - - REGION_TRANSLATE(pScreen, pRegion, stuff->dx, stuff->dy); - return (client->noClientException); -} - -int -SProcXFixesTranslateRegion (ClientPtr client) -{ - int n; - REQUEST(xXFixesTranslateRegionReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq); - swapl (&stuff->region, n); - swaps (&stuff->dx, n); - swaps (&stuff->dy, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesRegionExtents (ClientPtr client) -{ - RegionPtr pSource, pDestination; - REQUEST(xXFixesRegionExtentsReq); - - REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq); - VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); - VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); - - REGION_RESET (0, pDestination, REGION_EXTENTS (0, pSource)); - - return (client->noClientException); -} - -int -SProcXFixesRegionExtents (ClientPtr client) -{ - int n; - REQUEST(xXFixesRegionExtentsReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq); - swapl (&stuff->source, n); - swapl (&stuff->destination, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesFetchRegion (ClientPtr client) -{ - RegionPtr pRegion; - xXFixesFetchRegionReply *reply; - xRectangle *pRect; - BoxPtr pExtent; - BoxPtr pBox; - int i, nBox; - REQUEST(xXFixesFetchRegionReq); - - REQUEST_SIZE_MATCH(xXFixesFetchRegionReq); - VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess); - - pExtent = REGION_EXTENTS (0, pRegion); - pBox = REGION_RECTS (pRegion); - nBox = REGION_NUM_RECTS (pRegion); - - reply = xalloc (sizeof (xXFixesFetchRegionReply) + - nBox * sizeof (xRectangle)); - if (!reply) - return BadAlloc; - reply->type = X_Reply; - reply->sequenceNumber = client->sequence; - reply->length = nBox << 1; - reply->x = pExtent->x1; - reply->y = pExtent->y1; - reply->width = pExtent->x2 - pExtent->x1; - reply->height = pExtent->y2 - pExtent->y1; - - pRect = (xRectangle *) (reply + 1); - for (i = 0; i < nBox; i++) - { - pRect[i].x = pBox[i].x1; - pRect[i].y = pBox[i].y1; - pRect[i].width = pBox[i].x2 - pBox[i].x1; - pRect[i].height = pBox[i].y2 - pBox[i].y1; - } - if (client->swapped) - { - int n; - swaps (&reply->sequenceNumber, n); - swapl (&reply->length, n); - swaps (&reply->x, n); - swaps (&reply->y, n); - swaps (&reply->width, n); - swaps (&reply->height, n); - SwapShorts ((INT16 *) pRect, nBox * 4); - } - (void) WriteToClient(client, sizeof (xXFixesFetchRegionReply) + - nBox * sizeof (xRectangle), (char *) reply); - xfree (reply); - return (client->noClientException); -} - -int -SProcXFixesFetchRegion (ClientPtr client) -{ - int n; - REQUEST(xXFixesFetchRegionReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXFixesFetchRegionReq); - swapl (&stuff->region, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesSetGCClipRegion (ClientPtr client) -{ - GCPtr pGC; - RegionPtr pRegion; - XID vals[2]; - int rc; - REQUEST(xXFixesSetGCClipRegionReq); - REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); - - rc = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); - if (rc != Success) - return rc; - - VERIFY_REGION_OR_NONE (pRegion, stuff->region, client, DixReadAccess); - - if (pRegion) - { - pRegion = XFixesRegionCopy (pRegion); - if (!pRegion) - return BadAlloc; - } - - vals[0] = stuff->xOrigin; - vals[1] = stuff->yOrigin; - DoChangeGC (pGC, GCClipXOrigin|GCClipYOrigin, vals, 0); - (*pGC->funcs->ChangeClip)(pGC, pRegion ? CT_REGION : CT_NONE, (pointer)pRegion, 0); - - return (client->noClientException); -} - -int -SProcXFixesSetGCClipRegion (ClientPtr client) -{ - int n; - REQUEST(xXFixesSetGCClipRegionReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); - swapl (&stuff->gc, n); - swapl (&stuff->region, n); - swaps (&stuff->xOrigin, n); - swaps (&stuff->yOrigin, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -typedef RegionPtr (*CreateDftPtr)(WindowPtr pWin); - -int -ProcXFixesSetWindowShapeRegion (ClientPtr client) -{ - WindowPtr pWin; - ScreenPtr pScreen; - RegionPtr pRegion; - RegionPtr *pDestRegion; - int rc; - REQUEST(xXFixesSetWindowShapeRegionReq); - - REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); - rc = dixLookupResourceByType((pointer *)&pWin, stuff->dest, RT_WINDOW, - client, DixSetAttrAccess); - if (rc != Success) - { - client->errorValue = stuff->dest; - return (rc == BadValue) ? BadWindow : rc; - } - 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); -} - -int -SProcXFixesSetWindowShapeRegion (ClientPtr client) -{ - int n; - REQUEST(xXFixesSetWindowShapeRegionReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); - swapl (&stuff->dest, n); - swaps (&stuff->xOff, n); - swaps (&stuff->yOff, n); - swapl (&stuff->region, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesSetPictureClipRegion (ClientPtr client) -{ - PicturePtr pPicture; - RegionPtr pRegion; - ScreenPtr pScreen; - PictureScreenPtr ps; - REQUEST(xXFixesSetPictureClipRegionReq); - - REQUEST_SIZE_MATCH (xXFixesSetPictureClipRegionReq); - VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess, - RenderErrBase + BadPicture); - pScreen = pPicture->pDrawable->pScreen; - ps = GetPictureScreen (pScreen); - VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess); - - return SetPictureClipRegion (pPicture, stuff->xOrigin, stuff->yOrigin, - pRegion); -} - -int -SProcXFixesSetPictureClipRegion (ClientPtr client) -{ - int n; - REQUEST(xXFixesSetPictureClipRegionReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH (xXFixesSetPictureClipRegionReq); - swapl (&stuff->picture, n); - swapl (&stuff->region, n); - swaps (&stuff->xOrigin, n); - swaps (&stuff->yOrigin, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesExpandRegion (ClientPtr client) -{ - RegionPtr pSource, pDestination; - int ret = Success; - REQUEST (xXFixesExpandRegionReq); - BoxPtr pTmp; - BoxPtr pSrc; - int nBoxes; - int i; - - REQUEST_SIZE_MATCH (xXFixesExpandRegionReq); - VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); - VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); - - nBoxes = REGION_NUM_RECTS(pSource); - pSrc = REGION_RECTS(pSource); - if (nBoxes) - { - pTmp = xalloc (nBoxes * sizeof (BoxRec)); - if (!pTmp) - return BadAlloc; - for (i = 0; i < nBoxes; i++) - { - pTmp[i].x1 = pSrc[i].x1 - stuff->left; - pTmp[i].x2 = pSrc[i].x2 + stuff->right; - pTmp[i].y1 = pSrc[i].y1 - stuff->top; - pTmp[i].y2 = pSrc[i].y2 + stuff->bottom; - } - REGION_EMPTY (pScreen, pDestination); - for (i = 0; i < nBoxes; i++) - { - RegionRec r; - REGION_INIT (pScreen, &r, &pTmp[i], 0); - REGION_UNION (pScreen, pDestination, pDestination, &r); - } - xfree(pTmp); - } - if (ret == Success) - ret = client->noClientException; - return ret; -} - -int -SProcXFixesExpandRegion (ClientPtr client) -{ - int n; - REQUEST (xXFixesExpandRegionReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH (xXFixesExpandRegionReq); - swapl (&stuff->source, n); - swapl (&stuff->destination, n); - swaps (&stuff->left, n); - swaps (&stuff->right, n); - swaps (&stuff->top, n); - swaps (&stuff->bottom, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - +/* + * Copyright © 2003 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "xfixesint.h" +#include "scrnintstr.h" +#include +extern int RenderErrBase; +#include +#include +#include + +RESTYPE RegionResType; + +static int +RegionResFree (pointer data, XID id) +{ + RegionPtr pRegion = (RegionPtr) data; + + REGION_DESTROY (0, pRegion); + return Success; +} + +RegionPtr +XFixesRegionCopy (RegionPtr pRegion) +{ + RegionPtr pNew = REGION_CREATE (0, REGION_EXTENTS(0, pRegion), + REGION_NUM_RECTS(pRegion)); + if (!pNew) + return 0; + if (!REGION_COPY (0, pNew, pRegion)) + { + REGION_DESTROY (0, pNew); + return 0; + } + return pNew; +} + +Bool +XFixesRegionInit (void) +{ + RegionResType = CreateNewResourceType(RegionResFree, "XFixesRegion"); + + return (RegionResType != 0); +} + +int +ProcXFixesCreateRegion (ClientPtr client) +{ + int things; + RegionPtr pRegion; + REQUEST (xXFixesCreateRegionReq); + + REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq); + LEGAL_NEW_RESOURCE (stuff->region, client); + + things = (client->req_len << 2) - sizeof (xXFixesCreateRegionReq); + if (things & 4) + return BadLength; + things >>= 3; + + pRegion = RECTS_TO_REGION(0, things, (xRectangle *) (stuff + 1), CT_UNSORTED); + if (!pRegion) + return BadAlloc; + if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) + return BadAlloc; + + return(client->noClientException); +} + +int +SProcXFixesCreateRegion (ClientPtr client) +{ + register int n; + REQUEST(xXFixesCreateRegionReq); + + swaps(&stuff->length, n); + REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq); + swapl(&stuff->region, n); + SwapRestS(stuff); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesCreateRegionFromBitmap (ClientPtr client) +{ + RegionPtr pRegion; + PixmapPtr pPixmap; + int rc; + REQUEST (xXFixesCreateRegionFromBitmapReq); + + REQUEST_SIZE_MATCH (xXFixesCreateRegionFromBitmapReq); + LEGAL_NEW_RESOURCE (stuff->region, client); + + rc = dixLookupResourceByType((pointer *)&pPixmap, stuff->bitmap, RT_PIXMAP, + client, DixReadAccess); + if (rc != Success) + { + client->errorValue = stuff->bitmap; + return (rc == BadValue) ? BadPixmap : rc; + } + if (pPixmap->drawable.depth != 1) + return BadMatch; + + pRegion = BITMAP_TO_REGION(pPixmap->drawable.pScreen, pPixmap); + + if (!pRegion) + return BadAlloc; + + if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) + return BadAlloc; + + return(client->noClientException); +} + +int +SProcXFixesCreateRegionFromBitmap (ClientPtr client) +{ + int n; + REQUEST (xXFixesCreateRegionFromBitmapReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH (xXFixesCreateRegionFromBitmapReq); + swapl(&stuff->region, n); + swapl(&stuff->bitmap, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesCreateRegionFromWindow (ClientPtr client) +{ + RegionPtr pRegion; + Bool copy = TRUE; + WindowPtr pWin; + int rc; + REQUEST (xXFixesCreateRegionFromWindowReq); + + REQUEST_SIZE_MATCH (xXFixesCreateRegionFromWindowReq); + LEGAL_NEW_RESOURCE (stuff->region, client); + rc = dixLookupResourceByType((pointer *)&pWin, stuff->window, RT_WINDOW, + client, DixGetAttrAccess); + if (rc != Success) + { + client->errorValue = stuff->window; + return (rc == BadValue) ? BadWindow : rc; + } + switch (stuff->kind) { + case WindowRegionBounding: + pRegion = wBoundingShape(pWin); + if (!pRegion) + { + pRegion = CreateBoundingShape (pWin); + copy = FALSE; + } + break; + case WindowRegionClip: + pRegion = wClipShape(pWin); + if (!pRegion) + { + pRegion = CreateClipShape (pWin); + copy = FALSE; + } + break; + default: + client->errorValue = stuff->kind; + return BadValue; + } + if (copy && pRegion) + pRegion = XFixesRegionCopy (pRegion); + if (!pRegion) + return BadAlloc; + if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) + return BadAlloc; + + return(client->noClientException); +} + +int +SProcXFixesCreateRegionFromWindow (ClientPtr client) +{ + int n; + REQUEST (xXFixesCreateRegionFromWindowReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH (xXFixesCreateRegionFromWindowReq); + swapl(&stuff->region, n); + swapl(&stuff->window, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesCreateRegionFromGC (ClientPtr client) +{ + RegionPtr pRegion, pClip; + GCPtr pGC; + int rc; + REQUEST (xXFixesCreateRegionFromGCReq); + + REQUEST_SIZE_MATCH (xXFixesCreateRegionFromGCReq); + LEGAL_NEW_RESOURCE (stuff->region, client); + + rc = dixLookupGC(&pGC, stuff->gc, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + switch (pGC->clientClipType) { + case CT_PIXMAP: + pRegion = BITMAP_TO_REGION(pGC->pScreen, (PixmapPtr) pGC->clientClip); + if (!pRegion) + return BadAlloc; + break; + case CT_REGION: + pClip = (RegionPtr) pGC->clientClip; + pRegion = XFixesRegionCopy (pClip); + if (!pRegion) + return BadAlloc; + break; + default: + return BadImplementation; /* assume sane server bits */ + } + + if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) + return BadAlloc; + + return(client->noClientException); +} + +int +SProcXFixesCreateRegionFromGC (ClientPtr client) +{ + int n; + REQUEST (xXFixesCreateRegionFromGCReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH (xXFixesCreateRegionFromGCReq); + swapl(&stuff->region, n); + swapl(&stuff->gc, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesCreateRegionFromPicture (ClientPtr client) +{ + RegionPtr pRegion; + PicturePtr pPicture; + REQUEST (xXFixesCreateRegionFromPictureReq); + + REQUEST_SIZE_MATCH (xXFixesCreateRegionFromPictureReq); + LEGAL_NEW_RESOURCE (stuff->region, client); + + VERIFY_PICTURE(pPicture, stuff->picture, client, DixGetAttrAccess); + + switch (pPicture->clientClipType) { + case CT_PIXMAP: + pRegion = BITMAP_TO_REGION(pPicture->pDrawable->pScreen, + (PixmapPtr) pPicture->clientClip); + if (!pRegion) + return BadAlloc; + break; + case CT_REGION: + pRegion = XFixesRegionCopy ((RegionPtr) pPicture->clientClip); + if (!pRegion) + return BadAlloc; + break; + default: + return BadImplementation; /* assume sane server bits */ + } + + if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) + return BadAlloc; + + return(client->noClientException); +} + +int +SProcXFixesCreateRegionFromPicture (ClientPtr client) +{ + int n; + REQUEST (xXFixesCreateRegionFromPictureReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH (xXFixesCreateRegionFromPictureReq); + swapl(&stuff->region, n); + swapl(&stuff->picture, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesDestroyRegion (ClientPtr client) +{ + REQUEST (xXFixesDestroyRegionReq); + RegionPtr pRegion; + + REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq); + VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); + FreeResource (stuff->region, RT_NONE); + return(client->noClientException); +} + +int +SProcXFixesDestroyRegion (ClientPtr client) +{ + int n; + REQUEST (xXFixesDestroyRegionReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq); + swapl (&stuff->region, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesSetRegion (ClientPtr client) +{ + int things; + RegionPtr pRegion, pNew; + REQUEST (xXFixesSetRegionReq); + + REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq); + VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); + + things = (client->req_len << 2) - sizeof (xXFixesCreateRegionReq); + if (things & 4) + return BadLength; + things >>= 3; + + pNew = RECTS_TO_REGION(0, things, (xRectangle *) (stuff + 1), CT_UNSORTED); + if (!pNew) + return BadAlloc; + if (!REGION_COPY (0, pRegion, pNew)) + { + REGION_DESTROY (0, pNew); + return BadAlloc; + } + REGION_DESTROY (0, pNew); + return(client->noClientException); +} + +int +SProcXFixesSetRegion (ClientPtr client) +{ + int n; + REQUEST (xXFixesSetRegionReq); + + swaps (&stuff->length, n); + REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq); + swapl (&stuff->region, n); + SwapRestS(stuff); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesCopyRegion (ClientPtr client) +{ + RegionPtr pSource, pDestination; + REQUEST (xXFixesCopyRegionReq); + + VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); + VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); + + if (!REGION_COPY(pScreen, pDestination, pSource)) + return BadAlloc; + + return(client->noClientException); +} + +int +SProcXFixesCopyRegion (ClientPtr client) +{ + int n; + REQUEST (xXFixesCopyRegionReq); + + swaps (&stuff->length, n); + REQUEST_AT_LEAST_SIZE(xXFixesCopyRegionReq); + swapl (&stuff->source, n); + swapl (&stuff->destination, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesCombineRegion (ClientPtr client) +{ + RegionPtr pSource1, pSource2, pDestination; + int ret = Success; + REQUEST (xXFixesCombineRegionReq); + + REQUEST_SIZE_MATCH (xXFixesCombineRegionReq); + VERIFY_REGION(pSource1, stuff->source1, client, DixReadAccess); + VERIFY_REGION(pSource2, stuff->source2, client, DixReadAccess); + VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); + + switch (stuff->xfixesReqType) { + case X_XFixesUnionRegion: + if (!REGION_UNION (0, pDestination, pSource1, pSource2)) + ret = BadAlloc; + break; + case X_XFixesIntersectRegion: + if (!REGION_INTERSECT (0, pDestination, pSource1, pSource2)) + ret = BadAlloc; + break; + case X_XFixesSubtractRegion: + if (!REGION_SUBTRACT (0, pDestination, pSource1, pSource2)) + ret = BadAlloc; + break; + } + + if (ret == Success) + ret = client->noClientException; + return ret; +} + +int +SProcXFixesCombineRegion (ClientPtr client) +{ + int n; + REQUEST (xXFixesCombineRegionReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH (xXFixesCombineRegionReq); + swapl (&stuff->source1, n); + swapl (&stuff->source2, n); + swapl (&stuff->destination, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesInvertRegion (ClientPtr client) +{ + RegionPtr pSource, pDestination; + BoxRec bounds; + int ret = Success; + REQUEST(xXFixesInvertRegionReq); + + REQUEST_SIZE_MATCH(xXFixesInvertRegionReq); + VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); + VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); + + /* Compute bounds, limit to 16 bits */ + bounds.x1 = stuff->x; + bounds.y1 = stuff->y; + if ((int) stuff->x + (int) stuff->width > MAXSHORT) + bounds.x2 = MAXSHORT; + else + bounds.x2 = stuff->x + stuff->width; + + if ((int) stuff->y + (int) stuff->height > MAXSHORT) + bounds.y2 = MAXSHORT; + else + bounds.y2 = stuff->y + stuff->height; + + if (!REGION_INVERSE(0, pDestination, pSource, &bounds)) + ret = BadAlloc; + + if (ret == Success) + ret = client->noClientException; + return ret; +} + +int +SProcXFixesInvertRegion (ClientPtr client) +{ + int n; + REQUEST(xXFixesInvertRegionReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXFixesInvertRegionReq); + swapl (&stuff->source, n); + swaps (&stuff->x, n); + swaps (&stuff->y, n); + swaps (&stuff->width, n); + swaps (&stuff->height, n); + swapl (&stuff->destination, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesTranslateRegion (ClientPtr client) +{ + RegionPtr pRegion; + REQUEST(xXFixesTranslateRegionReq); + + REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq); + VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); + + REGION_TRANSLATE(pScreen, pRegion, stuff->dx, stuff->dy); + return (client->noClientException); +} + +int +SProcXFixesTranslateRegion (ClientPtr client) +{ + int n; + REQUEST(xXFixesTranslateRegionReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq); + swapl (&stuff->region, n); + swaps (&stuff->dx, n); + swaps (&stuff->dy, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesRegionExtents (ClientPtr client) +{ + RegionPtr pSource, pDestination; + REQUEST(xXFixesRegionExtentsReq); + + REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq); + VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); + VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); + + REGION_RESET (0, pDestination, REGION_EXTENTS (0, pSource)); + + return (client->noClientException); +} + +int +SProcXFixesRegionExtents (ClientPtr client) +{ + int n; + REQUEST(xXFixesRegionExtentsReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq); + swapl (&stuff->source, n); + swapl (&stuff->destination, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesFetchRegion (ClientPtr client) +{ + RegionPtr pRegion; + xXFixesFetchRegionReply *reply; + xRectangle *pRect; + BoxPtr pExtent; + BoxPtr pBox; + int i, nBox; + REQUEST(xXFixesFetchRegionReq); + + REQUEST_SIZE_MATCH(xXFixesFetchRegionReq); + VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess); + + pExtent = REGION_EXTENTS (0, pRegion); + pBox = REGION_RECTS (pRegion); + nBox = REGION_NUM_RECTS (pRegion); + + reply = xalloc (sizeof (xXFixesFetchRegionReply) + + nBox * sizeof (xRectangle)); + if (!reply) + return BadAlloc; + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = nBox << 1; + reply->x = pExtent->x1; + reply->y = pExtent->y1; + reply->width = pExtent->x2 - pExtent->x1; + reply->height = pExtent->y2 - pExtent->y1; + + pRect = (xRectangle *) (reply + 1); + for (i = 0; i < nBox; i++) + { + pRect[i].x = pBox[i].x1; + pRect[i].y = pBox[i].y1; + pRect[i].width = pBox[i].x2 - pBox[i].x1; + pRect[i].height = pBox[i].y2 - pBox[i].y1; + } + if (client->swapped) + { + int n; + swaps (&reply->sequenceNumber, n); + swapl (&reply->length, n); + swaps (&reply->x, n); + swaps (&reply->y, n); + swaps (&reply->width, n); + swaps (&reply->height, n); + SwapShorts ((INT16 *) pRect, nBox * 4); + } + (void) WriteToClient(client, sizeof (xXFixesFetchRegionReply) + + nBox * sizeof (xRectangle), (char *) reply); + xfree (reply); + return (client->noClientException); +} + +int +SProcXFixesFetchRegion (ClientPtr client) +{ + int n; + REQUEST(xXFixesFetchRegionReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXFixesFetchRegionReq); + swapl (&stuff->region, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesSetGCClipRegion (ClientPtr client) +{ + GCPtr pGC; + RegionPtr pRegion; + XID vals[2]; + int rc; + REQUEST(xXFixesSetGCClipRegionReq); + REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); + + rc = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); + if (rc != Success) + return rc; + + VERIFY_REGION_OR_NONE (pRegion, stuff->region, client, DixReadAccess); + + if (pRegion) + { + pRegion = XFixesRegionCopy (pRegion); + if (!pRegion) + return BadAlloc; + } + + vals[0] = stuff->xOrigin; + vals[1] = stuff->yOrigin; + DoChangeGC (pGC, GCClipXOrigin|GCClipYOrigin, vals, 0); + (*pGC->funcs->ChangeClip)(pGC, pRegion ? CT_REGION : CT_NONE, (pointer)pRegion, 0); + + return (client->noClientException); +} + +int +SProcXFixesSetGCClipRegion (ClientPtr client) +{ + int n; + REQUEST(xXFixesSetGCClipRegionReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); + swapl (&stuff->gc, n); + swapl (&stuff->region, n); + swaps (&stuff->xOrigin, n); + swaps (&stuff->yOrigin, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +typedef RegionPtr (*CreateDftPtr)(WindowPtr pWin); + +int +ProcXFixesSetWindowShapeRegion (ClientPtr client) +{ + WindowPtr pWin; + ScreenPtr pScreen; + RegionPtr pRegion; + RegionPtr *pDestRegion; + int rc; + REQUEST(xXFixesSetWindowShapeRegionReq); + + REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); + rc = dixLookupResourceByType((pointer *)&pWin, stuff->dest, RT_WINDOW, + client, DixSetAttrAccess); + if (rc != Success) + { + client->errorValue = stuff->dest; + return (rc == BadValue) ? BadWindow : rc; + } + 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); +} + +int +SProcXFixesSetWindowShapeRegion (ClientPtr client) +{ + int n; + REQUEST(xXFixesSetWindowShapeRegionReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); + swapl (&stuff->dest, n); + swaps (&stuff->xOff, n); + swaps (&stuff->yOff, n); + swapl (&stuff->region, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesSetPictureClipRegion (ClientPtr client) +{ + PicturePtr pPicture; + RegionPtr pRegion; + ScreenPtr pScreen; + PictureScreenPtr ps; + REQUEST(xXFixesSetPictureClipRegionReq); + + REQUEST_SIZE_MATCH (xXFixesSetPictureClipRegionReq); + VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess); + pScreen = pPicture->pDrawable->pScreen; + ps = GetPictureScreen (pScreen); + VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess); + + return SetPictureClipRegion (pPicture, stuff->xOrigin, stuff->yOrigin, + pRegion); +} + +int +SProcXFixesSetPictureClipRegion (ClientPtr client) +{ + int n; + REQUEST(xXFixesSetPictureClipRegionReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH (xXFixesSetPictureClipRegionReq); + swapl (&stuff->picture, n); + swapl (&stuff->region, n); + swaps (&stuff->xOrigin, n); + swaps (&stuff->yOrigin, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesExpandRegion (ClientPtr client) +{ + RegionPtr pSource, pDestination; + int ret = Success; + REQUEST (xXFixesExpandRegionReq); + BoxPtr pTmp; + BoxPtr pSrc; + int nBoxes; + int i; + + REQUEST_SIZE_MATCH (xXFixesExpandRegionReq); + VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); + VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); + + nBoxes = REGION_NUM_RECTS(pSource); + pSrc = REGION_RECTS(pSource); + if (nBoxes) + { + pTmp = xalloc (nBoxes * sizeof (BoxRec)); + if (!pTmp) + return BadAlloc; + for (i = 0; i < nBoxes; i++) + { + pTmp[i].x1 = pSrc[i].x1 - stuff->left; + pTmp[i].x2 = pSrc[i].x2 + stuff->right; + pTmp[i].y1 = pSrc[i].y1 - stuff->top; + pTmp[i].y2 = pSrc[i].y2 + stuff->bottom; + } + REGION_EMPTY (pScreen, pDestination); + for (i = 0; i < nBoxes; i++) + { + RegionRec r; + REGION_INIT (pScreen, &r, &pTmp[i], 0); + REGION_UNION (pScreen, pDestination, pDestination, &r); + } + xfree(pTmp); + } + if (ret == Success) + ret = client->noClientException; + return ret; +} + +int +SProcXFixesExpandRegion (ClientPtr client) +{ + int n; + REQUEST (xXFixesExpandRegionReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH (xXFixesExpandRegionReq); + swapl (&stuff->source, n); + swapl (&stuff->destination, n); + swaps (&stuff->left, n); + swaps (&stuff->right, n); + swaps (&stuff->top, n); + swaps (&stuff->bottom, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + -- cgit v1.2.3