123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233 |
- /************************************************************
- Copyright 1989, 1998 The Open Group
- 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.
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of The Open Group shall not be
- used in advertising or otherwise to promote the sale, use or other dealings
- in this Software without prior written authorization from The Open Group.
- ********************************************************/
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <stdlib.h>
- #include <X11/X.h>
- #include <X11/Xproto.h>
- #include "misc.h"
- #include "os.h"
- #include "windowstr.h"
- #include "scrnintstr.h"
- #include "pixmapstr.h"
- #include "extnsionst.h"
- #include "dixstruct.h"
- #include "resource.h"
- #include "opaque.h"
- #define _SHAPE_SERVER_ /* don't want Xlib structures */
- #include <X11/extensions/shapeproto.h>
- #include "regionstr.h"
- #include "gcstruct.h"
- #include "extinit.h"
- typedef RegionPtr (*CreateDftPtr) (WindowPtr /* pWin */
- );
- static int ShapeFreeClient(pointer /* data */ ,
- XID /* id */
- );
- static int ShapeFreeEvents(pointer /* data */ ,
- XID /* id */
- );
- static void ShapeResetProc(ExtensionEntry * /* extEntry */
- );
- static void SShapeNotifyEvent(xShapeNotifyEvent * /* from */ ,
- xShapeNotifyEvent * /* to */
- );
- static int
- RegionOperate(ClientPtr /* client */ ,
- WindowPtr /* pWin */ ,
- int /* kind */ ,
- RegionPtr * /* destRgnp */ ,
- RegionPtr /* srcRgn */ ,
- int /* op */ ,
- int /* xoff */ ,
- int /* yoff */ ,
- CreateDftPtr /* create */
- );
- /* SendShapeNotify, CreateBoundingShape and CreateClipShape are used
- * externally by the Xfixes extension and are now defined in window.h
- */
- static DISPATCH_PROC(ProcShapeCombine);
- static DISPATCH_PROC(ProcShapeDispatch);
- static DISPATCH_PROC(ProcShapeGetRectangles);
- static DISPATCH_PROC(ProcShapeInputSelected);
- static DISPATCH_PROC(ProcShapeMask);
- static DISPATCH_PROC(ProcShapeOffset);
- static DISPATCH_PROC(ProcShapeQueryExtents);
- static DISPATCH_PROC(ProcShapeQueryVersion);
- static DISPATCH_PROC(ProcShapeRectangles);
- static DISPATCH_PROC(ProcShapeSelectInput);
- static DISPATCH_PROC(SProcShapeCombine);
- static DISPATCH_PROC(SProcShapeDispatch);
- static DISPATCH_PROC(SProcShapeGetRectangles);
- static DISPATCH_PROC(SProcShapeInputSelected);
- static DISPATCH_PROC(SProcShapeMask);
- static DISPATCH_PROC(SProcShapeOffset);
- static DISPATCH_PROC(SProcShapeQueryExtents);
- static DISPATCH_PROC(SProcShapeQueryVersion);
- static DISPATCH_PROC(SProcShapeRectangles);
- static DISPATCH_PROC(SProcShapeSelectInput);
- #if 0
- static unsigned char ShapeReqCode = 0;
- #endif
- static int ShapeEventBase = 0;
- static RESTYPE ClientType, EventType; /* resource types for event masks */
- /*
- * each window has a list of clients requesting
- * ShapeNotify events. Each client has a resource
- * for each window it selects ShapeNotify input for,
- * this resource is used to delete the ShapeNotifyRec
- * entry from the per-window queue.
- */
- typedef struct _ShapeEvent *ShapeEventPtr;
- typedef struct _ShapeEvent {
- ShapeEventPtr next;
- ClientPtr client;
- WindowPtr window;
- XID clientResource;
- } ShapeEventRec;
- /****************
- * ShapeExtensionInit
- *
- * Called from InitExtensions in main() or from QueryExtension() if the
- * extension is dynamically loaded.
- *
- ****************/
- void
- ShapeExtensionInit(void)
- {
- ExtensionEntry *extEntry;
- ClientType = CreateNewResourceType(ShapeFreeClient);
- EventType = CreateNewResourceType(ShapeFreeEvents);
- if (ClientType && EventType &&
- (extEntry = AddExtension(SHAPENAME, ShapeNumberEvents, 0,
- ProcShapeDispatch, SProcShapeDispatch,
- ShapeResetProc, StandardMinorOpcode))) {
- #if 0
- ShapeReqCode = (unsigned char) extEntry->base;
- #endif
- ShapeEventBase = extEntry->eventBase;
- EventSwapVector[ShapeEventBase] = (EventSwapPtr) SShapeNotifyEvent;
- }
- }
- /*ARGSUSED*/ static void
- ShapeResetProc(extEntry)
- ExtensionEntry *extEntry;
- {
- }
- static int
- RegionOperate(client, pWin, kind, destRgnp, srcRgn, op, xoff, yoff, create)
- ClientPtr client;
- WindowPtr pWin;
- int kind;
- RegionPtr *destRgnp, srcRgn;
- int op;
- int xoff, yoff;
- CreateDftPtr create; /* creates a reasonable *destRgnp */
- {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- if (srcRgn && (xoff || yoff))
- REGION_TRANSLATE(srcRgn, xoff, yoff);
- if (!pWin->parent) {
- if (srcRgn)
- REGION_DESTROY(srcRgn);
- return Success;
- }
- /* May/30/2001:
- * The shape.PS specs say if src is None, existing shape is to be
- * removed (and so the op-code has no meaning in such removal);
- * see shape.PS, page 3, ShapeMask.
- */
- if (srcRgn == NULL) {
- if (*destRgnp != NULL) {
- REGION_DESTROY(*destRgnp);
- *destRgnp = 0;
- /* go on to remove shape and generate ShapeNotify */
- }
- else {
- /* May/30/2001:
- * The target currently has no shape in effect, so nothing to
- * do here. The specs say that ShapeNotify is generated whenever
- * the client region is "modified"; since no modification is done
- * here, we do not generate that event. The specs does not say
- * "it is an error to request removal when there is no shape in
- * effect", so we return good status.
- */
- return Success;
- }
- }
- else
- switch (op) {
- case ShapeSet:
- if (*destRgnp)
- REGION_DESTROY(*destRgnp);
- *destRgnp = srcRgn;
- srcRgn = 0;
- break;
- case ShapeUnion:
- if (*destRgnp)
- REGION_UNION(*destRgnp, *destRgnp, srcRgn);
- break;
- case ShapeIntersect:
- if (*destRgnp)
- REGION_INTERSECT(*destRgnp, *destRgnp, srcRgn);
- else {
- *destRgnp = srcRgn;
- srcRgn = 0;
- }
- break;
- case ShapeSubtract:
- if (!*destRgnp)
- *destRgnp = (*create) (pWin);
- REGION_SUBTRACT(*destRgnp, *destRgnp, srcRgn);
- break;
- case ShapeInvert:
- if (!*destRgnp)
- *destRgnp = REGION_CREATE((BoxPtr) 0, 0);
- else
- REGION_SUBTRACT(*destRgnp, srcRgn, *destRgnp);
- break;
- default:
- client->errorValue = op;
- return BadValue;
- }
- if (srcRgn)
- REGION_DESTROY(srcRgn);
- (*pScreen->SetShape) (pWin);
- SendShapeNotify(pWin, kind);
- return Success;
- }
- RegionPtr
- CreateBoundingShape(pWin)
- WindowPtr pWin;
- {
- BoxRec extents;
- extents.x1 = -wBorderWidth(pWin);
- extents.y1 = -wBorderWidth(pWin);
- extents.x2 = pWin->drawable.width + wBorderWidth(pWin);
- extents.y2 = pWin->drawable.height + wBorderWidth(pWin);
- return REGION_CREATE(&extents, 1);
- }
- RegionPtr
- CreateClipShape(pWin)
- WindowPtr pWin;
- {
- BoxRec extents;
- extents.x1 = 0;
- extents.y1 = 0;
- extents.x2 = pWin->drawable.width;
- extents.y2 = pWin->drawable.height;
- return REGION_CREATE(&extents, 1);
- }
- static int
- ProcShapeQueryVersion(client)
- ClientPtr client;
- {
- xShapeQueryVersionReply rep;
- REQUEST_SIZE_MATCH(xShapeQueryVersionReq);
- memset(&rep, 0, sizeof(xShapeQueryVersionReply));
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = SHAPE_MAJOR_VERSION;
- rep.minorVersion = SHAPE_MINOR_VERSION;
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- swaps(&rep.majorVersion);
- swaps(&rep.minorVersion);
- }
- WriteToClient(client, sizeof(xShapeQueryVersionReply), (char *) &rep);
- return (client->noClientException);
- }
- /*****************
- * ProcShapeRectangles
- *
- *****************/
- static int
- ProcShapeRectangles(client)
- ClientPtr client;
- {
- WindowPtr pWin;
- REQUEST(xShapeRectanglesReq);
- xRectangle *prects;
- int nrects, ctype;
- RegionPtr srcRgn;
- RegionPtr *destRgn;
- CreateDftPtr createDefault;
- REQUEST_AT_LEAST_SIZE(xShapeRectanglesReq);
- UpdateCurrentTime();
- pWin = LookupWindow(stuff->dest, client);
- if (!pWin)
- return BadWindow;
- 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 = RECTS_TO_REGION(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);
- }
- /**************
- * ProcShapeMask
- **************/
- static int
- ProcShapeMask(client)
- ClientPtr client;
- {
- WindowPtr pWin;
- ScreenPtr pScreen;
- REQUEST(xShapeMaskReq);
- RegionPtr srcRgn;
- RegionPtr *destRgn;
- PixmapPtr pPixmap;
- CreateDftPtr createDefault;
- REQUEST_SIZE_MATCH(xShapeMaskReq);
- UpdateCurrentTime();
- pWin = SecurityLookupWindow(stuff->dest, client, SecurityWriteAccess);
- if (!pWin)
- return BadWindow;
- 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 {
- pPixmap = (PixmapPtr) SecurityLookupIDByType(client, stuff->src,
- RT_PIXMAP,
- SecurityReadAccess);
- if (!pPixmap)
- return BadPixmap;
- if (pPixmap->drawable.pScreen != pScreen ||
- pPixmap->drawable.depth != 1)
- return BadMatch;
- srcRgn = BITMAP_TO_REGION(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);
- }
- /************
- * ProcShapeCombine
- ************/
- static int
- ProcShapeCombine(client)
- ClientPtr client;
- {
- WindowPtr pSrcWin, pDestWin;
- ScreenPtr pScreen;
- REQUEST(xShapeCombineReq);
- RegionPtr srcRgn;
- RegionPtr *destRgn;
- CreateDftPtr createDefault;
- CreateDftPtr createSrc;
- RegionPtr tmp;
- REQUEST_SIZE_MATCH(xShapeCombineReq);
- UpdateCurrentTime();
- pDestWin = LookupWindow(stuff->dest, client);
- if (!pDestWin)
- return BadWindow;
- 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;
- }
- pScreen = pDestWin->drawable.pScreen;
- pSrcWin = LookupWindow(stuff->src, client);
- if (!pSrcWin)
- return BadWindow;
- 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 != pScreen) {
- return BadMatch;
- }
- if (srcRgn) {
- tmp = REGION_CREATE((BoxPtr) 0, 0);
- REGION_COPY(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);
- }
- /*************
- * ProcShapeOffset
- *************/
- static int
- ProcShapeOffset(client)
- ClientPtr client;
- {
- WindowPtr pWin;
- ScreenPtr pScreen;
- REQUEST(xShapeOffsetReq);
- RegionPtr srcRgn;
- REQUEST_SIZE_MATCH(xShapeOffsetReq);
- UpdateCurrentTime();
- pWin = LookupWindow(stuff->dest, client);
- if (!pWin)
- return BadWindow;
- switch (stuff->destKind) {
- case ShapeBounding:
- srcRgn = wBoundingShape(pWin);
- break;
- case ShapeClip:
- srcRgn = wClipShape(pWin);
- break;
- case ShapeInput:
- srcRgn = wInputShape(pWin);
- break;
- default:
- client->errorValue = stuff->destKind;
- return BadValue;
- }
- pScreen = pWin->drawable.pScreen;
- if (srcRgn) {
- REGION_TRANSLATE(srcRgn, stuff->xOff, stuff->yOff);
- (*pScreen->SetShape) (pWin);
- }
- SendShapeNotify(pWin, (int) stuff->destKind);
- return Success;
- }
- static int
- ProcShapeQueryExtents(client)
- ClientPtr client;
- {
- REQUEST(xShapeQueryExtentsReq);
- WindowPtr pWin;
- xShapeQueryExtentsReply rep;
- BoxRec extents, *pExtents;
- RegionPtr region;
- REQUEST_SIZE_MATCH(xShapeQueryExtentsReq);
- pWin = LookupWindow(stuff->window, client);
- if (!pWin)
- return BadWindow;
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.boundingShaped = (wBoundingShape(pWin) != 0);
- rep.clipShaped = (wClipShape(pWin) != 0);
- if ((region = wBoundingShape(pWin))) {
- /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
- pExtents = REGION_EXTENTS(region);
- extents = *pExtents;
- }
- else {
- extents.x1 = -wBorderWidth(pWin);
- extents.y1 = -wBorderWidth(pWin);
- extents.x2 = pWin->drawable.width + wBorderWidth(pWin);
- extents.y2 = pWin->drawable.height + wBorderWidth(pWin);
- }
- rep.xBoundingShape = extents.x1;
- rep.yBoundingShape = extents.y1;
- rep.widthBoundingShape = extents.x2 - extents.x1;
- rep.heightBoundingShape = extents.y2 - extents.y1;
- if ((region = wClipShape(pWin))) {
- /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
- pExtents = REGION_EXTENTS(region);
- extents = *pExtents;
- }
- else {
- extents.x1 = 0;
- extents.y1 = 0;
- extents.x2 = pWin->drawable.width;
- extents.y2 = pWin->drawable.height;
- }
- rep.xClipShape = extents.x1;
- rep.yClipShape = extents.y1;
- rep.widthClipShape = extents.x2 - extents.x1;
- rep.heightClipShape = extents.y2 - extents.y1;
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- swaps(&rep.xBoundingShape);
- swaps(&rep.yBoundingShape);
- swaps(&rep.widthBoundingShape);
- swaps(&rep.heightBoundingShape);
- swaps(&rep.xClipShape);
- swaps(&rep.yClipShape);
- swaps(&rep.widthClipShape);
- swaps(&rep.heightClipShape);
- }
- WriteToClient(client, sizeof(xShapeQueryExtentsReply), (char *) &rep);
- return (client->noClientException);
- }
- /*ARGSUSED*/ static int
- ShapeFreeClient(data, id)
- pointer data;
- XID id;
- {
- ShapeEventPtr pShapeEvent;
- WindowPtr pWin;
- ShapeEventPtr *pHead, pCur, pPrev;
- pShapeEvent = (ShapeEventPtr) data;
- pWin = pShapeEvent->window;
- pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType);
- if (pHead) {
- pPrev = 0;
- for (pCur = *pHead; pCur && pCur != pShapeEvent; pCur = pCur->next)
- pPrev = pCur;
- if (pCur) {
- if (pPrev)
- pPrev->next = pShapeEvent->next;
- else
- *pHead = pShapeEvent->next;
- }
- }
- free((pointer) pShapeEvent);
- return 1;
- }
- /*ARGSUSED*/ static int
- ShapeFreeEvents(data, id)
- pointer data;
- XID id;
- {
- ShapeEventPtr *pHead, pCur, pNext;
- pHead = (ShapeEventPtr *) data;
- for (pCur = *pHead; pCur; pCur = pNext) {
- pNext = pCur->next;
- FreeResource(pCur->clientResource, ClientType);
- free((pointer) pCur);
- }
- free((pointer) pHead);
- return 1;
- }
- static int
- ProcShapeSelectInput(client)
- ClientPtr client;
- {
- REQUEST(xShapeSelectInputReq);
- WindowPtr pWin;
- ShapeEventPtr pShapeEvent, pNewShapeEvent, *pHead;
- XID clientResource;
- REQUEST_SIZE_MATCH(xShapeSelectInputReq);
- pWin = SecurityLookupWindow(stuff->window, client, SecurityWriteAccess);
- if (!pWin)
- return BadWindow;
- pHead = (ShapeEventPtr *) SecurityLookupIDByType(client,
- pWin->drawable.id,
- EventType,
- SecurityWriteAccess);
- switch (stuff->enable) {
- case xTrue:
- if (pHead) {
- /* check for existing entry. */
- for (pShapeEvent = *pHead;
- pShapeEvent; pShapeEvent = pShapeEvent->next) {
- if (pShapeEvent->client == client)
- return Success;
- }
- }
- /* build the entry */
- pNewShapeEvent = (ShapeEventPtr)
- malloc(sizeof(ShapeEventRec));
- if (!pNewShapeEvent)
- return BadAlloc;
- pNewShapeEvent->next = 0;
- pNewShapeEvent->client = client;
- pNewShapeEvent->window = pWin;
- /*
- * add a resource that will be deleted when
- * the client goes away
- */
- clientResource = FakeClientID(client->index);
- pNewShapeEvent->clientResource = clientResource;
- if (!AddResource(clientResource, ClientType, (pointer) pNewShapeEvent))
- return BadAlloc;
- /*
- * create a resource to contain a pointer to the list
- * of clients selecting input. This must be indirect as
- * the list may be arbitrarily rearranged which cannot be
- * done through the resource database.
- */
- if (!pHead) {
- pHead = malloc(sizeof(ShapeEventPtr));
- if (!pHead ||
- !AddResource(pWin->drawable.id, EventType, (pointer) pHead)) {
- FreeResource(clientResource, RT_NONE);
- return BadAlloc;
- }
- *pHead = 0;
- }
- pNewShapeEvent->next = *pHead;
- *pHead = pNewShapeEvent;
- break;
- case xFalse:
- /* delete the interest */
- if (pHead) {
- pNewShapeEvent = 0;
- for (pShapeEvent = *pHead; pShapeEvent;
- pShapeEvent = pShapeEvent->next) {
- if (pShapeEvent->client == client)
- break;
- pNewShapeEvent = pShapeEvent;
- }
- if (pShapeEvent) {
- FreeResource(pShapeEvent->clientResource, ClientType);
- if (pNewShapeEvent)
- pNewShapeEvent->next = pShapeEvent->next;
- else
- *pHead = pShapeEvent->next;
- free(pShapeEvent);
- }
- }
- break;
- default:
- client->errorValue = stuff->enable;
- return BadValue;
- }
- return Success;
- }
- /*
- * deliver the event
- */
- void
- SendShapeNotify(pWin, which)
- WindowPtr pWin;
- int which;
- {
- ShapeEventPtr *pHead, pShapeEvent;
- xShapeNotifyEvent se;
- BoxRec extents;
- RegionPtr region;
- BYTE shaped;
- pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType);
- if (!pHead)
- return;
- switch (which) {
- case ShapeBounding:
- region = wBoundingShape(pWin);
- if (region) {
- extents = *REGION_EXTENTS(region);
- shaped = xTrue;
- }
- else {
- extents.x1 = -wBorderWidth(pWin);
- extents.y1 = -wBorderWidth(pWin);
- extents.x2 = pWin->drawable.width + wBorderWidth(pWin);
- extents.y2 = pWin->drawable.height + wBorderWidth(pWin);
- shaped = xFalse;
- }
- break;
- case ShapeClip:
- region = wClipShape(pWin);
- if (region) {
- extents = *REGION_EXTENTS(region);
- shaped = xTrue;
- }
- else {
- extents.x1 = 0;
- extents.y1 = 0;
- extents.x2 = pWin->drawable.width;
- extents.y2 = pWin->drawable.height;
- shaped = xFalse;
- }
- break;
- case ShapeInput:
- region = wInputShape(pWin);
- if (region) {
- extents = *REGION_EXTENTS(region);
- shaped = xTrue;
- }
- else {
- extents.x1 = -wBorderWidth(pWin);
- extents.y1 = -wBorderWidth(pWin);
- extents.x2 = pWin->drawable.width + wBorderWidth(pWin);
- extents.y2 = pWin->drawable.height + wBorderWidth(pWin);
- shaped = xFalse;
- }
- break;
- default:
- return;
- }
- for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
- se.type = ShapeNotify + ShapeEventBase;
- se.kind = which;
- se.window = pWin->drawable.id;
- se.x = extents.x1;
- se.y = extents.y1;
- se.width = extents.x2 - extents.x1;
- se.height = extents.y2 - extents.y1;
- se.time = currentTime.milliseconds;
- se.shaped = shaped;
- WriteEventsToClient(pShapeEvent->client, 1, (xEvent *) &se);
- }
- }
- static int
- ProcShapeInputSelected(client)
- ClientPtr client;
- {
- REQUEST(xShapeInputSelectedReq);
- WindowPtr pWin;
- ShapeEventPtr pShapeEvent, *pHead;
- int enabled;
- xShapeInputSelectedReply rep;
- REQUEST_SIZE_MATCH(xShapeInputSelectedReq);
- pWin = LookupWindow(stuff->window, client);
- if (!pWin)
- return BadWindow;
- pHead = (ShapeEventPtr *) SecurityLookupIDByType(client,
- pWin->drawable.id,
- EventType,
- SecurityReadAccess);
- enabled = xFalse;
- if (pHead) {
- for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
- if (pShapeEvent->client == client) {
- enabled = xTrue;
- break;
- }
- }
- }
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.enabled = enabled;
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- }
- WriteToClient(client, sizeof(xShapeInputSelectedReply), (char *) &rep);
- return (client->noClientException);
- }
- static int
- ProcShapeGetRectangles(client)
- ClientPtr client;
- {
- REQUEST(xShapeGetRectanglesReq);
- WindowPtr pWin;
- xShapeGetRectanglesReply rep;
- xRectangle *rects;
- int nrects, i;
- RegionPtr region;
- REQUEST_SIZE_MATCH(xShapeGetRectanglesReq);
- pWin = LookupWindow(stuff->window, client);
- if (!pWin)
- return BadWindow;
- switch (stuff->kind) {
- case ShapeBounding:
- region = wBoundingShape(pWin);
- break;
- case ShapeClip:
- region = wClipShape(pWin);
- break;
- case ShapeInput:
- region = wInputShape(pWin);
- break;
- default:
- client->errorValue = stuff->kind;
- return BadValue;
- }
- if (!region) {
- nrects = 1;
- rects = (xRectangle *) ALLOCATE_LOCAL(sizeof(xRectangle));
- if (!rects)
- return BadAlloc;
- switch (stuff->kind) {
- case ShapeBounding:
- rects->x = -(int) wBorderWidth(pWin);
- rects->y = -(int) wBorderWidth(pWin);
- rects->width = pWin->drawable.width + wBorderWidth(pWin);
- rects->height = pWin->drawable.height + wBorderWidth(pWin);
- break;
- case ShapeClip:
- rects->x = 0;
- rects->y = 0;
- rects->width = pWin->drawable.width;
- rects->height = pWin->drawable.height;
- break;
- case ShapeInput:
- rects->x = -(int) wBorderWidth(pWin);
- rects->y = -(int) wBorderWidth(pWin);
- rects->width = pWin->drawable.width + wBorderWidth(pWin);
- rects->height = pWin->drawable.height + wBorderWidth(pWin);
- break;
- }
- }
- else {
- BoxPtr box;
- nrects = REGION_NUM_RECTS(region);
- box = REGION_RECTS(region);
- rects = (xRectangle *) ALLOCATE_LOCAL(nrects * sizeof(xRectangle));
- if (!rects && nrects)
- return BadAlloc;
- for (i = 0; i < nrects; i++, box++) {
- rects[i].x = box->x1;
- rects[i].y = box->y1;
- rects[i].width = box->x2 - box->x1;
- rects[i].height = box->y2 - box->y1;
- }
- }
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = (nrects * sizeof(xRectangle)) >> 2;
- rep.ordering = YXBanded;
- rep.nrects = nrects;
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- swapl(&rep.nrects);
- SwapShorts((short *) rects, (unsigned long) nrects * 4);
- }
- WriteToClient(client, sizeof(rep), (char *) &rep);
- WriteToClient(client, nrects * sizeof(xRectangle), (char *) rects);
- DEALLOCATE_LOCAL(rects);
- return client->noClientException;
- }
- static int
- ProcShapeDispatch(client)
- ClientPtr client;
- {
- REQUEST(xReq);
- switch (stuff->data) {
- case X_ShapeQueryVersion:
- return ProcShapeQueryVersion(client);
- case X_ShapeRectangles:
- return ProcShapeRectangles(client);
- case X_ShapeMask:
- return ProcShapeMask(client);
- case X_ShapeCombine:
- return ProcShapeCombine(client);
- case X_ShapeOffset:
- return ProcShapeOffset(client);
- case X_ShapeQueryExtents:
- return ProcShapeQueryExtents(client);
- case X_ShapeSelectInput:
- return ProcShapeSelectInput(client);
- case X_ShapeInputSelected:
- return ProcShapeInputSelected(client);
- case X_ShapeGetRectangles:
- return ProcShapeGetRectangles(client);
- default:
- return BadRequest;
- }
- }
- static void
- SShapeNotifyEvent(from, to)
- xShapeNotifyEvent *from, *to;
- {
- to->type = from->type;
- to->kind = from->kind;
- cpswapl(from->window, to->window);
- cpswaps(from->sequenceNumber, to->sequenceNumber);
- cpswaps(from->x, to->x);
- cpswaps(from->y, to->y);
- cpswaps(from->width, to->width);
- cpswaps(from->height, to->height);
- cpswapl(from->time, to->time);
- to->shaped = from->shaped;
- }
- static int
- SProcShapeQueryVersion(client)
- ClientPtr client;
- {
- REQUEST(xShapeQueryVersionReq);
- swaps(&stuff->length);
- return ProcShapeQueryVersion(client);
- }
- static int
- SProcShapeRectangles(client)
- ClientPtr client;
- {
- REQUEST(xShapeRectanglesReq);
- swaps(&stuff->length);
- REQUEST_AT_LEAST_SIZE(xShapeRectanglesReq);
- swapl(&stuff->dest);
- swaps(&stuff->xOff);
- swaps(&stuff->yOff);
- SwapRestS(stuff);
- return ProcShapeRectangles(client);
- }
- static int
- SProcShapeMask(client)
- ClientPtr client;
- {
- REQUEST(xShapeMaskReq);
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xShapeMaskReq);
- swapl(&stuff->dest);
- swaps(&stuff->xOff);
- swaps(&stuff->yOff);
- swapl(&stuff->src);
- return ProcShapeMask(client);
- }
- static int
- SProcShapeCombine(client)
- ClientPtr client;
- {
- REQUEST(xShapeCombineReq);
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xShapeCombineReq);
- swapl(&stuff->dest);
- swaps(&stuff->xOff);
- swaps(&stuff->yOff);
- swapl(&stuff->src);
- return ProcShapeCombine(client);
- }
- static int
- SProcShapeOffset(client)
- ClientPtr client;
- {
- REQUEST(xShapeOffsetReq);
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xShapeOffsetReq);
- swapl(&stuff->dest);
- swaps(&stuff->xOff);
- swaps(&stuff->yOff);
- return ProcShapeOffset(client);
- }
- static int
- SProcShapeQueryExtents(client)
- ClientPtr client;
- {
- REQUEST(xShapeQueryExtentsReq);
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xShapeQueryExtentsReq);
- swapl(&stuff->window);
- return ProcShapeQueryExtents(client);
- }
- static int
- SProcShapeSelectInput(client)
- ClientPtr client;
- {
- REQUEST(xShapeSelectInputReq);
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xShapeSelectInputReq);
- swapl(&stuff->window);
- return ProcShapeSelectInput(client);
- }
- static int
- SProcShapeInputSelected(client)
- ClientPtr client;
- {
- REQUEST(xShapeInputSelectedReq);
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xShapeInputSelectedReq);
- swapl(&stuff->window);
- return ProcShapeInputSelected(client);
- }
- static int
- SProcShapeGetRectangles(client)
- ClientPtr client;
- {
- REQUEST(xShapeGetRectanglesReq);
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xShapeGetRectanglesReq);
- swapl(&stuff->window);
- return ProcShapeGetRectangles(client);
- }
- static int
- SProcShapeDispatch(client)
- ClientPtr client;
- {
- REQUEST(xReq);
- switch (stuff->data) {
- case X_ShapeQueryVersion:
- return SProcShapeQueryVersion(client);
- case X_ShapeRectangles:
- return SProcShapeRectangles(client);
- case X_ShapeMask:
- return SProcShapeMask(client);
- case X_ShapeCombine:
- return SProcShapeCombine(client);
- case X_ShapeOffset:
- return SProcShapeOffset(client);
- case X_ShapeQueryExtents:
- return SProcShapeQueryExtents(client);
- case X_ShapeSelectInput:
- return SProcShapeSelectInput(client);
- case X_ShapeInputSelected:
- return SProcShapeInputSelected(client);
- case X_ShapeGetRectangles:
- return SProcShapeGetRectangles(client);
- default:
- return BadRequest;
- }
- }
|