1 /************************************************************
3 Copyright 1989, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
34 #include <X11/Xproto.h>
37 #include "windowstr.h"
38 #include "scrnintstr.h"
39 #include "pixmapstr.h"
40 #include "extnsionst.h"
41 #include "dixstruct.h"
44 #include <X11/extensions/shapeproto.h>
45 #include "regionstr.h"
48 #include "protocol-versions.h"
50 typedef RegionPtr (*CreateDftPtr
) (WindowPtr
/* pWin */
53 static int ShapeFreeClient(pointer
/* data */ ,
56 static int ShapeFreeEvents(pointer
/* data */ ,
59 static void SShapeNotifyEvent(xShapeNotifyEvent
* /* from */ ,
60 xShapeNotifyEvent
* /* to */
63 /* SendShapeNotify, CreateBoundingShape and CreateClipShape are used
64 * externally by the Xfixes extension and are now defined in window.h
68 #include "panoramiX.h"
69 #include "panoramiXsrv.h"
72 static int ShapeEventBase
= 0;
73 static RESTYPE ClientType
, ShapeEventType
; /* resource types for event masks */
76 * each window has a list of clients requesting
77 * ShapeNotify events. Each client has a resource
78 * for each window it selects ShapeNotify input for,
79 * this resource is used to delete the ShapeNotifyRec
80 * entry from the per-window queue.
83 typedef struct _ShapeEvent
*ShapeEventPtr
;
85 typedef struct _ShapeEvent
{
95 * Called from InitExtensions in main() or from QueryExtension() if the
96 * extension is dynamically loaded.
101 RegionOperate(ClientPtr client
,
105 RegionPtr srcRgn
, int op
, int xoff
, int yoff
, CreateDftPtr create
)
107 if (srcRgn
&& (xoff
|| yoff
))
108 RegionTranslate(srcRgn
, xoff
, yoff
);
111 RegionDestroy(srcRgn
);
116 * The shape.PS specs say if src is None, existing shape is to be
117 * removed (and so the op-code has no meaning in such removal);
118 * see shape.PS, page 3, ShapeMask.
120 if (srcRgn
== NULL
) {
121 if (*destRgnp
!= NULL
) {
122 RegionDestroy(*destRgnp
);
124 /* go on to remove shape and generate ShapeNotify */
128 * The target currently has no shape in effect, so nothing to
129 * do here. The specs say that ShapeNotify is generated whenever
130 * the client region is "modified"; since no modification is done
131 * here, we do not generate that event. The specs does not say
132 * "it is an error to request removal when there is no shape in
133 * effect", so we return good status.
142 RegionDestroy(*destRgnp
);
148 RegionUnion(*destRgnp
, *destRgnp
, srcRgn
);
152 RegionIntersect(*destRgnp
, *destRgnp
, srcRgn
);
160 *destRgnp
= (*create
) (pWin
);
161 RegionSubtract(*destRgnp
, *destRgnp
, srcRgn
);
165 *destRgnp
= RegionCreate((BoxPtr
) 0, 0);
167 RegionSubtract(*destRgnp
, srcRgn
, *destRgnp
);
170 client
->errorValue
= op
;
174 RegionDestroy(srcRgn
);
175 (*pWin
->drawable
.pScreen
->SetShape
) (pWin
, kind
);
176 SendShapeNotify(pWin
, kind
);
181 CreateBoundingShape(WindowPtr pWin
)
185 extents
.x1
= -wBorderWidth(pWin
);
186 extents
.y1
= -wBorderWidth(pWin
);
187 extents
.x2
= pWin
->drawable
.width
+ wBorderWidth(pWin
);
188 extents
.y2
= pWin
->drawable
.height
+ wBorderWidth(pWin
);
189 return RegionCreate(&extents
, 1);
193 CreateClipShape(WindowPtr pWin
)
199 extents
.x2
= pWin
->drawable
.width
;
200 extents
.y2
= pWin
->drawable
.height
;
201 return RegionCreate(&extents
, 1);
205 ProcShapeQueryVersion(ClientPtr client
)
207 xShapeQueryVersionReply rep
= {
209 .sequenceNumber
= client
->sequence
,
211 .majorVersion
= SERVER_SHAPE_MAJOR_VERSION
,
212 .minorVersion
= SERVER_SHAPE_MINOR_VERSION
215 REQUEST_SIZE_MATCH(xShapeQueryVersionReq
);
217 if (client
->swapped
) {
218 swaps(&rep
.sequenceNumber
);
220 swaps(&rep
.majorVersion
);
221 swaps(&rep
.minorVersion
);
223 WriteToClient(client
, sizeof(xShapeQueryVersionReply
), &rep
);
228 * ProcShapeRectangles
233 ProcShapeRectangles(ClientPtr client
)
237 REQUEST(xShapeRectanglesReq
);
239 int nrects
, ctype
, rc
;
242 CreateDftPtr createDefault
;
244 REQUEST_AT_LEAST_SIZE(xShapeRectanglesReq
);
246 rc
= dixLookupWindow(&pWin
, stuff
->dest
, client
, DixSetAttrAccess
);
249 switch (stuff
->destKind
) {
251 createDefault
= CreateBoundingShape
;
254 createDefault
= CreateClipShape
;
257 createDefault
= CreateBoundingShape
;
260 client
->errorValue
= stuff
->destKind
;
263 if ((stuff
->ordering
!= Unsorted
) && (stuff
->ordering
!= YSorted
) &&
264 (stuff
->ordering
!= YXSorted
) && (stuff
->ordering
!= YXBanded
)) {
265 client
->errorValue
= stuff
->ordering
;
268 nrects
= ((stuff
->length
<< 2) - sizeof(xShapeRectanglesReq
));
272 prects
= (xRectangle
*) &stuff
[1];
273 ctype
= VerifyRectOrder(nrects
, prects
, (int) stuff
->ordering
);
276 srcRgn
= RegionFromRects(nrects
, prects
, ctype
);
279 MakeWindowOptional(pWin
);
280 switch (stuff
->destKind
) {
282 destRgn
= &pWin
->optional
->boundingShape
;
285 destRgn
= &pWin
->optional
->clipShape
;
288 destRgn
= &pWin
->optional
->inputShape
;
294 return RegionOperate(client
, pWin
, (int) stuff
->destKind
,
295 destRgn
, srcRgn
, (int) stuff
->op
,
296 stuff
->xOff
, stuff
->yOff
, createDefault
);
301 ProcPanoramiXShapeRectangles(ClientPtr client
)
303 REQUEST(xShapeRectanglesReq
);
307 REQUEST_AT_LEAST_SIZE(xShapeRectanglesReq
);
309 result
= dixLookupResourceByType((pointer
*) &win
, stuff
->dest
, XRT_WINDOW
,
310 client
, DixWriteAccess
);
311 if (result
!= Success
)
315 stuff
->dest
= win
->info
[j
].id
;
316 result
= ProcShapeRectangles(client
);
317 if (result
!= Success
)
329 ProcShapeMask(ClientPtr client
)
334 REQUEST(xShapeMaskReq
);
338 CreateDftPtr createDefault
;
341 REQUEST_SIZE_MATCH(xShapeMaskReq
);
343 rc
= dixLookupWindow(&pWin
, stuff
->dest
, client
, DixSetAttrAccess
);
346 switch (stuff
->destKind
) {
348 createDefault
= CreateBoundingShape
;
351 createDefault
= CreateClipShape
;
354 createDefault
= CreateBoundingShape
;
357 client
->errorValue
= stuff
->destKind
;
360 pScreen
= pWin
->drawable
.pScreen
;
361 if (stuff
->src
== None
)
364 rc
= dixLookupResourceByType((pointer
*) &pPixmap
, stuff
->src
,
365 RT_PIXMAP
, client
, DixReadAccess
);
368 if (pPixmap
->drawable
.pScreen
!= pScreen
||
369 pPixmap
->drawable
.depth
!= 1)
371 srcRgn
= BitmapToRegion(pScreen
, pPixmap
);
377 MakeWindowOptional(pWin
);
378 switch (stuff
->destKind
) {
380 destRgn
= &pWin
->optional
->boundingShape
;
383 destRgn
= &pWin
->optional
->clipShape
;
386 destRgn
= &pWin
->optional
->inputShape
;
392 return RegionOperate(client
, pWin
, (int) stuff
->destKind
,
393 destRgn
, srcRgn
, (int) stuff
->op
,
394 stuff
->xOff
, stuff
->yOff
, createDefault
);
399 ProcPanoramiXShapeMask(ClientPtr client
)
401 REQUEST(xShapeMaskReq
);
402 PanoramiXRes
*win
, *pmap
;
405 REQUEST_SIZE_MATCH(xShapeMaskReq
);
407 result
= dixLookupResourceByType((pointer
*) &win
, stuff
->dest
, XRT_WINDOW
,
408 client
, DixWriteAccess
);
409 if (result
!= Success
)
412 if (stuff
->src
!= None
) {
413 result
= dixLookupResourceByType((pointer
*) &pmap
, stuff
->src
,
414 XRT_PIXMAP
, client
, DixReadAccess
);
415 if (result
!= Success
)
422 stuff
->dest
= win
->info
[j
].id
;
424 stuff
->src
= pmap
->info
[j
].id
;
425 result
= ProcShapeMask(client
);
426 if (result
!= Success
)
438 ProcShapeCombine(ClientPtr client
)
440 WindowPtr pSrcWin
, pDestWin
;
442 REQUEST(xShapeCombineReq
);
445 CreateDftPtr createDefault
;
446 CreateDftPtr createSrc
;
450 REQUEST_SIZE_MATCH(xShapeCombineReq
);
452 rc
= dixLookupWindow(&pDestWin
, stuff
->dest
, client
, DixSetAttrAccess
);
455 if (!pDestWin
->optional
)
456 MakeWindowOptional(pDestWin
);
457 switch (stuff
->destKind
) {
459 createDefault
= CreateBoundingShape
;
462 createDefault
= CreateClipShape
;
465 createDefault
= CreateBoundingShape
;
468 client
->errorValue
= stuff
->destKind
;
472 rc
= dixLookupWindow(&pSrcWin
, stuff
->src
, client
, DixGetAttrAccess
);
475 switch (stuff
->srcKind
) {
477 srcRgn
= wBoundingShape(pSrcWin
);
478 createSrc
= CreateBoundingShape
;
481 srcRgn
= wClipShape(pSrcWin
);
482 createSrc
= CreateClipShape
;
485 srcRgn
= wInputShape(pSrcWin
);
486 createSrc
= CreateBoundingShape
;
489 client
->errorValue
= stuff
->srcKind
;
492 if (pSrcWin
->drawable
.pScreen
!= pDestWin
->drawable
.pScreen
) {
497 tmp
= RegionCreate((BoxPtr
) 0, 0);
498 RegionCopy(tmp
, srcRgn
);
502 srcRgn
= (*createSrc
) (pSrcWin
);
504 if (!pDestWin
->optional
)
505 MakeWindowOptional(pDestWin
);
506 switch (stuff
->destKind
) {
508 destRgn
= &pDestWin
->optional
->boundingShape
;
511 destRgn
= &pDestWin
->optional
->clipShape
;
514 destRgn
= &pDestWin
->optional
->inputShape
;
520 return RegionOperate(client
, pDestWin
, (int) stuff
->destKind
,
521 destRgn
, srcRgn
, (int) stuff
->op
,
522 stuff
->xOff
, stuff
->yOff
, createDefault
);
527 ProcPanoramiXShapeCombine(ClientPtr client
)
529 REQUEST(xShapeCombineReq
);
530 PanoramiXRes
*win
, *win2
;
533 REQUEST_AT_LEAST_SIZE(xShapeCombineReq
);
535 result
= dixLookupResourceByType((pointer
*) &win
, stuff
->dest
, XRT_WINDOW
,
536 client
, DixWriteAccess
);
537 if (result
!= Success
)
540 result
= dixLookupResourceByType((pointer
*) &win2
, stuff
->src
, XRT_WINDOW
,
541 client
, DixReadAccess
);
542 if (result
!= Success
)
546 stuff
->dest
= win
->info
[j
].id
;
547 stuff
->src
= win2
->info
[j
].id
;
548 result
= ProcShapeCombine(client
);
549 if (result
!= Success
)
561 ProcShapeOffset(ClientPtr client
)
565 REQUEST(xShapeOffsetReq
);
569 REQUEST_SIZE_MATCH(xShapeOffsetReq
);
571 rc
= dixLookupWindow(&pWin
, stuff
->dest
, client
, DixSetAttrAccess
);
574 switch (stuff
->destKind
) {
576 srcRgn
= wBoundingShape(pWin
);
579 srcRgn
= wClipShape(pWin
);
582 srcRgn
= wInputShape(pWin
);
585 client
->errorValue
= stuff
->destKind
;
589 RegionTranslate(srcRgn
, stuff
->xOff
, stuff
->yOff
);
590 (*pWin
->drawable
.pScreen
->SetShape
) (pWin
, stuff
->destKind
);
592 SendShapeNotify(pWin
, (int) stuff
->destKind
);
598 ProcPanoramiXShapeOffset(ClientPtr client
)
600 REQUEST(xShapeOffsetReq
);
604 REQUEST_AT_LEAST_SIZE(xShapeOffsetReq
);
606 result
= dixLookupResourceByType((pointer
*) &win
, stuff
->dest
, XRT_WINDOW
,
607 client
, DixWriteAccess
);
608 if (result
!= Success
)
612 stuff
->dest
= win
->info
[j
].id
;
613 result
= ProcShapeOffset(client
);
614 if (result
!= Success
)
622 ProcShapeQueryExtents(ClientPtr client
)
624 REQUEST(xShapeQueryExtentsReq
);
626 xShapeQueryExtentsReply rep
;
627 BoxRec extents
, *pExtents
;
631 REQUEST_SIZE_MATCH(xShapeQueryExtentsReq
);
632 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixGetAttrAccess
);
635 rep
= (xShapeQueryExtentsReply
) {
637 .sequenceNumber
= client
->sequence
,
639 .boundingShaped
= (wBoundingShape(pWin
) != 0),
640 .clipShaped
= (wClipShape(pWin
) != 0)
642 if ((region
= wBoundingShape(pWin
))) {
643 /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
644 pExtents
= RegionExtents(region
);
648 extents
.x1
= -wBorderWidth(pWin
);
649 extents
.y1
= -wBorderWidth(pWin
);
650 extents
.x2
= pWin
->drawable
.width
+ wBorderWidth(pWin
);
651 extents
.y2
= pWin
->drawable
.height
+ wBorderWidth(pWin
);
653 rep
.xBoundingShape
= extents
.x1
;
654 rep
.yBoundingShape
= extents
.y1
;
655 rep
.widthBoundingShape
= extents
.x2
- extents
.x1
;
656 rep
.heightBoundingShape
= extents
.y2
- extents
.y1
;
657 if ((region
= wClipShape(pWin
))) {
658 /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
659 pExtents
= RegionExtents(region
);
665 extents
.x2
= pWin
->drawable
.width
;
666 extents
.y2
= pWin
->drawable
.height
;
668 rep
.xClipShape
= extents
.x1
;
669 rep
.yClipShape
= extents
.y1
;
670 rep
.widthClipShape
= extents
.x2
- extents
.x1
;
671 rep
.heightClipShape
= extents
.y2
- extents
.y1
;
672 if (client
->swapped
) {
673 swaps(&rep
.sequenceNumber
);
675 swaps(&rep
.xBoundingShape
);
676 swaps(&rep
.yBoundingShape
);
677 swaps(&rep
.widthBoundingShape
);
678 swaps(&rep
.heightBoundingShape
);
679 swaps(&rep
.xClipShape
);
680 swaps(&rep
.yClipShape
);
681 swaps(&rep
.widthClipShape
);
682 swaps(&rep
.heightClipShape
);
684 WriteToClient(client
, sizeof(xShapeQueryExtentsReply
), &rep
);
688 /*ARGSUSED*/ static int
689 ShapeFreeClient(pointer data
, XID id
)
691 ShapeEventPtr pShapeEvent
;
693 ShapeEventPtr
*pHead
, pCur
, pPrev
;
696 pShapeEvent
= (ShapeEventPtr
) data
;
697 pWin
= pShapeEvent
->window
;
698 rc
= dixLookupResourceByType((pointer
*) &pHead
, pWin
->drawable
.id
,
699 ShapeEventType
, serverClient
, DixReadAccess
);
702 for (pCur
= *pHead
; pCur
&& pCur
!= pShapeEvent
; pCur
= pCur
->next
)
706 pPrev
->next
= pShapeEvent
->next
;
708 *pHead
= pShapeEvent
->next
;
711 free((pointer
) pShapeEvent
);
715 /*ARGSUSED*/ static int
716 ShapeFreeEvents(pointer data
, XID id
)
718 ShapeEventPtr
*pHead
, pCur
, pNext
;
720 pHead
= (ShapeEventPtr
*) data
;
721 for (pCur
= *pHead
; pCur
; pCur
= pNext
) {
723 FreeResource(pCur
->clientResource
, ClientType
);
724 free((pointer
) pCur
);
726 free((pointer
) pHead
);
731 ProcShapeSelectInput(ClientPtr client
)
733 REQUEST(xShapeSelectInputReq
);
735 ShapeEventPtr pShapeEvent
, pNewShapeEvent
, *pHead
;
739 REQUEST_SIZE_MATCH(xShapeSelectInputReq
);
740 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixReceiveAccess
);
743 rc
= dixLookupResourceByType((pointer
*) &pHead
, pWin
->drawable
.id
,
744 ShapeEventType
, client
, DixWriteAccess
);
745 if (rc
!= Success
&& rc
!= BadValue
)
748 switch (stuff
->enable
) {
752 /* check for existing entry. */
753 for (pShapeEvent
= *pHead
;
754 pShapeEvent
; pShapeEvent
= pShapeEvent
->next
) {
755 if (pShapeEvent
->client
== client
)
760 /* build the entry */
761 pNewShapeEvent
= malloc(sizeof(ShapeEventRec
));
764 pNewShapeEvent
->next
= 0;
765 pNewShapeEvent
->client
= client
;
766 pNewShapeEvent
->window
= pWin
;
768 * add a resource that will be deleted when
769 * the client goes away
771 clientResource
= FakeClientID(client
->index
);
772 pNewShapeEvent
->clientResource
= clientResource
;
773 if (!AddResource(clientResource
, ClientType
, (pointer
) pNewShapeEvent
))
776 * create a resource to contain a pointer to the list
777 * of clients selecting input. This must be indirect as
778 * the list may be arbitrarily rearranged which cannot be
779 * done through the resource database.
782 pHead
= malloc(sizeof(ShapeEventPtr
));
784 !AddResource(pWin
->drawable
.id
, ShapeEventType
,
786 FreeResource(clientResource
, RT_NONE
);
791 pNewShapeEvent
->next
= *pHead
;
792 *pHead
= pNewShapeEvent
;
795 /* delete the interest */
798 for (pShapeEvent
= *pHead
; pShapeEvent
;
799 pShapeEvent
= pShapeEvent
->next
) {
800 if (pShapeEvent
->client
== client
)
802 pNewShapeEvent
= pShapeEvent
;
805 FreeResource(pShapeEvent
->clientResource
, ClientType
);
807 pNewShapeEvent
->next
= pShapeEvent
->next
;
809 *pHead
= pShapeEvent
->next
;
815 client
->errorValue
= stuff
->enable
;
826 SendShapeNotify(WindowPtr pWin
, int which
)
828 ShapeEventPtr
*pHead
, pShapeEvent
;
834 rc
= dixLookupResourceByType((pointer
*) &pHead
, pWin
->drawable
.id
,
835 ShapeEventType
, serverClient
, DixReadAccess
);
840 region
= wBoundingShape(pWin
);
842 extents
= *RegionExtents(region
);
846 extents
.x1
= -wBorderWidth(pWin
);
847 extents
.y1
= -wBorderWidth(pWin
);
848 extents
.x2
= pWin
->drawable
.width
+ wBorderWidth(pWin
);
849 extents
.y2
= pWin
->drawable
.height
+ wBorderWidth(pWin
);
854 region
= wClipShape(pWin
);
856 extents
= *RegionExtents(region
);
862 extents
.x2
= pWin
->drawable
.width
;
863 extents
.y2
= pWin
->drawable
.height
;
868 region
= wInputShape(pWin
);
870 extents
= *RegionExtents(region
);
874 extents
.x1
= -wBorderWidth(pWin
);
875 extents
.y1
= -wBorderWidth(pWin
);
876 extents
.x2
= pWin
->drawable
.width
+ wBorderWidth(pWin
);
877 extents
.y2
= pWin
->drawable
.height
+ wBorderWidth(pWin
);
884 for (pShapeEvent
= *pHead
; pShapeEvent
; pShapeEvent
= pShapeEvent
->next
) {
885 xShapeNotifyEvent se
= {
886 .type
= ShapeNotify
+ ShapeEventBase
,
888 .window
= pWin
->drawable
.id
,
891 .width
= extents
.x2
- extents
.x1
,
892 .height
= extents
.y2
- extents
.y1
,
893 .time
= currentTime
.milliseconds
,
896 WriteEventsToClient(pShapeEvent
->client
, 1, (xEvent
*) &se
);
901 ProcShapeInputSelected(ClientPtr client
)
903 REQUEST(xShapeInputSelectedReq
);
905 ShapeEventPtr pShapeEvent
, *pHead
;
907 xShapeInputSelectedReply rep
;
909 REQUEST_SIZE_MATCH(xShapeInputSelectedReq
);
910 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixGetAttrAccess
);
913 rc
= dixLookupResourceByType((pointer
*) &pHead
, pWin
->drawable
.id
,
914 ShapeEventType
, client
, DixReadAccess
);
915 if (rc
!= Success
&& rc
!= BadValue
)
919 for (pShapeEvent
= *pHead
; pShapeEvent
; pShapeEvent
= pShapeEvent
->next
) {
920 if (pShapeEvent
->client
== client
) {
926 rep
= (xShapeInputSelectedReply
) {
929 .sequenceNumber
= client
->sequence
,
932 if (client
->swapped
) {
933 swaps(&rep
.sequenceNumber
);
936 WriteToClient(client
, sizeof(xShapeInputSelectedReply
), &rep
);
941 ProcShapeGetRectangles(ClientPtr client
)
943 REQUEST(xShapeGetRectanglesReq
);
945 xShapeGetRectanglesReply rep
;
950 REQUEST_SIZE_MATCH(xShapeGetRectanglesReq
);
951 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixGetAttrAccess
);
954 switch (stuff
->kind
) {
956 region
= wBoundingShape(pWin
);
959 region
= wClipShape(pWin
);
962 region
= wInputShape(pWin
);
965 client
->errorValue
= stuff
->kind
;
970 rects
= malloc(sizeof(xRectangle
));
973 switch (stuff
->kind
) {
975 rects
->x
= -(int) wBorderWidth(pWin
);
976 rects
->y
= -(int) wBorderWidth(pWin
);
977 rects
->width
= pWin
->drawable
.width
+ wBorderWidth(pWin
);
978 rects
->height
= pWin
->drawable
.height
+ wBorderWidth(pWin
);
983 rects
->width
= pWin
->drawable
.width
;
984 rects
->height
= pWin
->drawable
.height
;
987 rects
->x
= -(int) wBorderWidth(pWin
);
988 rects
->y
= -(int) wBorderWidth(pWin
);
989 rects
->width
= pWin
->drawable
.width
+ wBorderWidth(pWin
);
990 rects
->height
= pWin
->drawable
.height
+ wBorderWidth(pWin
);
997 nrects
= RegionNumRects(region
);
998 box
= RegionRects(region
);
999 rects
= malloc(nrects
* sizeof(xRectangle
));
1000 if (!rects
&& nrects
)
1002 for (i
= 0; i
< nrects
; i
++, box
++) {
1003 rects
[i
].x
= box
->x1
;
1004 rects
[i
].y
= box
->y1
;
1005 rects
[i
].width
= box
->x2
- box
->x1
;
1006 rects
[i
].height
= box
->y2
- box
->y1
;
1009 rep
= (xShapeGetRectanglesReply
) {
1011 .ordering
= YXBanded
,
1012 .sequenceNumber
= client
->sequence
,
1013 .length
= bytes_to_int32(nrects
* sizeof(xRectangle
)),
1016 if (client
->swapped
) {
1017 swaps(&rep
.sequenceNumber
);
1020 SwapShorts((short *) rects
, (unsigned long) nrects
* 4);
1022 WriteToClient(client
, sizeof(rep
), &rep
);
1023 WriteToClient(client
, nrects
* sizeof(xRectangle
), rects
);
1029 ProcShapeDispatch(ClientPtr client
)
1032 switch (stuff
->data
) {
1033 case X_ShapeQueryVersion
:
1034 return ProcShapeQueryVersion(client
);
1035 case X_ShapeRectangles
:
1037 if (!noPanoramiXExtension
)
1038 return ProcPanoramiXShapeRectangles(client
);
1041 return ProcShapeRectangles(client
);
1044 if (!noPanoramiXExtension
)
1045 return ProcPanoramiXShapeMask(client
);
1048 return ProcShapeMask(client
);
1049 case X_ShapeCombine
:
1051 if (!noPanoramiXExtension
)
1052 return ProcPanoramiXShapeCombine(client
);
1055 return ProcShapeCombine(client
);
1058 if (!noPanoramiXExtension
)
1059 return ProcPanoramiXShapeOffset(client
);
1062 return ProcShapeOffset(client
);
1063 case X_ShapeQueryExtents
:
1064 return ProcShapeQueryExtents(client
);
1065 case X_ShapeSelectInput
:
1066 return ProcShapeSelectInput(client
);
1067 case X_ShapeInputSelected
:
1068 return ProcShapeInputSelected(client
);
1069 case X_ShapeGetRectangles
:
1070 return ProcShapeGetRectangles(client
);
1077 SShapeNotifyEvent(xShapeNotifyEvent
* from
, xShapeNotifyEvent
* to
)
1079 to
->type
= from
->type
;
1080 to
->kind
= from
->kind
;
1081 cpswapl(from
->window
, to
->window
);
1082 cpswaps(from
->sequenceNumber
, to
->sequenceNumber
);
1083 cpswaps(from
->x
, to
->x
);
1084 cpswaps(from
->y
, to
->y
);
1085 cpswaps(from
->width
, to
->width
);
1086 cpswaps(from
->height
, to
->height
);
1087 cpswapl(from
->time
, to
->time
);
1088 to
->shaped
= from
->shaped
;
1092 SProcShapeQueryVersion(ClientPtr client
)
1094 REQUEST(xShapeQueryVersionReq
);
1096 swaps(&stuff
->length
);
1097 return ProcShapeQueryVersion(client
);
1101 SProcShapeRectangles(ClientPtr client
)
1103 REQUEST(xShapeRectanglesReq
);
1105 swaps(&stuff
->length
);
1106 REQUEST_AT_LEAST_SIZE(xShapeRectanglesReq
);
1107 swapl(&stuff
->dest
);
1108 swaps(&stuff
->xOff
);
1109 swaps(&stuff
->yOff
);
1111 return ProcShapeRectangles(client
);
1115 SProcShapeMask(ClientPtr client
)
1117 REQUEST(xShapeMaskReq
);
1119 swaps(&stuff
->length
);
1120 REQUEST_SIZE_MATCH(xShapeMaskReq
);
1121 swapl(&stuff
->dest
);
1122 swaps(&stuff
->xOff
);
1123 swaps(&stuff
->yOff
);
1125 return ProcShapeMask(client
);
1129 SProcShapeCombine(ClientPtr client
)
1131 REQUEST(xShapeCombineReq
);
1133 swaps(&stuff
->length
);
1134 REQUEST_SIZE_MATCH(xShapeCombineReq
);
1135 swapl(&stuff
->dest
);
1136 swaps(&stuff
->xOff
);
1137 swaps(&stuff
->yOff
);
1139 return ProcShapeCombine(client
);
1143 SProcShapeOffset(ClientPtr client
)
1145 REQUEST(xShapeOffsetReq
);
1147 swaps(&stuff
->length
);
1148 REQUEST_SIZE_MATCH(xShapeOffsetReq
);
1149 swapl(&stuff
->dest
);
1150 swaps(&stuff
->xOff
);
1151 swaps(&stuff
->yOff
);
1152 return ProcShapeOffset(client
);
1156 SProcShapeQueryExtents(ClientPtr client
)
1158 REQUEST(xShapeQueryExtentsReq
);
1160 swaps(&stuff
->length
);
1161 REQUEST_SIZE_MATCH(xShapeQueryExtentsReq
);
1162 swapl(&stuff
->window
);
1163 return ProcShapeQueryExtents(client
);
1167 SProcShapeSelectInput(ClientPtr client
)
1169 REQUEST(xShapeSelectInputReq
);
1171 swaps(&stuff
->length
);
1172 REQUEST_SIZE_MATCH(xShapeSelectInputReq
);
1173 swapl(&stuff
->window
);
1174 return ProcShapeSelectInput(client
);
1178 SProcShapeInputSelected(ClientPtr client
)
1180 REQUEST(xShapeInputSelectedReq
);
1182 swaps(&stuff
->length
);
1183 REQUEST_SIZE_MATCH(xShapeInputSelectedReq
);
1184 swapl(&stuff
->window
);
1185 return ProcShapeInputSelected(client
);
1189 SProcShapeGetRectangles(ClientPtr client
)
1191 REQUEST(xShapeGetRectanglesReq
);
1192 swaps(&stuff
->length
);
1193 REQUEST_SIZE_MATCH(xShapeGetRectanglesReq
);
1194 swapl(&stuff
->window
);
1195 return ProcShapeGetRectangles(client
);
1199 SProcShapeDispatch(ClientPtr client
)
1202 switch (stuff
->data
) {
1203 case X_ShapeQueryVersion
:
1204 return SProcShapeQueryVersion(client
);
1205 case X_ShapeRectangles
:
1206 return SProcShapeRectangles(client
);
1208 return SProcShapeMask(client
);
1209 case X_ShapeCombine
:
1210 return SProcShapeCombine(client
);
1212 return SProcShapeOffset(client
);
1213 case X_ShapeQueryExtents
:
1214 return SProcShapeQueryExtents(client
);
1215 case X_ShapeSelectInput
:
1216 return SProcShapeSelectInput(client
);
1217 case X_ShapeInputSelected
:
1218 return SProcShapeInputSelected(client
);
1219 case X_ShapeGetRectangles
:
1220 return SProcShapeGetRectangles(client
);
1227 ShapeExtensionInit(void)
1229 ExtensionEntry
*extEntry
;
1231 ClientType
= CreateNewResourceType(ShapeFreeClient
, "ShapeClient");
1232 ShapeEventType
= CreateNewResourceType(ShapeFreeEvents
, "ShapeEvent");
1233 if (ClientType
&& ShapeEventType
&&
1234 (extEntry
= AddExtension(SHAPENAME
, ShapeNumberEvents
, 0,
1235 ProcShapeDispatch
, SProcShapeDispatch
,
1236 NULL
, StandardMinorOpcode
))) {
1237 ShapeEventBase
= extEntry
->eventBase
;
1238 EventSwapVector
[ShapeEventBase
] = (EventSwapPtr
) SShapeNotifyEvent
;