1 /***********************************************************
3 Copyright (c) 1987 X Consortium
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of the X Consortium shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from the X Consortium.
27 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
31 Permission to use, copy, modify, and distribute this software and its
32 documentation for any purpose and without fee is hereby granted,
33 provided that the above copyright notice appear in all copies and that
34 both that copyright notice and this permission notice appear in
35 supporting documentation, and that the name of Digital not be
36 used in advertising or publicity pertaining to distribution of the
37 software without specific, written prior permission.
39 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
47 ******************************************************************/
49 /* $XConsortium: gc.c /main/70 1996/08/01 19:21:09 dpw $ */
50 /* $XFree86: xc/programs/Xserver/dix/gc.c,v 3.4 1996/12/23 06:29:45 dawes Exp $ */
58 #include "pixmapstr.h"
59 #include "dixfontstr.h"
60 #include "scrnintstr.h"
66 extern XID clientErrorValue;
67 extern FontPtr defaultFont;
69 static Bool CreateDefaultTile(
70 #if NeedFunctionPrototypes
75 unsigned char DefaultDash[2] = {4, 4};
78 ValidateGC(pDraw, pGC)
82 (*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw);
83 pGC->stateChanges = 0;
84 pGC->serialNumber = pDraw->serialNumber;
88 /* dixChangeGC(client, pGC, mask, pC32, pUnion)
90 * This function was created as part of the Security extension
91 * implementation. The client performing the gc change must be passed so
92 * that access checks can be performed on any tiles, stipples, or fonts
93 * that are specified. ddxen can call this too; they should normally
94 * pass NullClient for the client since any access checking should have
95 * already been done at a higher level.
97 * Since we had to create a new function anyway, we decided to change the
98 * way the list of gc values is passed to eliminate the compiler warnings
99 * caused by the DoChangeGC interface. You can pass the values via pC32
100 * or pUnion, but not both; one of them must be NULL. If you don't need
101 * to pass any pointers, you can use either one:
103 * /* example calling dixChangeGC using pC32 parameter
107 * dixChangeGC(client, pGC, GCForeground|GCBackground, v, NULL);
109 * /* example calling dixChangeGC using pUnion parameter;
110 * /* same effect as above
112 * v[0].val = foreground;
113 * v[1].val = background;
114 * dixChangeGC(client, pGC, GCForeground|GCBackground, NULL, v);
116 * However, if you need to pass a pointer to a pixmap or font, you MUST
117 * use the pUnion parameter.
119 * /* example calling dixChangeGC passing pointers in the value list
121 * v[0].val = FillTiled;
122 * v[1].ptr = pPixmap; /* pointer to a pixmap
123 * dixChangeGC(client, pGC, GCFillStyle|GCTile, NULL, v);
125 * Note: we could have gotten by with just the pUnion parameter, but on
126 * 64 bit machines that would have forced us to copy the value list that
127 * comes in the ChangeGC request.
129 * Ideally, we'd change all the DoChangeGC calls to dixChangeGC, but this
130 * is far too many changes to consider at this time, so we've only
131 * changed the ones that caused compiler warnings. New code should use
137 #define NEXTVAL(_type, _var) { \
138 if (pC32) _var = (_type)*pC32++; \
140 _var = (_type)(pUnion->val); pUnion++; \
144 #define NEXT_PTR(_type, _var) { \
145 assert(pUnion); _var = (_type)pUnion->ptr; pUnion++; }
148 dixChangeGC(client, pGC, mask, pC32, pUnion)
151 register BITS32 mask;
153 ChangeGCValPtr pUnion;
155 register BITS32 index2;
156 register int error = 0;
160 assert( (pC32 && !pUnion) || (!pC32 && pUnion) );
161 pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
163 maskQ = mask; /* save these for when we walk the GCque */
164 while (mask && !error)
166 index2 = (BITS32) lowbit (mask);
168 pGC->stateChanges |= index2;
174 NEXTVAL(CARD8, newalu);
179 clientErrorValue = newalu;
185 NEXTVAL(unsigned long, pGC->planemask);
188 NEXTVAL(unsigned long, pGC->fgPixel);
190 * this is for CreateGC
192 if (!pGC->tileIsPixel && !pGC->tile.pixmap)
194 pGC->tileIsPixel = TRUE;
195 pGC->tile.pixel = pGC->fgPixel;
199 NEXTVAL(unsigned long, pGC->bgPixel);
201 case GCLineWidth: /* ??? line width is a CARD16 */
202 NEXTVAL(CARD16, pGC->lineWidth);
206 unsigned int newlinestyle;
207 NEXTVAL(unsigned int, newlinestyle);
208 if (newlinestyle <= LineDoubleDash)
209 pGC->lineStyle = newlinestyle;
212 clientErrorValue = newlinestyle;
219 unsigned int newcapstyle;
220 NEXTVAL(unsigned int, newcapstyle);
221 if (newcapstyle <= CapProjecting)
222 pGC->capStyle = newcapstyle;
225 clientErrorValue = newcapstyle;
232 unsigned int newjoinstyle;
233 NEXTVAL(unsigned int, newjoinstyle);
234 if (newjoinstyle <= JoinBevel)
235 pGC->joinStyle = newjoinstyle;
238 clientErrorValue = newjoinstyle;
245 unsigned int newfillstyle;
246 NEXTVAL(unsigned int, newfillstyle);
247 if (newfillstyle <= FillOpaqueStippled)
248 pGC->fillStyle = newfillstyle;
251 clientErrorValue = newfillstyle;
258 unsigned int newfillrule;
259 NEXTVAL(unsigned int, newfillrule);
260 if (newfillrule <= WindingRule)
261 pGC->fillRule = newfillrule;
264 clientErrorValue = newfillrule;
274 NEXT_PTR(PixmapPtr, pPixmap);
278 NEXTVAL(XID, newpix);
279 pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
280 newpix, RT_PIXMAP, SecurityReadAccess);
284 if ((pPixmap->drawable.depth != pGC->depth) ||
285 (pPixmap->drawable.pScreen != pGC->pScreen))
292 if (!pGC->tileIsPixel)
293 (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
294 pGC->tileIsPixel = FALSE;
295 pGC->tile.pixmap = pPixmap;
300 clientErrorValue = newpix;
310 NEXT_PTR(PixmapPtr, pPixmap);
314 NEXTVAL(XID, newstipple)
315 pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
316 newstipple, RT_PIXMAP, SecurityReadAccess);
320 if ((pPixmap->drawable.depth != 1) ||
321 (pPixmap->drawable.pScreen != pGC->pScreen))
329 (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
330 pGC->stipple = pPixmap;
335 clientErrorValue = newstipple;
340 case GCTileStipXOrigin:
341 NEXTVAL(INT16, pGC->patOrg.x);
343 case GCTileStipYOrigin:
344 NEXTVAL(INT16, pGC->patOrg.y);
352 NEXT_PTR(FontPtr, pFont);
356 NEXTVAL(XID, newfont)
357 pFont = (FontPtr)SecurityLookupIDByType(client, newfont,
358 RT_FONT, SecurityReadAccess);
364 CloseFont(pGC->font, (Font)0);
369 clientErrorValue = newfont;
374 case GCSubwindowMode:
376 unsigned int newclipmode;
377 NEXTVAL(unsigned int, newclipmode);
378 if (newclipmode <= IncludeInferiors)
379 pGC->subWindowMode = newclipmode;
382 clientErrorValue = newclipmode;
387 case GCGraphicsExposures:
390 NEXTVAL(unsigned int, newge);
392 pGC->graphicsExposures = newge;
395 clientErrorValue = newge;
401 NEXTVAL(INT16, pGC->clipOrg.x);
404 NEXTVAL(INT16, pGC->clipOrg.y);
413 NEXT_PTR(PixmapPtr, pPixmap);
421 pPixmap = NullPixmap;
424 pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
425 pid, RT_PIXMAP, SecurityReadAccess);
430 if ((pPixmap->drawable.depth != 1) ||
431 (pPixmap->drawable.pScreen != pGC->pScreen))
437 clipType = CT_PIXMAP;
441 else if (!pUnion && (pid != None))
443 clientErrorValue = pid;
448 (*pGC->funcs->ChangeClip)(pGC, clipType,
449 (pointer)pPixmap, 0);
454 NEXTVAL(INT16, pGC->dashOffset);
459 NEXTVAL(CARD8, newdash);
462 if (pGC->dash != DefaultDash)
465 pGC->numInDashList = 2;
466 pGC->dash = DefaultDash;
469 else if (newdash != 0)
473 dash = (unsigned char *)xalloc(2 * sizeof(unsigned char));
476 if (pGC->dash != DefaultDash)
478 pGC->numInDashList = 2;
488 clientErrorValue = newdash;
495 unsigned int newarcmode;
496 NEXTVAL(unsigned int, newarcmode);
497 if (newarcmode <= ArcPieSlice)
498 pGC->arcMode = newarcmode;
501 clientErrorValue = newarcmode;
507 clientErrorValue = maskQ;
511 } /* end while mask && !error */
513 if (pGC->fillStyle == FillTiled && pGC->tileIsPixel)
515 if (!CreateDefaultTile (pGC))
517 pGC->fillStyle = FillSolid;
521 (*pGC->funcs->ChangeGC)(pGC, maskQ);
528 /* Publically defined entry to ChangeGC. Just calls dixChangeGC and tells
529 * it that all of the entries are constants or IDs */
531 ChangeGC(pGC, mask, pval)
533 register BITS32 mask;
536 return (dixChangeGC(NullClient, pGC, mask, pval, NULL));
539 /* DoChangeGC(pGC, mask, pval, fPointer)
540 mask is a set of bits indicating which values to change.
541 pval contains an appropriate value for each mask.
542 fPointer is true if the values for tiles, stipples, fonts or clipmasks
543 are pointers instead of IDs. Note: if you are passing pointers you
544 MUST declare the array of values as type pointer! Other data types
545 may not be large enough to hold pointers on some machines. Yes,
546 this means you have to cast to (XID *) when you pass the array to
547 DoChangeGC. Similarly, if you are not passing pointers (fPointer = 0) you
548 MUST declare the array as type XID (not unsigned long!), or again the wrong
549 size data type may be used. To avoid this cruftiness, use dixChangeGC
552 if there is an error, the value is marked as changed
553 anyway, which is probably wrong, but infrequent.
556 all values sent over the protocol for ChangeGC requests are
560 DoChangeGC(pGC, mask, pval, fPointer)
562 register BITS32 mask;
567 /* XXX might be a problem on 64 bit big-endian servers */
568 dixChangeGC(NullClient, pGC, mask, NULL, (ChangeGCValPtr)pval);
570 dixChangeGC(NullClient, pGC, mask, pval, NULL);
574 /* CreateGC(pDrawable, mask, pval, pStatus)
575 creates a default GC for the given drawable, using mask to fill
576 in any non-default values.
577 Returns a pointer to the new GC on success, NULL otherwise.
578 returns status of non-default fields in pStatus
580 should check for failure to create default tile
585 #if NeedFunctionPrototypes
586 AllocateGC(ScreenPtr pScreen)
594 register DevUnion *ppriv;
595 register unsigned *sizes;
596 register unsigned size;
599 pGC = (GCPtr)xalloc(pScreen->totalGCSize);
602 ppriv = (DevUnion *)(pGC + 1);
603 pGC->devPrivates = ppriv;
604 sizes = pScreen->GCPrivateSizes;
605 ptr = (char *)(ppriv + pScreen->GCPrivateLen);
606 for (i = pScreen->GCPrivateLen; --i >= 0; ppriv++, sizes++)
608 if ( (size = *sizes) )
610 ppriv->ptr = (pointer)ptr;
614 ppriv->ptr = (pointer)NULL;
621 CreateGC(pDrawable, mask, pval, pStatus)
622 DrawablePtr pDrawable;
629 pGC = AllocateGC(pDrawable->pScreen);
636 pGC->pScreen = pDrawable->pScreen;
637 pGC->depth = pDrawable->depth;
638 pGC->alu = GXcopy; /* dst <- src */
640 pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
646 pGC->lineStyle = LineSolid;
647 pGC->capStyle = CapButt;
648 pGC->joinStyle = JoinMiter;
649 pGC->fillStyle = FillSolid;
650 pGC->fillRule = EvenOddRule;
651 pGC->arcMode = ArcPieSlice;
652 if (mask & GCForeground)
655 * magic special case -- ChangeGC checks for this condition
656 * and snags the Foreground value to create a pseudo default-tile
658 pGC->tileIsPixel = FALSE;
659 pGC->tile.pixmap = NullPixmap;
663 pGC->tileIsPixel = TRUE;
669 pGC->subWindowMode = ClipByChildren;
670 pGC->graphicsExposures = TRUE;
673 pGC->clientClipType = CT_NONE;
674 pGC->clientClip = (pointer)NULL;
675 pGC->numInDashList = 2;
676 pGC->dash = DefaultDash;
678 pGC->lastWinOrg.x = 0;
679 pGC->lastWinOrg.y = 0;
681 /* use the default font and stipple */
682 pGC->font = defaultFont;
683 defaultFont->refcnt++;
684 pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
685 pGC->stipple->refcnt++;
687 pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
688 if (!(*pGC->pScreen->CreateGC)(pGC))
691 *pStatus = ChangeGC(pGC, mask, pval);
694 if (*pStatus != Success)
696 if (!pGC->tileIsPixel && !pGC->tile.pixmap)
697 pGC->tileIsPixel = TRUE; /* undo special case */
706 CreateDefaultTile (pGC)
717 (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h, pGC->pScreen);
719 (*pGC->pScreen->CreatePixmap)(pGC->pScreen,
721 pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen);
722 if (!pTile || !pgcScratch)
725 (*pTile->drawable.pScreen->DestroyPixmap)(pTile);
727 FreeScratchGC(pgcScratch);
731 tmpval[1] = pGC->tile.pixel;
732 tmpval[2] = FillSolid;
733 (void)ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle,
735 ValidateGC((DrawablePtr)pTile, pgcScratch);
740 (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pTile, pgcScratch, 1, &rect);
741 /* Always remember to free the scratch graphics context after use. */
742 FreeScratchGC(pgcScratch);
744 pGC->tileIsPixel = FALSE;
745 pGC->tile.pixmap = pTile;
750 CopyGC(pgcSrc, pgcDst, mask)
753 register BITS32 mask;
755 register BITS32 index2;
759 if (pgcSrc == pgcDst)
761 pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
762 pgcDst->stateChanges |= mask;
766 index2 = (BITS32) lowbit (mask);
771 pgcDst->alu = pgcSrc->alu;
774 pgcDst->planemask = pgcSrc->planemask;
777 pgcDst->fgPixel = pgcSrc->fgPixel;
780 pgcDst->bgPixel = pgcSrc->bgPixel;
783 pgcDst->lineWidth = pgcSrc->lineWidth;
786 pgcDst->lineStyle = pgcSrc->lineStyle;
789 pgcDst->capStyle = pgcSrc->capStyle;
792 pgcDst->joinStyle = pgcSrc->joinStyle;
795 pgcDst->fillStyle = pgcSrc->fillStyle;
798 pgcDst->fillRule = pgcSrc->fillRule;
802 if (EqualPixUnion(pgcDst->tileIsPixel,
809 if (!pgcDst->tileIsPixel)
810 (* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile.pixmap);
811 pgcDst->tileIsPixel = pgcSrc->tileIsPixel;
812 pgcDst->tile = pgcSrc->tile;
813 if (!pgcDst->tileIsPixel)
814 pgcDst->tile.pixmap->refcnt++;
819 if (pgcDst->stipple == pgcSrc->stipple)
822 (* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple);
823 pgcDst->stipple = pgcSrc->stipple;
825 pgcDst->stipple->refcnt ++;
828 case GCTileStipXOrigin:
829 pgcDst->patOrg.x = pgcSrc->patOrg.x;
831 case GCTileStipYOrigin:
832 pgcDst->patOrg.y = pgcSrc->patOrg.y;
835 if (pgcDst->font == pgcSrc->font)
838 CloseFont(pgcDst->font, (Font)0);
839 if ((pgcDst->font = pgcSrc->font) != NullFont)
840 (pgcDst->font)->refcnt++;
842 case GCSubwindowMode:
843 pgcDst->subWindowMode = pgcSrc->subWindowMode;
845 case GCGraphicsExposures:
846 pgcDst->graphicsExposures = pgcSrc->graphicsExposures;
849 pgcDst->clipOrg.x = pgcSrc->clipOrg.x;
852 pgcDst->clipOrg.y = pgcSrc->clipOrg.y;
855 (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
858 pgcDst->dashOffset = pgcSrc->dashOffset;
861 if (pgcSrc->dash == DefaultDash)
863 if (pgcDst->dash != DefaultDash)
866 pgcDst->numInDashList = pgcSrc->numInDashList;
867 pgcDst->dash = pgcSrc->dash;
875 dash = (unsigned char *)xalloc(pgcSrc->numInDashList *
876 sizeof(unsigned char));
879 if (pgcDst->dash != DefaultDash)
881 pgcDst->numInDashList = pgcSrc->numInDashList;
883 for (i=0; i<pgcSrc->numInDashList; i++)
884 dash[i] = pgcSrc->dash[i];
891 pgcDst->arcMode = pgcSrc->arcMode;
894 clientErrorValue = maskQ;
899 if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel)
901 if (!CreateDefaultTile (pgcDst))
903 pgcDst->fillStyle = FillSolid;
907 (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst);
913 * does the diX part of freeing the characteristics in the GC
919 pointer value; /* must conform to DeleteType */
922 GCPtr pGC = (GCPtr)value;
924 CloseFont(pGC->font, (Font)0);
925 (* pGC->funcs->DestroyClip)(pGC);
927 if (!pGC->tileIsPixel)
928 (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
930 (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
932 (*pGC->funcs->DestroyGC) (pGC);
933 if (pGC->dash != DefaultDash)
940 SetGCMask(pGC, selectMask, newDataMask)
945 pGC->stateChanges = (~selectMask & pGC->stateChanges) |
946 (selectMask & newDataMask);
947 if (selectMask & newDataMask)
948 pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
953 /* CreateScratchGC(pScreen, depth)
954 like CreateGC, but doesn't do the default tile or stipple,
955 since we can't create them without already having a GC. any code
956 using the tile or stipple has to set them explicitly anyway,
957 since the state of the scratch gc is unknown. This is OK
958 because ChangeGC() has to be able to deal with NULL tiles and
959 stipples anyway (in case the CreateGC() call has provided a
960 value for them -- we can't set the default tile until the
961 client-supplied attributes are installed, since the fgPixel
962 is what fills the default tile. (maybe this comment should
963 go with CreateGC() or ChangeGC().)
967 CreateScratchGC(pScreen, depth)
973 pGC = AllocateGC(pScreen);
977 pGC->pScreen = pScreen;
979 pGC->alu = GXcopy; /* dst <- src */
981 pGC->serialNumber = 0;
986 pGC->lineStyle = LineSolid;
987 pGC->capStyle = CapButt;
988 pGC->joinStyle = JoinMiter;
989 pGC->fillStyle = FillSolid;
990 pGC->fillRule = EvenOddRule;
991 pGC->arcMode = ArcPieSlice;
992 pGC->font = defaultFont;
993 if ( pGC->font) /* necessary, because open of default font could fail */
995 pGC->tileIsPixel = TRUE;
997 pGC->stipple = NullPixmap;
1000 pGC->subWindowMode = ClipByChildren;
1001 pGC->graphicsExposures = TRUE;
1004 pGC->clientClipType = CT_NONE;
1005 pGC->dashOffset = 0;
1006 pGC->numInDashList = 2;
1007 pGC->dash = DefaultDash;
1008 pGC->lastWinOrg.x = 0;
1009 pGC->lastWinOrg.y = 0;
1011 pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
1012 if (!(*pScreen->CreateGC)(pGC))
1014 FreeGC(pGC, (XID)0);
1021 FreeGCperDepth(screenNum)
1025 register ScreenPtr pScreen;
1028 pScreen = screenInfo.screens[screenNum];
1029 ppGC = pScreen->GCperDepth;
1031 for (i = 0; i <= pScreen->numDepths; i++)
1032 (void)FreeGC(ppGC[i], (XID)0);
1038 CreateGCperDepth(screenNum)
1042 register ScreenPtr pScreen;
1046 pScreen = screenInfo.screens[screenNum];
1048 ppGC = pScreen->GCperDepth;
1049 /* do depth 1 separately because it's not included in list */
1050 if (!(ppGC[0] = CreateScratchGC(pScreen, 1)))
1052 ppGC[0]->graphicsExposures = FALSE;
1054 pDepth = pScreen->allowedDepths;
1055 for (i=0; i<pScreen->numDepths; i++, pDepth++)
1057 if (!(ppGC[i+1] = CreateScratchGC(pScreen, pDepth->depth)))
1060 (void)FreeGC(ppGC[i], (XID)0);
1063 ppGC[i+1]->graphicsExposures = FALSE;
1069 CreateDefaultStipple(screenNum)
1072 register ScreenPtr pScreen;
1078 pScreen = screenInfo.screens[screenNum];
1082 (* pScreen->QueryBestSize)(StippleShape, &w, &h, pScreen);
1083 if (!(pScreen->PixmapPerDepth[0] =
1084 (*pScreen->CreatePixmap)(pScreen, w, h, 1)))
1086 /* fill stipple with 1 */
1087 tmpval[0] = GXcopy; tmpval[1] = 1; tmpval[2] = FillSolid;
1088 pgcScratch = GetScratchGC(1, pScreen);
1091 (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
1094 (void)ChangeGC(pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval);
1095 ValidateGC((DrawablePtr)pScreen->PixmapPerDepth[0], pgcScratch);
1100 (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pScreen->PixmapPerDepth[0],
1101 pgcScratch, 1, &rect);
1102 FreeScratchGC(pgcScratch);
1107 FreeDefaultStipple(screenNum)
1110 ScreenPtr pScreen = screenInfo.screens[screenNum];
1111 (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
1115 SetDashes(pGC, offset, ndash, pdash)
1118 register unsigned ndash;
1119 register unsigned char *pdash;
1122 register unsigned char *p, *indash;
1131 /* dash segment must be > 0 */
1132 clientErrorValue = 0;
1138 p = (unsigned char *)xalloc(2 * ndash * sizeof(unsigned char));
1140 p = (unsigned char *)xalloc(ndash * sizeof(unsigned char));
1144 pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
1145 if (offset != pGC->dashOffset)
1147 pGC->dashOffset = offset;
1148 pGC->stateChanges |= GCDashOffset;
1149 maskQ |= GCDashOffset;
1152 if (pGC->dash != DefaultDash)
1154 pGC->numInDashList = ndash;
1158 pGC->numInDashList += ndash;
1166 pGC->stateChanges |= GCDashList;
1167 maskQ |= GCDashList;
1169 if (pGC->funcs->ChangeGC)
1170 (*pGC->funcs->ChangeGC) (pGC, maskQ);
1175 VerifyRectOrder(nrects, prects, ordering)
1180 register xRectangle *prectP, *prectN;
1190 for(i = 1, prectP = prects, prectN = prects + 1;
1192 i++, prectP++, prectN++)
1193 if(prectN->y < prectP->y)
1200 for(i = 1, prectP = prects, prectN = prects + 1;
1202 i++, prectP++, prectN++)
1203 if((prectN->y < prectP->y) ||
1204 ( (prectN->y == prectP->y) &&
1205 (prectN->x < prectP->x) ) )
1212 for(i = 1, prectP = prects, prectN = prects + 1;
1214 i++, prectP++, prectN++)
1215 if((prectN->y != prectP->y &&
1216 prectN->y < prectP->y + (int) prectP->height) ||
1217 ((prectN->y == prectP->y) &&
1218 (prectN->height != prectP->height ||
1219 prectN->x < prectP->x + (int) prectP->width)))
1228 SetClipRects(pGC, xOrigin, yOrigin, nrects, prects, ordering)
1230 int xOrigin, yOrigin;
1236 xRectangle *prectsNew;
1238 newct = VerifyRectOrder(nrects, prects, ordering);
1241 size = nrects * sizeof(xRectangle);
1242 prectsNew = (xRectangle *) xalloc(size);
1243 if (!prectsNew && size)
1246 pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
1247 pGC->clipOrg.x = xOrigin;
1248 pGC->stateChanges |= GCClipXOrigin;
1250 pGC->clipOrg.y = yOrigin;
1251 pGC->stateChanges |= GCClipYOrigin;
1254 memmove((char *)prectsNew, (char *)prects, size);
1255 (*pGC->funcs->ChangeClip)(pGC, newct, (pointer)prectsNew, nrects);
1256 if (pGC->funcs->ChangeGC)
1257 (*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask);
1263 sets reasonable defaults
1264 if we can get a pre-allocated one, use it and mark it as used.
1265 if we can't, create one out of whole cloth (The Velveteen GC -- if
1266 you use it often enough it will become real.)
1269 GetScratchGC(depth, pScreen)
1270 register unsigned depth;
1271 register ScreenPtr pScreen;
1276 for (i=0; i<=pScreen->numDepths; i++)
1277 if ( pScreen->GCperDepth[i]->depth == depth &&
1278 !(pScreen->rgf & (1L << (i+1)))
1281 pScreen->rgf |= (1L << (i+1));
1282 pGC = (pScreen->GCperDepth[i]);
1285 pGC->planemask = ~0;
1286 pGC->serialNumber = 0;
1290 pGC->lineStyle = LineSolid;
1291 pGC->capStyle = CapButt;
1292 pGC->joinStyle = JoinMiter;
1293 pGC->fillStyle = FillSolid;
1294 pGC->fillRule = EvenOddRule;
1295 pGC->arcMode = ArcChord;
1298 pGC->subWindowMode = ClipByChildren;
1299 pGC->graphicsExposures = FALSE;
1302 if (pGC->clientClipType != CT_NONE)
1303 (*pGC->funcs->ChangeClip) (pGC, CT_NONE, NULL, 0);
1304 pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
1307 /* if we make it this far, need to roll our own */
1308 pGC = CreateScratchGC(pScreen, depth);
1310 pGC->graphicsExposures = FALSE;
1315 if the gc to free is in the table of pre-existing ones,
1316 mark it as available.
1317 if not, free it for real
1323 register ScreenPtr pScreen = pGC->pScreen;
1326 for (i=0; i<=pScreen->numDepths; i++)
1328 if ( pScreen->GCperDepth[i] == pGC)
1330 pScreen->rgf &= ~(1L << (i+1));
1334 (void)FreeGC(pGC, (GContext)0);