|
|
1.1 root 1: /***********************************************************
2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
4:
5: All Rights Reserved
6:
7: Permission to use, copy, modify, and distribute this software and its
8: documentation for any purpose and without fee is hereby granted,
9: provided that the above copyright notice appear in all copies and that
10: both that copyright notice and this permission notice appear in
11: supporting documentation, and that the names of Digital or MIT not be
12: used in advertising or publicity pertaining to distribution of the
13: software without specific, written prior permission.
14:
15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21: SOFTWARE.
22:
23: ******************************************************************/
24:
1.1.1.2 ! root 25: /* $Header: gc.c,v 1.96 87/10/03 14:33:48 rws Exp $ */
1.1 root 26:
27: #include "X.h"
28: #include "Xmd.h"
29: #include "Xproto.h"
30: #include "misc.h"
31: #include "resource.h"
32: #include "gcstruct.h"
33: #include "pixmapstr.h"
34: #include "dixfontstr.h"
35: #include "scrnintstr.h"
36: #include "region.h"
37:
38: #include "dix.h"
39:
40: extern int NotImplemented();
41:
42: /* written by drewry august 1986 */
43:
44: void
45: ValidateGC(pDraw, pGC)
46: DrawablePtr pDraw;
47: GC *pGC;
48: {
49: GCInterestPtr pQ, pQInit;
50:
51: pQ = pGC->pNextGCInterest;
52: pQInit = (GCInterestPtr) &pGC->pNextGCInterest;
53: if (pGC->serialNumber != pDraw->serialNumber)
54: pGC->stateChanges |= GC_CALL_VALIDATE_BIT;
55: do
56: {
57: if (pQ->ValInterestMask & pGC->stateChanges)
58: (* pQ->ValidateGC) (pGC, pQ, pGC->stateChanges, pDraw);
59: pQ = pQ->pNextGCInterest;
60: }
61: while(pQ != pQInit);
62: pGC->stateChanges = 0;
63: pGC->serialNumber = pDraw->serialNumber;
64: }
65:
66:
67:
68: /* Publically defined entry to ChangeGC. Just calls DoChangeGC and tells
69: * it that all of the entries are constants or IDs */
70: ChangeGC(pGC, mask, pval)
71: register GC *pGC;
72: register BITS32 mask;
73: CARD32 *pval;
74: {
75: return (DoChangeGC(pGC, mask, pval, 0));
76: }
77: /* DoChangeGC(pGC, mask, pval, fPointer)
78: mask is a set of bits indicating which values to change.
79: pval contains an appropriate value for each mask.
80: fPointer is true if the values for tiles, stipples, fonts or clipmasks
81: are pointers instead of IDs.
82: if there is an error, the value is marked as changed
83: anyway, which is probably wrong, but infrequent.
84:
85: NOTE:
86: all values sent over the protocol for ChangeGC requests are
87: 32 bits long
88: */
89:
90: int
91: DoChangeGC(pGC, mask, pval, fPointer)
92: register GC *pGC;
93: register BITS32 mask;
94: CARD32 *pval;
95: int fPointer;
96: {
97: register int index;
98: register int error = 0;
99: PixmapPtr pPixmap;
100: BITS32 maskQ;
101: GCInterestPtr pQ, pQInit;
102:
103: pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
104:
105: maskQ = mask; /* save these for when we walk the GCque */
106: while (mask && !error)
107: {
108: index = ffs(mask) - 1;
109: mask &= ~(index = (1 << index));
110: pGC->stateChanges |= index;
111: switch (index)
112: {
113: case GCFunction:
114: if (((CARD8)*pval >= GXclear) && ((CARD8)*pval <= GXset))
115: pGC->alu = (CARD8)*pval;
116: else
117: error = BadValue;
118: pval++;
119: break;
120: case GCPlaneMask:
121: pGC->planemask = *pval++;
122: break;
123: case GCForeground:
124: pGC->fgPixel = *pval++;
125: break;
126: case GCBackground:
127: pGC->bgPixel = *pval++;
128: break;
129: case GCLineWidth: /* ??? line width is a CARD16 */
130: pGC->lineWidth = (CARD16)*pval;
131: pval++;
132: break;
133: case GCLineStyle:
134: if (((CARD8)*pval >= LineSolid)
135: && ((CARD8)*pval <= LineDoubleDash))
136: pGC->lineStyle = (CARD8)*pval;
137: else
138: error = BadValue;
139: pval++;
140: break;
141: case GCCapStyle:
142: if (((CARD8)*pval >= CapNotLast)
143: && ((CARD8)*pval <= CapProjecting))
144: pGC->capStyle = (CARD8)*pval;
145: else
146: error = BadValue;
147: pval++;
148: break;
149: case GCJoinStyle:
150: if (((CARD8)*pval >= JoinMiter) && ((CARD8)*pval <= JoinBevel))
151: pGC->joinStyle = (CARD8)*pval;
152: else
153: error = BadValue;
154: pval++;
155: break;
156: case GCFillStyle:
157: if (((CARD8)*pval >= FillSolid)
158: && ((CARD8)*pval <= FillOpaqueStippled))
159: pGC->fillStyle = (CARD8)*pval;
160: else
161: error = BadValue;
162: pval++;
163: break;
164: case GCFillRule:
165: if (((CARD8)*pval >= EvenOddRule) &&
166: ((CARD8)*pval <= WindingRule))
167: pGC->fillRule = (CARD8)*pval;
168: else
169: error = BadValue;
170: pval++;
171: break;
172: case GCTile:
173: if(fPointer)
174: pPixmap = (PixmapPtr) *pval;
175: else
176: pPixmap = (PixmapPtr)LookupID((CARD32)*pval,
177: RT_PIXMAP, RC_CORE);
178: pval++;
179: if (pPixmap)
180: {
181: if ((pPixmap->drawable.depth != pGC->depth) ||
182: (pPixmap->drawable.pScreen != pGC->pScreen))
183: {
184: error = BadMatch;
185: }
186: else
187: {
188: (* pGC->pScreen->DestroyPixmap)(pGC->tile);
189: pGC->tile = pPixmap;
190: pPixmap->refcnt++;
191: }
192: }
193: else
194: error = BadPixmap;
195: break;
196: case GCStipple:
197: if(fPointer)
198: pPixmap = (PixmapPtr) *pval;
199: else
200: pPixmap = (PixmapPtr)LookupID((CARD32)*pval,
201: RT_PIXMAP, RC_CORE);
202: pval++;
203: if (pPixmap)
204: {
205: if ((pPixmap->drawable.depth != 1) ||
206: (pPixmap->drawable.pScreen != pGC->pScreen))
207: {
208: error = BadMatch;
209: }
210: else
211: {
212: (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
213: pGC->stipple = pPixmap;
214: pPixmap->refcnt++;
215: }
216: }
217: else
218: error = BadPixmap;
219: break;
220: case GCTileStipXOrigin:
221: pGC->patOrg.x = (INT16)*pval;
222: pval++;
223: break;
224: case GCTileStipYOrigin:
225: pGC->patOrg.y = (INT16)*pval;
226: pval++;
227: break;
228: case GCFont:
229: {
230: CARD32 fid;
231: FontPtr pFont;
232:
233:
234: if(fPointer)
235: pFont = (FontPtr) *pval++;
236: else
237: {
238: fid = * pval++;
239: pFont = (FontPtr)LookupID(fid, RT_FONT, RC_CORE);
240: }
241:
242: if (pFont)
243: {
244: if (pGC->font)
245: CloseFont( pGC->font);
246: pGC->font = pFont;
247: pGC->font->refcnt++;
248: }
249: else
250: error = BadFont;
251: break;
252: }
253: case GCSubwindowMode:
254: if ((*pval == ClipByChildren) ||
255: (*pval == IncludeInferiors))
256: pGC->subWindowMode = (CARD8)(*pval);
257: else
258: error = BadValue;
259: pval++;
260: break;
261: case GCGraphicsExposures:
262: if ((Bool)*pval == xFalse)
263: pGC->graphicsExposures = FALSE;
264: else if ((Bool)*pval == xTrue)
265: pGC->graphicsExposures = TRUE;
266: else
267: error = BadValue;
268: pval++;
269: break;
270: case GCClipXOrigin:
271: pGC->clipOrg.x = (INT16)(*pval);
272: pval++;
273: break;
274: case GCClipYOrigin:
275: pGC->clipOrg.y = (INT16)(*pval);
276: pval++;
277: break;
278: case GCClipMask:
279: {
280: Pixmap pid;
281: int clipType;
282:
283: pid = (Pixmap) *pval;
284: if (pid == None)
285: {
286: clipType = CT_NONE;
287: }
288: else
289: {
290: if(fPointer)
291: pPixmap = (PixmapPtr) pval;
292: else
293: pPixmap = (PixmapPtr)LookupID(pid, RT_PIXMAP, RC_CORE);
294: if (pPixmap)
295: {
296: clipType = CT_PIXMAP;
297: pPixmap->refcnt++;
298: }
299: else
300: error = BadPixmap;
301: }
302: pval++;
303: if(error == Success)
304: {
305: (*pGC->ChangeClip)(pGC, clipType, pPixmap, 0);
306: }
307: break;
308: }
309: case GCDashOffset:
310: pGC->dashOffset = (CARD16)*pval;
311: pval++;
312: break;
313: case GCDashList:
314: Xfree(pGC->dash);
315: pGC->numInDashList = 2;
316: pGC->dash = (unsigned char *)Xalloc(2 * sizeof(unsigned char));
317: pGC->dash[0] = (CARD8)(*pval);
318: pGC->dash[1] = (CARD8)(*pval++);
319: break;
320: case GCArcMode:
321: if (((CARD8)*pval >= ArcChord)
322: && ((CARD8)*pval <= ArcPieSlice))
323: pGC->arcMode = (CARD8)*pval;
324: else
325: error = BadValue;
326: pval++;
327: break;
328: default:
329: break;
330: }
331: }
332: pQ = pGC->pNextGCInterest;
333: pQInit = (GCInterestPtr) &pGC->pNextGCInterest;
334: do
335: {
336: /* I assume that if you've set a change interest mask, you've set a
337: * changeGC function */
338: if(pQ->ChangeInterestMask & maskQ)
339: (*pQ->ChangeGC)(pGC, pQ, maskQ);
340: pQ = pQ->pNextGCInterest;
341: }
342: while(pQ != pQInit);
343: return error;
344: }
345:
346: /* CreateGC(pDrawable, mask, pval, pStatus)
347: creates a default GC for the given drawable, using mask to fill
348: in any non-default values.
349: Returns a pointer to the new GC on success, NULL otherwise.
350: returns status of non-default fields in pStatus
351: BUG:
352: should check for failure to create default tile and stipple
353: should be able to set the tile before the call the (pScreen->ChangeGC)
354: as it is, we must call ChangeGC twice.
355:
356: */
357:
358: GC *
359: CreateGC(pDrawable, mask, pval, pStatus)
360: DrawablePtr pDrawable;
361: BITS32 mask;
362: long *pval;
363: BITS32 *pStatus;
364: {
365: register GC *pGC;
366: extern FontPtr defaultFont;
367: CARD32 tmpval[3];
368: PixmapPtr pTile;
369: GCPtr pgcScratch; /* for drawing into default tile and stipple */
370: xRectangle rect;
371: #ifdef DEBUG
372: void (**j)();
373: #endif /* DEBUG */
374:
375: pGC = (GC *)Xalloc(sizeof(GC));
376: if (!pGC)
377: return (GC *)NULL;
378:
379: #ifdef DEBUG
380: for(j = &pGC->FillSpans;
381: j < &pGC->PushPixels;
382: j++ )
383: *j = (void (*) ())NotImplemented;
384: #endif /* DEBUG */
385:
386: pGC->pScreen = pDrawable->pScreen;
387: pGC->depth = pDrawable->depth;
388: pGC->alu = GXcopy; /* dst <- src */
389: pGC->planemask = ~0;
390: pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
391:
392: pGC->fgPixel = 0;
393: pGC->bgPixel = 1;
394: pGC->lineWidth = 0;
395: pGC->lineStyle = LineSolid;
396: pGC->capStyle = CapButt;
397: pGC->joinStyle = JoinMiter;
398: pGC->fillStyle = FillSolid;
399: pGC->fillRule = EvenOddRule;
400: pGC->arcMode = ArcPieSlice;
401: pGC->font = defaultFont;
402: if ( pGC->font) /* necessary, because open of default font could fail */
403: pGC->font->refcnt++;
404: pGC->tile = NullPixmap;
405:
406: /* use the default stipple */
407: pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
408: pGC->stipple->refcnt++;
409: pGC->patOrg.x = 0;
410: pGC->patOrg.y = 0;
411: pGC->subWindowMode = ClipByChildren;
412: pGC->graphicsExposures = TRUE;
413: pGC->clipOrg.x = 0;
414: pGC->clipOrg.y = 0;
415: pGC->clientClipType = CT_NONE;
416: pGC->clientClip = (pointer)NULL;
417: pGC->numInDashList = 2;
418: pGC->dash = (unsigned char *)Xalloc(2 * sizeof(unsigned char));
419: pGC->dash[0] = 4;
420: pGC->dash[1] = 4;
421: pGC->dashOffset = 0;
422:
423: pGC->stateChanges = (1 << GCLastBit+1) - 1;
424: (*pGC->pScreen->CreateGC)(pGC);
425: if(mask)
426: *pStatus = ChangeGC(pGC, mask, pval);
427: else
428: *pStatus = Success;
429:
430: /* if the client hasn't provided a tile, build one and fill it with
431: the foreground pixel
432: */
433: if (!pGC->tile)
434: {
435: int w, h;
436:
437: w = 16;
438: h = 16;
439: (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h);
440: pTile = (PixmapPtr)
441: (*pGC->pScreen->CreatePixmap)(pDrawable->pScreen,
442: w, h, pGC->depth);
443: tmpval[0] = GXcopy;
444: tmpval[1] = pGC->fgPixel;
445: tmpval[2] = FillSolid;
446: pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen);
447: ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle,
448: tmpval);
449: ValidateGC(pTile, pgcScratch);
450: rect.x = 0;
451: rect.y = 0;
452: rect.width = w;
453: rect.height = h;
454: (*pgcScratch->PolyFillRect)(pTile, pgcScratch,
455: 1, &rect);
456: /* Always remember to free the scratch graphics context after use. */
457: FreeScratchGC(pgcScratch);
458:
459: /*
460: * Unfortunately, we must call ChangeGC a second time to get
461: * the tile installed. This would be nice to do before the first
462: * call to ChangeGC, but we don't know the value of the
463: * foreground pixel until afterwards.
464: */
465: DoChangeGC(pGC, GCTile, (CARD32 *)&pTile, TRUE);
466: }
467: return (pGC);
468: }
469:
470:
471: void
472: CopyGC(pgcSrc, pgcDst, mask)
473: register GC *pgcSrc;
474: register GC *pgcDst;
475: register int mask;
476: {
477: register int index;
478: int maskQ;
479: GCInterestPtr pQ, pQInit;
480: int i;
481:
482: pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
483: pgcDst->stateChanges |= mask;
484: maskQ = mask;
485: while (mask)
486: {
487: index = ffs(mask) - 1;
488: mask &= ~(index = (1 << index));
489: switch (index)
490: {
491: case GCFunction:
492: pgcDst->alu = pgcSrc->alu;
493: break;
494: case GCPlaneMask:
495: pgcDst->planemask = pgcSrc->planemask;
496: break;
497: case GCForeground:
498: pgcDst->fgPixel = pgcSrc->fgPixel;
499: break;
500: case GCBackground:
501: pgcDst->bgPixel = pgcSrc->bgPixel;
502: break;
503: case GCLineWidth:
504: pgcDst->lineWidth = pgcSrc->lineWidth;
505: break;
506: case GCLineStyle:
507: pgcDst->lineStyle = pgcSrc->lineStyle;
508: break;
509: case GCCapStyle:
510: pgcDst->capStyle = pgcSrc->capStyle;
511: break;
512: case GCJoinStyle:
513: pgcDst->joinStyle = pgcSrc->joinStyle;
514: break;
515: case GCFillStyle:
516: pgcDst->fillStyle = pgcSrc->fillStyle;
517: break;
518: case GCFillRule:
519: pgcDst->fillRule = pgcSrc->fillRule;
520: break;
521: case GCTile:
522: {
523: if (pgcDst->tile == pgcSrc->tile)
524: break;
525: (* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile);
526: pgcDst->tile = pgcSrc->tile;
527: if (IS_VALID_PIXMAP(pgcDst->tile))
528: pgcDst->tile->refcnt ++;
529: break;
530: }
531: case GCStipple:
532: {
1.1.1.2 ! root 533: if (pgcDst->stipple == pgcSrc->stipple)
1.1 root 534: break;
535: (* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple);
536: pgcDst->stipple = pgcSrc->stipple;
537: if (IS_VALID_PIXMAP(pgcDst->stipple))
538: pgcDst->stipple->refcnt ++;
539: break;
540: }
541: case GCTileStipXOrigin:
542: pgcDst->patOrg.x = pgcSrc->patOrg.x;
543: break;
544: case GCTileStipYOrigin:
545: pgcDst->patOrg.y = pgcSrc->patOrg.y;
546: break;
547: case GCFont:
548: if (pgcDst->font == pgcSrc->font)
549: break;
550: if (pgcDst->font)
551: CloseFont(pgcDst->font);
552: if ((pgcDst->font = pgcSrc->font) != NullFont)
553: (pgcDst->font)->refcnt++;
554: break;
555: case GCSubwindowMode:
556: pgcDst->subWindowMode = pgcSrc->subWindowMode;
557: break;
558: case GCGraphicsExposures:
559: pgcDst->graphicsExposures = pgcSrc->graphicsExposures;
560: break;
561: case GCClipXOrigin:
562: pgcDst->clipOrg.x = pgcSrc->clipOrg.x;
563: break;
564: case GCClipYOrigin:
565: pgcDst->clipOrg.y = pgcSrc->clipOrg.y;
566: break;
567: case GCClipMask:
568: (* pgcDst->CopyClip)(pgcDst, pgcSrc);
569: break;
570: case GCDashOffset:
571: pgcDst->dashOffset = pgcSrc->dashOffset;
572: break;
573: case GCDashList:
574: Xfree(pgcDst->dash);
575: pgcDst->dash = (unsigned char *)
576: Xalloc(2 * sizeof(unsigned char));
577: pgcDst->numInDashList = pgcSrc->numInDashList;
578: for (i=0; i<pgcSrc->numInDashList; i++)
579: pgcDst->dash[i] = pgcSrc->dash[i];
580: break;
581: case GCArcMode:
582: pgcDst->arcMode = pgcSrc->arcMode;
583: break;
584: default:
585: break;
586: }
587: }
588: pQ = pgcSrc->pNextGCInterest;
589: pQInit = (GCInterestPtr) &pgcSrc->pNextGCInterest;
590: do
591: {
592: if(pQ->CopyGCSource)
593: (*pQ->CopyGCSource)(pgcSrc, pQ, maskQ, pgcDst);
594: pQ = pQ->pNextGCInterest;
595: }
596: while(pQ != pQInit);
597: pQ = pgcDst->pNextGCInterest;
598: pQInit = (GCInterestPtr) &pgcDst->pNextGCInterest;
599: do
600: {
601: if(pQ->CopyGCDest)
602: (*pQ->CopyGCDest)(pgcDst, pQ, maskQ, pgcSrc);
603: pQ = pQ->pNextGCInterest;
604: }
605: while(pQ != pQInit);
606: }
607:
608: /*****************
609: * FreeGC
610: * does the diX part of freeing the characteristics in the GC
611: ***************/
612:
613: void
614: FreeGC(pGC, gid)
615: GC *pGC;
616: int gid;
617: {
618: GCInterestPtr pQ, pQInit, pQnext;
619:
620: CloseFont(pGC->font);
621: (* pGC->DestroyClip)(pGC);
622:
623: (* pGC->pScreen->DestroyPixmap)(pGC->tile);
624: (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
625:
626: pQ = pGC->pNextGCInterest;
627: pQInit = (GCInterestPtr) &pGC->pNextGCInterest;
628: do
629: {
630: pQnext = pQ->pNextGCInterest;
631: if(pQ->DestroyGC)
632: (*pQ->DestroyGC) (pGC, pQ);
633: pQ = pQnext;
634: }
635: while(pQ != pQInit);
636: Xfree(pGC->dash);
637: Xfree(pGC);
638: }
639:
640: void
641: SetGCMask(pGC, selectMask, newDataMask)
642: GCPtr pGC;
643: Mask selectMask;
644: Mask newDataMask;
645: {
646: pGC->stateChanges = (~selectMask & pGC->stateChanges) |
647: (selectMask & newDataMask);
648: if (selectMask & newDataMask)
649: pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
650: }
651:
652:
653:
654: /* CreateScratchGC(pScreen, depth)
655: like CreateGC, but doesn't do the default tile or stipple,
656: since we can't create them without already having a GC. any code
657: using the tile or stipple has to set them explicitly anyway,
658: since the state of the scratch gc is unknown. This is OK
659: because ChangeGC() has to be able to deal with NULL tiles and
660: stipples anyway (in case the CreateGC() call has provided a
661: value for them -- we can't set the default tile until the
662: client-supplied attributes are installed, since the fgPixel
663: is what fills the default tile. (maybe this comment should
664: go with CreateGC() or ChangeGC().)
665: */
666:
667: GC *
668: CreateScratchGC(pScreen, depth)
669: ScreenPtr pScreen;
670: int depth;
671: {
672: register GC *pGC;
673: extern FontPtr defaultFont;
674: #ifdef DEBUG
675: void (**j)();
676: #endif /* DEBUG */
677:
678: pGC = (GC *)Xalloc(sizeof(GC));
679: if (!pGC)
680: return (GC *)NULL;
681:
682: #ifdef DEBUG
683: for(j = &pGC->FillSpans;
684: j < &pGC->PushPixels;
685: j++ )
686: *j = (void (*) ())NotImplemented;
687: #endif /* DEBUG */
688:
689: pGC->pScreen = pScreen;
690: pGC->depth = depth;
691: pGC->alu = GXcopy; /* dst <- src */
692: pGC->planemask = ~0;
693: pGC->serialNumber = 0;
694:
695: pGC->fgPixel = 0;
696: pGC->bgPixel = 1;
697: pGC->lineWidth = 0;
698: pGC->lineStyle = LineSolid;
699: pGC->capStyle = CapButt;
700: pGC->joinStyle = JoinMiter;
701: pGC->fillStyle = FillSolid;
702: pGC->fillRule = EvenOddRule;
703: pGC->arcMode = ArcPieSlice;
704: pGC->font = defaultFont;
705: if ( pGC->font) /* necessary, because open of default font could fail */
706: pGC->font->refcnt++;
707: pGC->tile = NullPixmap;
708: pGC->stipple = NullPixmap;
709: pGC->patOrg.x = 0;
710: pGC->patOrg.y = 0;
711: pGC->subWindowMode = ClipByChildren;
712: pGC->graphicsExposures = TRUE;
713: pGC->clipOrg.x = 0;
714: pGC->clipOrg.y = 0;
715: pGC->clientClipType = CT_NONE;
716: pGC->numInDashList = 2;
717: pGC->dash = (unsigned char *)Xalloc(2 * sizeof(unsigned char));
718: pGC->dash[0] = 4;
719: pGC->dash[1] = 4;
720: pGC->dashOffset = 0;
721:
722: pGC->stateChanges = (1 << GCLastBit+1) - 1;
723: (*pScreen->CreateGC)(pGC);
724: return pGC;
725: }
726:
727:
728: FreeGCperDepth(screenNum)
729: int screenNum;
730: {
731: register int i;
732: register ScreenPtr pScreen;
733: GCPtr *ppGC;
734:
735: pScreen = &screenInfo.screen[screenNum];
736: ppGC = (GCPtr *) pScreen->GCperDepth;
737:
738: /* do depth 1 seperately because it's not included in list */
739: FreeGC(ppGC[0], 0);
740:
741: for (i = 0; i < pScreen-> numDepths; i++)
742: {
743: FreeGC(ppGC[i+1], 0);
744: }
745: }
746:
747:
748: CreateGCperDepthArray(screenNum)
749: int screenNum;
750: {
751: register int i;
752: register ScreenPtr pScreen;
753: DepthPtr pDepth;
754:
755: pScreen = &screenInfo.screen[screenNum];
756: pScreen->rgf = 0;
757: /* do depth 1 seperately because it's not included in list */
758: pScreen->GCperDepth[0] = CreateScratchGC(pScreen, 1);
759: (pScreen->GCperDepth[0])->graphicsExposures = FALSE;
760:
761: pDepth = pScreen->allowedDepths;
762: for (i=0; i<pScreen->numDepths; i++, pDepth++)
763: {
764: pScreen->GCperDepth[i+1] = CreateScratchGC(pScreen,
765: pDepth->depth);
766: (pScreen->GCperDepth[i+1])->graphicsExposures = FALSE;
767: }
768: }
769:
770: CreateDefaultStipple(screenNum)
771: int screenNum;
772: {
773: register ScreenPtr pScreen;
774: int tmpval[3];
775: xRectangle rect;
776: int w, h;
777: GCPtr pgcScratch;
778:
779: pScreen = &screenInfo.screen[screenNum];
780:
781: w = 16;
782: h = 16;
783: (* pScreen->QueryBestSize)(StippleShape, &w, &h);
784: pScreen->PixmapPerDepth[0] =
785: (*pScreen->CreatePixmap)(pScreen, w, h, 1);
786:
787: /* fill stipple with 1 */
788: tmpval[0] = GXcopy; tmpval[1] = 1; tmpval[2] = FillSolid;
789: pgcScratch = GetScratchGC(1, pScreen);
790: ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle, tmpval);
791: ValidateGC(pScreen->PixmapPerDepth[0], pgcScratch);
792: rect.x = 0;
793: rect.y = 0;
794: rect.width = w;
795: rect.height = h;
796: (*pgcScratch->PolyFillRect)(pScreen->PixmapPerDepth[0],
797: pgcScratch, 1, &rect);
798: FreeScratchGC(pgcScratch);
799: }
800:
801: FreeDefaultStipple(screenNum)
802: int screenNum;
803: {
804: ScreenPtr pScreen = &screenInfo.screen[screenNum];
805: (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
806: }
807:
808:
809: SetDashes(pGC, offset, ndash, pdash)
810: register GCPtr pGC;
811: int offset;
812: register int ndash;
813: register unsigned char *pdash;
814: {
815: register int i;
816: register unsigned char *p;
817: GCInterestPtr pQ, pQInit;
818: int maskQ = 0;
819:
820: i = ndash;
821: p = pdash;
822: while (i--)
823: {
824: if (!*p++)
825: {
826: /* dash segment must be > 0 */
827: return BadValue;
828: }
829: }
830:
831: if (offset != pGC->dashOffset)
832: {
833: pGC->dashOffset = offset;
834: pGC->stateChanges |= GCDashOffset;
835: maskQ |= GCDashOffset;
836: }
837:
838: p = (unsigned char *)Xalloc(ndash * sizeof(unsigned char));
839: if (!p)
840: {
841: return BadAlloc;
842: }
843: Xfree(pGC->dash);
844: pGC->dash = p;
845: pGC->numInDashList = ndash;
846: while(ndash--)
847: *p++ = *pdash++;
848: pGC->stateChanges |= GCDashList;
849: maskQ |= GCDashList;
850:
851: pQ = pGC->pNextGCInterest;
852: pQInit = (GCInterestPtr) &pGC->pNextGCInterest;
853: do
854: {
855: if(pQ->ChangeInterestMask & maskQ)
856: (*pQ->ChangeGC)(pGC, pQ, maskQ);
857: pQ = pQ->pNextGCInterest;
858: }
859: while(pQ != pQInit);
860: return Success;
861: }
862:
863:
864: int
865: SetClipRects(pGC, nrects, prects, ordering)
866: GCPtr pGC;
867: int nrects;
868: xRectangle *prects;
869: int ordering;
870: {
871: register xRectangle *prectP, *prectN;
872: register int i;
873: int newct, size;
874: xRectangle *prectsNew;
875: GCInterestPtr pQ, pQInit;
876:
877: switch(ordering)
878: {
879: case Unsorted:
880: newct = CT_UNSORTED;
881: break;
882: case YSorted:
883: if(i > 0)
884: {
885: prectP = prects;
886: prectN = prects + 1;
887: for(i = 1; i < nrects; i++, prectN++, prectP++)
888: if(prectN->y < prectP->y)
889: return(BadMatch);
890: }
891: newct = CT_YSORTED;
892: break;
893: case YXSorted:
894: if(i > 0)
895: {
896: for(i = 1; i < nrects; i++, prectN++, prectP++)
897: if((prectN->y < prectP->y) ||
898: ( (prectN->y == prectP->y) &&
899: (prectN->x < prectP->x) ) )
900: return(BadMatch);
901: }
902: newct = CT_YXSORTED;
903: break;
904: case YXBanded:
905: if(i > 0)
906: {
907: for(i = 1; i < nrects; i++, prectN++, prectP++)
908: if((prectN->y < prectP->y) ||
909: ( (prectN->y == prectP->y) &&
910: ( (prectN->x < prectP->x) ||
911: (prectN->height != prectP->height) ) ) )
912: return(BadMatch);
913: }
914: newct = CT_YXBANDED;
915: break;
916: }
917:
918: size = nrects * sizeof(xRectangle);
919: prectsNew = (xRectangle *) Xalloc(size);
920: bcopy(prects, prectsNew, size);
921: (*pGC->ChangeClip)(pGC, newct, prectsNew, nrects);
922: pQ = pGC->pNextGCInterest;
923: pQInit = (GCInterestPtr) &pGC->pNextGCInterest;
924: do
925: {
926: if(pQ->ChangeInterestMask & GCClipMask)
927: (*pQ->ChangeGC)(pGC, pQ, GCClipMask);
928: pQ = pQ->pNextGCInterest;
929: }
930: while(pQ != pQInit);
931: return Success;
932:
933: }
934:
935:
936: /*
937: sets reasonable defaults
938: if we can get a pre-allocated one, use it and mark it as used.
939: if we can't, create one out of whole cloth (The Velveteen GC -- if
940: you use it often enough it will become real.)
941: */
942: GCPtr
943: GetScratchGC(depth, pScreen)
944: register int depth;
945: register ScreenPtr pScreen;
946: {
947: register int i;
948: register GCPtr pGC = (GCPtr)NULL;;
949:
950: for (i=0; i<=pScreen->numDepths; i++)
951: if ( pScreen->GCperDepth[i]->depth == depth &&
952: !(pScreen->rgf & 1 << (i+1))
953: )
954: {
955: pScreen->rgf |= 1 << (i+1);
956: pGC = (pScreen->GCperDepth[i]);
957:
958: pGC->alu = GXcopy;
959: pGC->planemask = ~0;
960: pGC->serialNumber = 0;
961: pGC->fgPixel = 0;
962: pGC->bgPixel = 1;
963: pGC->lineWidth = 0;
964: pGC->lineStyle = LineSolid;
965: pGC->capStyle = CapButt;
966: pGC->joinStyle = JoinMiter;
967: pGC->fillStyle = FillSolid;
968: pGC->fillRule = EvenOddRule;
969: pGC->arcMode = ArcChord;
970: pGC->patOrg.x = 0;
971: pGC->patOrg.y = 0;
972: pGC->subWindowMode = ClipByChildren;
973: pGC->graphicsExposures = FALSE;
974: pGC->clipOrg.x = 0;
975: pGC->clipOrg.y = 0;
976: /* can't change clip type, because we might drop storage */
977: pGC->stateChanges = (1 << GCLastBit+1) - 1;
978: return pGC;
979: }
980: /* if we make it this far, need to roll our own */
981: pGC = CreateScratchGC(pScreen, depth);
982: pGC->graphicsExposures = FALSE;
983: return pGC;
984: }
985:
986: /*
987: if the gc to free is in the table of pre-existing ones,
988: mark it as available.
989: if not, free it for real
990: */
991: void
992: FreeScratchGC(pGC)
993: register GCPtr pGC;
994: {
995: register ScreenPtr pScreen = pGC->pScreen;
996: register int i;
997:
998: for (i=0; i<=pScreen->numDepths; i++)
999: {
1000: if ( pScreen->GCperDepth[i] == pGC)
1001: {
1002: pScreen->rgf &= ~(1<<i+1);
1003: return;
1004: }
1005: }
1006: FreeGC(pGC, 0);
1007: }
1008:
1009:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.