1
/* $XFree86: xc/programs/Xserver/dix/gc.c,v 3.9 2001/12/14 19:59:32 dawes Exp $ */
2
/***********************************************************
4
Copyright 1987, 1998 The Open Group
6
Permission to use, copy, modify, distribute, and sell this software and its
7
documentation for any purpose is hereby granted without fee, provided that
8
the above copyright notice appear in all copies and that both that
9
copyright notice and this permission notice appear in supporting
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
OPEN GROUP 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 Open Group 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 Open Group.
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
/* $Xorg: gc.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
51
#ifdef HAVE_DIX_CONFIG_H
52
#include <dix-config.h>
57
#include <X11/Xproto.h>
61
#include "pixmapstr.h"
62
#include "dixfontstr.h"
63
#include "scrnintstr.h"
69
extern XID clientErrorValue;
70
extern FontPtr defaultFont;
72
static Bool CreateDefaultTile(GCPtr pGC);
74
unsigned char DefaultDash[2] = {4, 4};
77
ValidateGC(DrawablePtr pDraw, GC *pGC)
79
(*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw);
80
pGC->stateChanges = 0;
81
pGC->serialNumber = pDraw->serialNumber;
85
/* dixChangeGC(client, pGC, mask, pC32, pUnion)
87
* This function was created as part of the Security extension
88
* implementation. The client performing the gc change must be passed so
89
* that access checks can be performed on any tiles, stipples, or fonts
90
* that are specified. ddxen can call this too; they should normally
91
* pass NullClient for the client since any access checking should have
92
* already been done at a higher level.
94
* Since we had to create a new function anyway, we decided to change the
95
* way the list of gc values is passed to eliminate the compiler warnings
96
* caused by the DoChangeGC interface. You can pass the values via pC32
97
* or pUnion, but not both; one of them must be NULL. If you don't need
98
* to pass any pointers, you can use either one:
100
* example calling dixChangeGC using pC32 parameter
105
* dixChangeGC(client, pGC, GCForeground|GCBackground, v, NULL);
107
* example calling dixChangeGC using pUnion parameter;
108
* same effect as above
111
* v[0].val = foreground;
112
* v[1].val = background;
113
* dixChangeGC(client, pGC, GCForeground|GCBackground, NULL, v);
115
* However, if you need to pass a pointer to a pixmap or font, you MUST
116
* use the pUnion parameter.
118
* example calling dixChangeGC passing pointers in the value list
119
* v[1].ptr is a pointer to a pixmap
122
* v[0].val = FillTiled;
123
* v[1].ptr = pPixmap;
124
* dixChangeGC(client, pGC, GCFillStyle|GCTile, NULL, v);
126
* Note: we could have gotten by with just the pUnion parameter, but on
127
* 64 bit machines that would have forced us to copy the value list that
128
* comes in the ChangeGC request.
130
* Ideally, we'd change all the DoChangeGC calls to dixChangeGC, but this
131
* is far too many changes to consider at this time, so we've only
132
* changed the ones that caused compiler warnings. New code should use
138
#define NEXTVAL(_type, _var) { \
139
if (pC32) _var = (_type)*pC32++; \
141
_var = (_type)(pUnion->val); pUnion++; \
145
#define NEXT_PTR(_type, _var) { \
146
assert(pUnion); _var = (_type)pUnion->ptr; pUnion++; }
149
dixChangeGC(ClientPtr client, register GC *pGC, register BITS32 mask, CARD32 *pC32, ChangeGCValPtr pUnion)
151
register BITS32 index2;
152
register int error = 0;
156
assert( (pC32 && !pUnion) || (!pC32 && pUnion) );
157
pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
159
maskQ = mask; /* save these for when we walk the GCque */
160
while (mask && !error)
162
index2 = (BITS32) lowbit (mask);
164
pGC->stateChanges |= index2;
170
NEXTVAL(CARD8, newalu);
175
clientErrorValue = newalu;
181
NEXTVAL(unsigned long, pGC->planemask);
184
NEXTVAL(unsigned long, pGC->fgPixel);
186
* this is for CreateGC
188
if (!pGC->tileIsPixel && !pGC->tile.pixmap)
190
pGC->tileIsPixel = TRUE;
191
pGC->tile.pixel = pGC->fgPixel;
195
NEXTVAL(unsigned long, pGC->bgPixel);
197
case GCLineWidth: /* ??? line width is a CARD16 */
198
NEXTVAL(CARD16, pGC->lineWidth);
202
unsigned int newlinestyle;
203
NEXTVAL(unsigned int, newlinestyle);
204
if (newlinestyle <= LineDoubleDash)
205
pGC->lineStyle = newlinestyle;
208
clientErrorValue = newlinestyle;
215
unsigned int newcapstyle;
216
NEXTVAL(unsigned int, newcapstyle);
217
if (newcapstyle <= CapProjecting)
218
pGC->capStyle = newcapstyle;
221
clientErrorValue = newcapstyle;
228
unsigned int newjoinstyle;
229
NEXTVAL(unsigned int, newjoinstyle);
230
if (newjoinstyle <= JoinBevel)
231
pGC->joinStyle = newjoinstyle;
234
clientErrorValue = newjoinstyle;
241
unsigned int newfillstyle;
242
NEXTVAL(unsigned int, newfillstyle);
243
if (newfillstyle <= FillOpaqueStippled)
244
pGC->fillStyle = newfillstyle;
247
clientErrorValue = newfillstyle;
254
unsigned int newfillrule;
255
NEXTVAL(unsigned int, newfillrule);
256
if (newfillrule <= WindingRule)
257
pGC->fillRule = newfillrule;
260
clientErrorValue = newfillrule;
270
NEXT_PTR(PixmapPtr, pPixmap);
274
NEXTVAL(XID, newpix);
275
pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
276
newpix, RT_PIXMAP, SecurityReadAccess);
280
if ((pPixmap->drawable.depth != pGC->depth) ||
281
(pPixmap->drawable.pScreen != pGC->pScreen))
288
if (!pGC->tileIsPixel)
289
(* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
290
pGC->tileIsPixel = FALSE;
291
pGC->tile.pixmap = pPixmap;
296
clientErrorValue = newpix;
306
NEXT_PTR(PixmapPtr, pPixmap);
310
NEXTVAL(XID, newstipple)
311
pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
312
newstipple, RT_PIXMAP, SecurityReadAccess);
316
if ((pPixmap->drawable.depth != 1) ||
317
(pPixmap->drawable.pScreen != pGC->pScreen))
325
(* pGC->pScreen->DestroyPixmap)(pGC->stipple);
326
pGC->stipple = pPixmap;
331
clientErrorValue = newstipple;
336
case GCTileStipXOrigin:
337
NEXTVAL(INT16, pGC->patOrg.x);
339
case GCTileStipYOrigin:
340
NEXTVAL(INT16, pGC->patOrg.y);
348
NEXT_PTR(FontPtr, pFont);
352
NEXTVAL(XID, newfont)
353
pFont = (FontPtr)SecurityLookupIDByType(client, newfont,
354
RT_FONT, SecurityReadAccess);
360
CloseFont(pGC->font, (Font)0);
365
clientErrorValue = newfont;
370
case GCSubwindowMode:
372
unsigned int newclipmode;
373
NEXTVAL(unsigned int, newclipmode);
374
if (newclipmode <= IncludeInferiors)
375
pGC->subWindowMode = newclipmode;
378
clientErrorValue = newclipmode;
383
case GCGraphicsExposures:
386
NEXTVAL(unsigned int, newge);
388
pGC->graphicsExposures = newge;
391
clientErrorValue = newge;
397
NEXTVAL(INT16, pGC->clipOrg.x);
400
NEXTVAL(INT16, pGC->clipOrg.y);
409
NEXT_PTR(PixmapPtr, pPixmap);
417
pPixmap = NullPixmap;
420
pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
421
pid, RT_PIXMAP, SecurityReadAccess);
426
if ((pPixmap->drawable.depth != 1) ||
427
(pPixmap->drawable.pScreen != pGC->pScreen))
433
clipType = CT_PIXMAP;
437
else if (!pUnion && (pid != None))
439
clientErrorValue = pid;
444
(*pGC->funcs->ChangeClip)(pGC, clipType,
445
(pointer)pPixmap, 0);
450
NEXTVAL(INT16, pGC->dashOffset);
455
NEXTVAL(CARD8, newdash);
458
if (pGC->dash != DefaultDash)
461
pGC->numInDashList = 2;
462
pGC->dash = DefaultDash;
465
else if (newdash != 0)
469
dash = (unsigned char *)xalloc(2 * sizeof(unsigned char));
472
if (pGC->dash != DefaultDash)
474
pGC->numInDashList = 2;
484
clientErrorValue = newdash;
491
unsigned int newarcmode;
492
NEXTVAL(unsigned int, newarcmode);
493
if (newarcmode <= ArcPieSlice)
494
pGC->arcMode = newarcmode;
497
clientErrorValue = newarcmode;
503
clientErrorValue = maskQ;
507
} /* end while mask && !error */
509
if (pGC->fillStyle == FillTiled && pGC->tileIsPixel)
511
if (!CreateDefaultTile (pGC))
513
pGC->fillStyle = FillSolid;
517
(*pGC->funcs->ChangeGC)(pGC, maskQ);
524
/* Publically defined entry to ChangeGC. Just calls dixChangeGC and tells
525
* it that all of the entries are constants or IDs */
527
ChangeGC(register GC *pGC, register BITS32 mask, XID *pval)
529
return (dixChangeGC(NullClient, pGC, mask, pval, NULL));
532
/* DoChangeGC(pGC, mask, pval, fPointer)
533
mask is a set of bits indicating which values to change.
534
pval contains an appropriate value for each mask.
535
fPointer is true if the values for tiles, stipples, fonts or clipmasks
536
are pointers instead of IDs. Note: if you are passing pointers you
537
MUST declare the array of values as type pointer! Other data types
538
may not be large enough to hold pointers on some machines. Yes,
539
this means you have to cast to (XID *) when you pass the array to
540
DoChangeGC. Similarly, if you are not passing pointers (fPointer = 0) you
541
MUST declare the array as type XID (not unsigned long!), or again the wrong
542
size data type may be used. To avoid this cruftiness, use dixChangeGC
545
if there is an error, the value is marked as changed
546
anyway, which is probably wrong, but infrequent.
549
all values sent over the protocol for ChangeGC requests are
553
DoChangeGC(register GC *pGC, register BITS32 mask, XID *pval, int fPointer)
556
/* XXX might be a problem on 64 bit big-endian servers */
557
return dixChangeGC(NullClient, pGC, mask, NULL, (ChangeGCValPtr)pval);
559
return dixChangeGC(NullClient, pGC, mask, pval, NULL);
563
/* CreateGC(pDrawable, mask, pval, pStatus)
564
creates a default GC for the given drawable, using mask to fill
565
in any non-default values.
566
Returns a pointer to the new GC on success, NULL otherwise.
567
returns status of non-default fields in pStatus
569
should check for failure to create default tile
574
AllocateGC(ScreenPtr pScreen)
578
register DevUnion *ppriv;
579
register unsigned *sizes;
580
register unsigned size;
583
pGC = (GCPtr)xalloc(pScreen->totalGCSize);
586
ppriv = (DevUnion *)(pGC + 1);
587
pGC->devPrivates = ppriv;
588
sizes = pScreen->GCPrivateSizes;
589
ptr = (char *)(ppriv + pScreen->GCPrivateLen);
590
for (i = pScreen->GCPrivateLen; --i >= 0; ppriv++, sizes++)
592
if ( (size = *sizes) )
594
ppriv->ptr = (pointer)ptr;
598
ppriv->ptr = (pointer)NULL;
605
CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus)
609
pGC = AllocateGC(pDrawable->pScreen);
616
pGC->pScreen = pDrawable->pScreen;
617
pGC->depth = pDrawable->depth;
618
pGC->alu = GXcopy; /* dst <- src */
620
pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
626
pGC->lineStyle = LineSolid;
627
pGC->capStyle = CapButt;
628
pGC->joinStyle = JoinMiter;
629
pGC->fillStyle = FillSolid;
630
pGC->fillRule = EvenOddRule;
631
pGC->arcMode = ArcPieSlice;
632
if (mask & GCForeground)
635
* magic special case -- ChangeGC checks for this condition
636
* and snags the Foreground value to create a pseudo default-tile
638
pGC->tileIsPixel = FALSE;
639
pGC->tile.pixmap = NullPixmap;
643
pGC->tileIsPixel = TRUE;
649
pGC->subWindowMode = ClipByChildren;
650
pGC->graphicsExposures = TRUE;
653
pGC->clientClipType = CT_NONE;
654
pGC->clientClip = (pointer)NULL;
655
pGC->numInDashList = 2;
656
pGC->dash = DefaultDash;
658
pGC->lastWinOrg.x = 0;
659
pGC->lastWinOrg.y = 0;
661
/* use the default font and stipple */
662
pGC->font = defaultFont;
663
defaultFont->refcnt++;
664
pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
665
pGC->stipple->refcnt++;
667
pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
668
if (!(*pGC->pScreen->CreateGC)(pGC))
671
*pStatus = ChangeGC(pGC, mask, pval);
674
if (*pStatus != Success)
676
if (!pGC->tileIsPixel && !pGC->tile.pixmap)
677
pGC->tileIsPixel = TRUE; /* undo special case */
686
CreateDefaultTile (GCPtr pGC)
696
(*pGC->pScreen->QueryBestSize)(TileShape, &w, &h, pGC->pScreen);
698
(*pGC->pScreen->CreatePixmap)(pGC->pScreen,
700
pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen);
701
if (!pTile || !pgcScratch)
704
(*pTile->drawable.pScreen->DestroyPixmap)(pTile);
706
FreeScratchGC(pgcScratch);
710
tmpval[1] = pGC->tile.pixel;
711
tmpval[2] = FillSolid;
712
(void)ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle,
714
ValidateGC((DrawablePtr)pTile, pgcScratch);
719
(*pgcScratch->ops->PolyFillRect)((DrawablePtr)pTile, pgcScratch, 1, &rect);
720
/* Always remember to free the scratch graphics context after use. */
721
FreeScratchGC(pgcScratch);
723
pGC->tileIsPixel = FALSE;
724
pGC->tile.pixmap = pTile;
729
CopyGC(register GC *pgcSrc, register GC *pgcDst, register BITS32 mask)
731
register BITS32 index2;
735
if (pgcSrc == pgcDst)
737
pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
738
pgcDst->stateChanges |= mask;
742
index2 = (BITS32) lowbit (mask);
747
pgcDst->alu = pgcSrc->alu;
750
pgcDst->planemask = pgcSrc->planemask;
753
pgcDst->fgPixel = pgcSrc->fgPixel;
756
pgcDst->bgPixel = pgcSrc->bgPixel;
759
pgcDst->lineWidth = pgcSrc->lineWidth;
762
pgcDst->lineStyle = pgcSrc->lineStyle;
765
pgcDst->capStyle = pgcSrc->capStyle;
768
pgcDst->joinStyle = pgcSrc->joinStyle;
771
pgcDst->fillStyle = pgcSrc->fillStyle;
774
pgcDst->fillRule = pgcSrc->fillRule;
778
if (EqualPixUnion(pgcDst->tileIsPixel,
785
if (!pgcDst->tileIsPixel)
786
(* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile.pixmap);
787
pgcDst->tileIsPixel = pgcSrc->tileIsPixel;
788
pgcDst->tile = pgcSrc->tile;
789
if (!pgcDst->tileIsPixel)
790
pgcDst->tile.pixmap->refcnt++;
795
if (pgcDst->stipple == pgcSrc->stipple)
798
(* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple);
799
pgcDst->stipple = pgcSrc->stipple;
801
pgcDst->stipple->refcnt ++;
804
case GCTileStipXOrigin:
805
pgcDst->patOrg.x = pgcSrc->patOrg.x;
807
case GCTileStipYOrigin:
808
pgcDst->patOrg.y = pgcSrc->patOrg.y;
811
if (pgcDst->font == pgcSrc->font)
814
CloseFont(pgcDst->font, (Font)0);
815
if ((pgcDst->font = pgcSrc->font) != NullFont)
816
(pgcDst->font)->refcnt++;
818
case GCSubwindowMode:
819
pgcDst->subWindowMode = pgcSrc->subWindowMode;
821
case GCGraphicsExposures:
822
pgcDst->graphicsExposures = pgcSrc->graphicsExposures;
825
pgcDst->clipOrg.x = pgcSrc->clipOrg.x;
828
pgcDst->clipOrg.y = pgcSrc->clipOrg.y;
831
(* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
834
pgcDst->dashOffset = pgcSrc->dashOffset;
837
if (pgcSrc->dash == DefaultDash)
839
if (pgcDst->dash != DefaultDash)
842
pgcDst->numInDashList = pgcSrc->numInDashList;
843
pgcDst->dash = pgcSrc->dash;
851
dash = (unsigned char *)xalloc(pgcSrc->numInDashList *
852
sizeof(unsigned char));
855
if (pgcDst->dash != DefaultDash)
857
pgcDst->numInDashList = pgcSrc->numInDashList;
859
for (i=0; i<pgcSrc->numInDashList; i++)
860
dash[i] = pgcSrc->dash[i];
867
pgcDst->arcMode = pgcSrc->arcMode;
870
clientErrorValue = maskQ;
875
if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel)
877
if (!CreateDefaultTile (pgcDst))
879
pgcDst->fillStyle = FillSolid;
883
(*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst);
888
* does the diX part of freeing the characteristics in the GC.
890
* \param value must conform to DeleteType
893
FreeGC(pointer value, XID gid)
895
GCPtr pGC = (GCPtr)value;
897
CloseFont(pGC->font, (Font)0);
898
(* pGC->funcs->DestroyClip)(pGC);
900
if (!pGC->tileIsPixel)
901
(* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
903
(* pGC->pScreen->DestroyPixmap)(pGC->stipple);
905
(*pGC->funcs->DestroyGC) (pGC);
906
if (pGC->dash != DefaultDash)
913
SetGCMask(GCPtr pGC, Mask selectMask, Mask newDataMask)
915
pGC->stateChanges = (~selectMask & pGC->stateChanges) |
916
(selectMask & newDataMask);
917
if (selectMask & newDataMask)
918
pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
923
/* CreateScratchGC(pScreen, depth)
924
like CreateGC, but doesn't do the default tile or stipple,
925
since we can't create them without already having a GC. any code
926
using the tile or stipple has to set them explicitly anyway,
927
since the state of the scratch gc is unknown. This is OK
928
because ChangeGC() has to be able to deal with NULL tiles and
929
stipples anyway (in case the CreateGC() call has provided a
930
value for them -- we can't set the default tile until the
931
client-supplied attributes are installed, since the fgPixel
932
is what fills the default tile. (maybe this comment should
933
go with CreateGC() or ChangeGC().)
937
CreateScratchGC(ScreenPtr pScreen, unsigned depth)
941
pGC = AllocateGC(pScreen);
945
pGC->pScreen = pScreen;
947
pGC->alu = GXcopy; /* dst <- src */
949
pGC->serialNumber = 0;
954
pGC->lineStyle = LineSolid;
955
pGC->capStyle = CapButt;
956
pGC->joinStyle = JoinMiter;
957
pGC->fillStyle = FillSolid;
958
pGC->fillRule = EvenOddRule;
959
pGC->arcMode = ArcPieSlice;
960
pGC->font = defaultFont;
961
if ( pGC->font) /* necessary, because open of default font could fail */
963
pGC->tileIsPixel = TRUE;
965
pGC->stipple = NullPixmap;
968
pGC->subWindowMode = ClipByChildren;
969
pGC->graphicsExposures = TRUE;
972
pGC->clientClipType = CT_NONE;
974
pGC->numInDashList = 2;
975
pGC->dash = DefaultDash;
976
pGC->lastWinOrg.x = 0;
977
pGC->lastWinOrg.y = 0;
979
pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
980
if (!(*pScreen->CreateGC)(pGC))
989
FreeGCperDepth(int screenNum)
992
register ScreenPtr pScreen;
995
pScreen = screenInfo.screens[screenNum];
996
ppGC = pScreen->GCperDepth;
998
for (i = 0; i <= pScreen->numDepths; i++)
999
(void)FreeGC(ppGC[i], (XID)0);
1005
CreateGCperDepth(int screenNum)
1008
register ScreenPtr pScreen;
1012
pScreen = screenInfo.screens[screenNum];
1014
ppGC = pScreen->GCperDepth;
1015
/* do depth 1 separately because it's not included in list */
1016
if (!(ppGC[0] = CreateScratchGC(pScreen, 1)))
1018
ppGC[0]->graphicsExposures = FALSE;
1019
/* Make sure we don't overflow GCperDepth[] */
1020
if( pScreen->numDepths > MAXFORMATS )
1023
pDepth = pScreen->allowedDepths;
1024
for (i=0; i<pScreen->numDepths; i++, pDepth++)
1026
if (!(ppGC[i+1] = CreateScratchGC(pScreen, pDepth->depth)))
1029
(void)FreeGC(ppGC[i], (XID)0);
1032
ppGC[i+1]->graphicsExposures = FALSE;
1038
CreateDefaultStipple(int screenNum)
1040
register ScreenPtr pScreen;
1046
pScreen = screenInfo.screens[screenNum];
1050
(* pScreen->QueryBestSize)(StippleShape, &w, &h, pScreen);
1051
if (!(pScreen->PixmapPerDepth[0] =
1052
(*pScreen->CreatePixmap)(pScreen, w, h, 1)))
1054
/* fill stipple with 1 */
1055
tmpval[0] = GXcopy; tmpval[1] = 1; tmpval[2] = FillSolid;
1056
pgcScratch = GetScratchGC(1, pScreen);
1059
(*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
1062
(void)ChangeGC(pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval);
1063
ValidateGC((DrawablePtr)pScreen->PixmapPerDepth[0], pgcScratch);
1068
(*pgcScratch->ops->PolyFillRect)((DrawablePtr)pScreen->PixmapPerDepth[0],
1069
pgcScratch, 1, &rect);
1070
FreeScratchGC(pgcScratch);
1075
FreeDefaultStipple(int screenNum)
1077
ScreenPtr pScreen = screenInfo.screens[screenNum];
1078
(*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
1082
SetDashes(register GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash)
1085
register unsigned char *p, *indash;
1094
/* dash segment must be > 0 */
1095
clientErrorValue = 0;
1101
p = (unsigned char *)xalloc(2 * ndash * sizeof(unsigned char));
1103
p = (unsigned char *)xalloc(ndash * sizeof(unsigned char));
1107
pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
1108
if (offset != pGC->dashOffset)
1110
pGC->dashOffset = offset;
1111
pGC->stateChanges |= GCDashOffset;
1112
maskQ |= GCDashOffset;
1115
if (pGC->dash != DefaultDash)
1117
pGC->numInDashList = ndash;
1121
pGC->numInDashList += ndash;
1129
pGC->stateChanges |= GCDashList;
1130
maskQ |= GCDashList;
1132
if (pGC->funcs->ChangeGC)
1133
(*pGC->funcs->ChangeGC) (pGC, maskQ);
1138
VerifyRectOrder(int nrects, xRectangle *prects, int ordering)
1140
register xRectangle *prectP, *prectN;
1150
for(i = 1, prectP = prects, prectN = prects + 1;
1152
i++, prectP++, prectN++)
1153
if(prectN->y < prectP->y)
1160
for(i = 1, prectP = prects, prectN = prects + 1;
1162
i++, prectP++, prectN++)
1163
if((prectN->y < prectP->y) ||
1164
( (prectN->y == prectP->y) &&
1165
(prectN->x < prectP->x) ) )
1172
for(i = 1, prectP = prects, prectN = prects + 1;
1174
i++, prectP++, prectN++)
1175
if((prectN->y != prectP->y &&
1176
prectN->y < prectP->y + (int) prectP->height) ||
1177
((prectN->y == prectP->y) &&
1178
(prectN->height != prectP->height ||
1179
prectN->x < prectP->x + (int) prectP->width)))
1188
SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects,
1189
xRectangle *prects, int ordering)
1192
xRectangle *prectsNew;
1194
newct = VerifyRectOrder(nrects, prects, ordering);
1197
size = nrects * sizeof(xRectangle);
1198
prectsNew = (xRectangle *) xalloc(size);
1199
if (!prectsNew && size)
1202
pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
1203
pGC->clipOrg.x = xOrigin;
1204
pGC->stateChanges |= GCClipXOrigin;
1206
pGC->clipOrg.y = yOrigin;
1207
pGC->stateChanges |= GCClipYOrigin;
1210
memmove((char *)prectsNew, (char *)prects, size);
1211
(*pGC->funcs->ChangeClip)(pGC, newct, (pointer)prectsNew, nrects);
1212
if (pGC->funcs->ChangeGC)
1213
(*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask);
1219
sets reasonable defaults
1220
if we can get a pre-allocated one, use it and mark it as used.
1221
if we can't, create one out of whole cloth (The Velveteen GC -- if
1222
you use it often enough it will become real.)
1225
GetScratchGC(register unsigned depth, register ScreenPtr pScreen)
1230
for (i=0; i<=pScreen->numDepths; i++)
1231
if ( pScreen->GCperDepth[i]->depth == depth &&
1232
!(pScreen->rgf & (1L << (i+1)))
1235
pScreen->rgf |= (1L << (i+1));
1236
pGC = (pScreen->GCperDepth[i]);
1239
pGC->planemask = ~0;
1240
pGC->serialNumber = 0;
1244
pGC->lineStyle = LineSolid;
1245
pGC->capStyle = CapButt;
1246
pGC->joinStyle = JoinMiter;
1247
pGC->fillStyle = FillSolid;
1248
pGC->fillRule = EvenOddRule;
1249
pGC->arcMode = ArcChord;
1252
pGC->subWindowMode = ClipByChildren;
1253
pGC->graphicsExposures = FALSE;
1256
if (pGC->clientClipType != CT_NONE)
1257
(*pGC->funcs->ChangeClip) (pGC, CT_NONE, NULL, 0);
1258
pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
1261
/* if we make it this far, need to roll our own */
1262
pGC = CreateScratchGC(pScreen, depth);
1264
pGC->graphicsExposures = FALSE;
1269
if the gc to free is in the table of pre-existing ones,
1270
mark it as available.
1271
if not, free it for real
1274
FreeScratchGC(register GCPtr pGC)
1276
register ScreenPtr pScreen = pGC->pScreen;
1279
for (i=0; i<=pScreen->numDepths; i++)
1281
if ( pScreen->GCperDepth[i] == pGC)
1283
pScreen->rgf &= ~(1L << (i+1));
1287
(void)FreeGC(pGC, (GContext)0);