|
|
1.1 root 1: /*-
2: * sunGC.c --
3: * Functions to support the meddling with GC's we do to preserve
4: * the software cursor...
5: *
6: * Copyright (c) 1987 by the Regents of the University of California
7: *
8: * Permission to use, copy, modify, and distribute this
9: * software and its documentation for any purpose and without
10: * fee is hereby granted, provided that the above copyright
11: * notice appear in all copies. The University of California
12: * makes no representations about the suitability of this
13: * software for any purpose. It is provided "as is" without
14: * express or implied warranty.
15: *
16: *
17: */
18: #ifndef lint
19: static char rcsid[] =
20: "$Header: sunGC.c,v 4.2 87/09/12 21:43:53 sun Exp $ SPRITE (Berkeley)";
21: #endif lint
22:
23: #include "sun.h"
24:
25: #include "X.h"
26: #include "Xmd.h"
27: #include "extnsionst.h"
28: #include "regionstr.h"
29: #include "windowstr.h"
30: #include "fontstruct.h"
31: #include "dixfontstr.h"
32: #include "../mi/mifpoly.h" /* for SppPointPtr */
33:
34: /*
35: * Overlap BoxPtr and Box elements
36: */
37: #define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \
38: (((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \
39: ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2))
40:
41: /*
42: * Overlap BoxPtr, origins, and rectangle
43: */
44: #define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \
45: BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h))
46:
47: /*
48: * Overlap BoxPtr, origins and RectPtr
49: */
50: #define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \
51: ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y,(pRect)->width, \
52: (pRect)->height)
53: /*
54: * Overlap BoxPtr and horizontal span
55: */
56: #define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y))
57:
58:
59: #ifdef notdef
60: #define COMPARE_GCS(g1, g2) compare_gcs(g1, g2)
61:
62: static
63: compare_gcs(g1, g2)
64: GCPtr g1, g2;
65: {
66: if (g1->pScreen != g2->pScreen) FatalError("GC and Shadow mis-match - pScreen\n");
67: if (g1->depth != g2->depth) FatalError("GC and Shadow mis-match - depth\n");
68: #ifdef notdef
69: if (g1->serialNumber != g2->serialNumber) FatalError("GC and Shadow mis-match - serialNumber\n");
70: #endif
71: if (g1->alu != g2->alu) FatalError("GC and Shadow mis-match - alu\n");
72: if (g1->planemask != g2->planemask) FatalError("GC and Shadow mis-match - planemask\n");
73: if (g1->fgPixel != g2->fgPixel) FatalError("GC and Shadow mis-match - fgPixel\n");
74: if (g1->bgPixel != g2->bgPixel) FatalError("GC and Shadow mis-match - bgPixel\n");
75: if (g1->lineWidth != g2->lineWidth) FatalError("GC and Shadow mis-match - lineWidth\n");
76: if (g1->lineStyle != g2->lineStyle) FatalError("GC and Shadow mis-match - lineStyle\n");
77: if (g1->capStyle != g2->capStyle) FatalError("GC and Shadow mis-match - capStyle\n");
78: if (g1->joinStyle != g2->joinStyle) FatalError("GC and Shadow mis-match - joinStyle\n");
79: if (g1->fillStyle != g2->fillStyle) FatalError("GC and Shadow mis-match - fillStyle\n");
80: if (g1->fillRule != g2->fillRule) FatalError("GC and Shadow mis-match - fillRule\n");
81: if (g1->arcMode != g2->arcMode) FatalError("GC and Shadow mis-match - arcMode\n");
82: if (g1->tile != g2->tile) FatalError("GC and Shadow mis-match - tile\n");
83: if (g1->stipple != g2->stipple) FatalError("GC and Shadow mis-match - stipple\n");
84: if (g1->patOrg.x != g2->patOrg.x) FatalError("GC and Shadow mis-match - patOrg.x\n");
85: if (g1->patOrg.y != g2->patOrg.y) FatalError("GC and Shadow mis-match - patOrg.y\n");
86: if (g1->font != g2->font) FatalError("GC and Shadow mis-match - font\n");
87: if (g1->subWindowMode != g2->subWindowMode) FatalError("GC and Shadow mis-match - subWindowMode\n");
88: if (g1->graphicsExposures != g2->graphicsExposures) FatalError("GC and Shadow mis-match - graphicsExposures\n");
89: if (g1->clipOrg.x != g2->clipOrg.x) FatalError("GC and Shadow mis-match - clipOrg.x\n");
90: if (g1->clipOrg.y != g2->clipOrg.y) FatalError("GC and Shadow mis-match - clipOrg.y\n");
91: #ifdef notdef
92: if (g1->clientClip != g2->clientClip) FatalError("GC and Shadow mis-match - clientClip\n");
93: #endif
94: if (g1->clientClipType != g2->clientClipType) FatalError("GC and Shadow mis-match - clientClipType\n");
95: if (g1->dashOffset != g2->dashOffset) FatalError("GC and Shadow mis-match - dashOffset\n");
96: if (g1->numInDashList != g2->numInDashList) FatalError("GC and Shadow mis-match - numInDashList\n");
97: #ifdef notdef
98: if (g1->dash != g2->dash) FatalError("GC and Shadow mis-match - dash\n");
99: if (g1->stateChanges != g2->stateChanges) FatalError("GC and Shadow mis-match - stateChanges\n");
100: #endif
101: if (g1->lastWinOrg.x != g2->lastWinOrg.x) FatalError("GC and Shadow mis-match - lastWinOrg.x\n");
102: if (g1->lastWinOrg.y != g2->lastWinOrg.y) FatalError("GC and Shadow mis-match - lastWinOrg.y\n");
103: if (g1->miTranslate != g2->miTranslate) FatalError("GC and Shadow mis-match - miTranslate\n");
104:
105: }
106: #else
107: #define COMPARE_GCS(g1, g2)
108: #endif
109:
110:
111: /*-
112: *-----------------------------------------------------------------------
113: * sunSaveCursorBox --
114: * Given an array of points, figure out the bounding box for the
115: * series and remove the cursor if it overlaps that box.
116: *
117: * Results:
118: *
119: * Side Effects:
120: *
121: *-----------------------------------------------------------------------
122: */
123: void
124: sunSaveCursorBox (xorg, yorg, mode, pPts, nPts, pCursorBox)
125: register int xorg; /* X-Origin for points */
126: register int yorg; /* Y-Origin for points */
127: int mode; /* CoordModeOrigin or
128: * CoordModePrevious */
129: register DDXPointPtr pPts; /* Array of points */
130: int nPts; /* Number of points */
131: register BoxPtr pCursorBox; /* Bounding box for cursor */
132: {
133: register int minx,
134: miny,
135: maxx,
136: maxy;
137:
138: minx = maxx = pPts->x + xorg;
139: miny = maxy = pPts->y + yorg;
140:
141: pPts++;
142: nPts--;
143:
144: if (mode == CoordModeOrigin) {
145: while (nPts--) {
146: minx = min(minx, pPts->x + xorg);
147: maxx = max(maxx, pPts->x + xorg);
148: miny = min(miny, pPts->y + yorg);
149: maxy = max(maxy, pPts->y + yorg);
150: pPts++;
151: }
152: } else {
153: xorg = minx;
154: yorg = miny;
155: while (nPts--) {
156: minx = min(minx, pPts->x + xorg);
157: maxx = max(maxx, pPts->x + xorg);
158: miny = min(miny, pPts->y + yorg);
159: maxy = max(maxy, pPts->y + yorg);
160: xorg += pPts->x;
161: yorg += pPts->y;
162: pPts++;
163: }
164: }
165: if (BOX_OVERLAP(pCursorBox,minx,miny,maxx,maxy)) {
166: sunRemoveCursor();
167: }
168: }
169:
170: /*-
171: *-----------------------------------------------------------------------
172: * sunFillSpans --
173: * Remove the cursor if any of the spans overlaps the area covered
174: * by the cursor. This assumes the points have been translated
175: * already, though perhaps it shouldn't...
176: *
177: * Results:
178: * None.
179: *
180: * Side Effects:
181: *
182: *-----------------------------------------------------------------------
183: */
184: void
185: sunFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
186: DrawablePtr pDrawable;
187: GCPtr pGC;
188: int nInit; /* number of spans to fill */
189: DDXPointPtr pptInit; /* pointer to list of start points */
190: int *pwidthInit; /* pointer to list of n widths */
191: int fSorted;
192: {
193: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
194:
195: if (pDrawable->type == DRAWABLE_WINDOW) {
196: BoxRec cursorBox;
197:
198: if (sunCursorLoc (pDrawable->pScreen, &cursorBox)) {
199: register DDXPointPtr pts;
200: register int *widths;
201: register int nPts;
202:
203: for (pts = pptInit, widths = pwidthInit, nPts = nInit;
204: nPts--;
205: pts++, widths++) {
206: if (SPN_OVERLAP(&cursorBox,pts->y,pts->x,*widths)) {
207: sunRemoveCursor();
208: break;
209: }
210: }
211: }
212: }
213:
214: COMPARE_GCS(pGC,pShadowGC);
215: (* pShadowGC->FillSpans)(pDrawable, pShadowGC, nInit, pptInit,
216: pwidthInit, fSorted);
217: }
218:
219: /*-
220: *-----------------------------------------------------------------------
221: * sunSetSpans --
222: * Remove the cursor if any of the horizontal segments overlaps
223: * the area covered by the cursor. This also assumes the spans
224: * have been translated from the window's coordinates to the
225: * screen's.
226: * Results:
227: * None.
228: *
229: * Side Effects:
230: *
231: *-----------------------------------------------------------------------
232: */
233: void
234: sunSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted)
235: DrawablePtr pDrawable;
236: GCPtr pGC;
237: int *psrc;
238: register DDXPointPtr ppt;
239: int *pwidth;
240: int nspans;
241: int fSorted;
242: {
243: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
244:
245: if (pDrawable->type == DRAWABLE_WINDOW) {
246: BoxRec cursorBox;
247:
248: if (sunCursorLoc (pDrawable->pScreen, &cursorBox)) {
249: register DDXPointPtr pts;
250: register int *widths;
251: register int nPts;
252:
253: for (pts = ppt, widths = pwidth, nPts = nspans;
254: nPts--;
255: pts++, widths++) {
256: if (SPN_OVERLAP(&cursorBox,pts->y,pts->x,*widths)) {
257: sunRemoveCursor();
258: break;
259: }
260: }
261: }
262: }
263:
264: COMPARE_GCS(pGC,pShadowGC);
265: (* pShadowGC->SetSpans) (pDrawable, pShadowGC, psrc, ppt, pwidth,
266: nspans, fSorted);
267: }
268:
269: /*-
270: *-----------------------------------------------------------------------
271: * sunGetSpans --
272: * Remove the cursor if any of the desired spans overlaps the cursor.
273: *
274: * Results:
275: *
276: * Side Effects:
277: *
278: *-----------------------------------------------------------------------
279: */
280: unsigned int *
281: sunGetSpans(pDrawable, wMax, ppt, pwidth, nspans)
282: DrawablePtr pDrawable; /* drawable from which to get bits */
283: int wMax; /* largest value of all *pwidths */
284: register DDXPointPtr ppt; /* points to start copying from */
285: int *pwidth; /* list of number of bits to copy */
286: int nspans; /* number of scanlines to copy */
287: {
288: if (pDrawable->type == DRAWABLE_WINDOW) {
289: BoxRec cursorBox;
290:
291: if (sunCursorLoc (pDrawable->pScreen, &cursorBox)) {
292: register DDXPointPtr pts;
293: register int *widths;
294: register int nPts;
295: register int xorg,
296: yorg;
297:
298: xorg = ((WindowPtr)pDrawable)->absCorner.x;
299: yorg = ((WindowPtr)pDrawable)->absCorner.y;
300:
301: for (pts = ppt, widths = pwidth, nPts = nspans;
302: nPts--;
303: pts++, widths++) {
304: if (SPN_OVERLAP(&cursorBox,pts->y+yorg,
305: pts->x+xorg,*widths)) {
306: sunRemoveCursor();
307: break;
308: }
309: }
310: }
311: }
312:
313: /*
314: * XXX: Because we have no way to get at the GC used to call us,
315: * we must rely on the GetSpans vector never changing and stick it
316: * in the fbFd structure. Gross.
317: */
318: return (* sunFbs[pDrawable->pScreen->myNum].GetSpans)(pDrawable, wMax,
319: ppt, pwidth, nspans);
320: }
321:
322: /*-
323: *-----------------------------------------------------------------------
324: * sunPutImage --
325: * Remove the cursor if it is in the way of the image to be
326: * put down...
327: *
328: * Results:
329: * None.
330: *
331: * Side Effects:
332: *
333: *-----------------------------------------------------------------------
334: */
335: void
336: sunPutImage(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits)
337: DrawablePtr pDst;
338: GCPtr pGC;
339: int depth;
340: int x;
341: int y;
342: int w;
343: int h;
344: int format;
345: char *pBits;
346: {
347: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
348:
349: if (pDst->type == DRAWABLE_WINDOW) {
350: BoxRec cursorBox;
351: if (sunCursorLoc (pDst->pScreen, &cursorBox)) {
352: register WindowPtr pWin = (WindowPtr)pDst;
353:
354: if (ORG_OVERLAP(&cursorBox,pWin->absCorner.x,pWin->absCorner.y,
355: x,y,w,h)) {
356: sunRemoveCursor();
357: }
358: }
359: }
360:
361: COMPARE_GCS(pGC,pShadowGC);
362: (* pShadowGC->PutImage) (pDst, pShadowGC, depth, x, y, w, h,
363: leftPad, format, pBits);
364: }
365:
366: /*-
367: *-----------------------------------------------------------------------
368: * sunGetImage --
369: * Remove the cursor if it overlaps the image to be gotten.
370: *
371: * Results:
372: * None.
373: *
374: * Side Effects:
375: *
376: *-----------------------------------------------------------------------
377: */
378: void
379: sunGetImage (pSrc, x, y, w, h, format, planeMask, pBits)
380: DrawablePtr pSrc;
381: int x;
382: int y;
383: int w;
384: int h;
385: unsigned int format;
386: unsigned int planeMask;
387: int *pBits;
388: {
389: if (pSrc->type == DRAWABLE_WINDOW) {
390: BoxRec cursorBox;
391:
392: if (sunCursorLoc(pSrc->pScreen, &cursorBox)) {
393: register WindowPtr pWin = (WindowPtr)pSrc;
394:
395: if (ORG_OVERLAP(&cursorBox,pWin->absCorner.x,pWin->absCorner.y,
396: x,y,w,h)) {
397: sunRemoveCursor();
398: }
399: }
400: }
401:
402: (* sunFbs[pSrc->pScreen->myNum].GetImage) (pSrc, x, y, w, h, format,
403: planeMask, pBits);
404: }
405:
406: /*-
407: *-----------------------------------------------------------------------
408: * sunCopyArea --
409: * Remove the cursor if it overlaps either the source or destination
410: * drawables, then call the screen-specific CopyArea routine.
411: *
412: * Results:
413: * None.
414: *
415: * Side Effects:
416: *
417: *-----------------------------------------------------------------------
418: */
419: void
420: sunCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty)
421: DrawablePtr pSrc;
422: DrawablePtr pDst;
423: GCPtr pGC;
424: int srcx;
425: int srcy;
426: int w;
427: int h;
428: int dstx;
429: int dsty;
430: {
431: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
432: BoxRec cursorBox;
433: register WindowPtr pWin;
434: int out = FALSE;
435:
436: if (pSrc->type == DRAWABLE_WINDOW &&
437: sunCursorLoc(pSrc->pScreen, &cursorBox)) {
438: pWin = (WindowPtr)pSrc;
439:
440: if (ORG_OVERLAP(&cursorBox,pWin->absCorner.x,pWin->absCorner.y,
441: srcx, srcy, w, h)) {
442: sunRemoveCursor();
443: out = TRUE;
444: }
445: }
446:
447: if (!out && pDst->type == DRAWABLE_WINDOW &&
448: sunCursorLoc(pDst->pScreen, &cursorBox)) {
449: pWin = (WindowPtr)pDst;
450:
451: if (ORG_OVERLAP(&cursorBox,pWin->absCorner.x,pWin->absCorner.y,
452: dstx, dsty, w, h)) {
453: sunRemoveCursor();
454: }
455: }
456:
457: COMPARE_GCS(pGC,pShadowGC);
458: (* pShadowGC->CopyArea) (pSrc, pDst, pShadowGC, srcx, srcy,
459: w, h, dstx, dsty);
460: }
461:
462: /*-
463: *-----------------------------------------------------------------------
464: * sunCopyPlane --
465: * Remove the cursor as necessary and call the screen-specific
466: * CopyPlane function.
467: *
468: * Results:
469: * None.
470: *
471: * Side Effects:
472: *
473: *-----------------------------------------------------------------------
474: */
475: void
476: sunCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
477: DrawablePtr pSrc;
478: DrawablePtr pDst;
479: register GC *pGC;
480: int srcx,
481: srcy;
482: int w,
483: h;
484: int dstx,
485: dsty;
486: unsigned int plane;
487: {
488: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
489: BoxRec cursorBox;
490: register WindowPtr pWin;
491: int out = FALSE;
492:
493: if (pSrc->type == DRAWABLE_WINDOW &&
494: sunCursorLoc(pSrc->pScreen, &cursorBox)) {
495: pWin = (WindowPtr)pSrc;
496:
497: if (ORG_OVERLAP(&cursorBox,pWin->absCorner.x,pWin->absCorner.y,
498: srcx, srcy, w, h)) {
499: sunRemoveCursor();
500: out = TRUE;
501: }
502: }
503:
504: if (!out && pDst->type == DRAWABLE_WINDOW &&
505: sunCursorLoc(pDst->pScreen, &cursorBox)) {
506: pWin = (WindowPtr)pDst;
507:
508: if (ORG_OVERLAP(&cursorBox,pWin->absCorner.x,pWin->absCorner.y,
509: dstx, dsty, w, h)) {
510: sunRemoveCursor();
511: }
512: }
513:
514:
515: COMPARE_GCS(pGC,pShadowGC);
516: (* pShadowGC->CopyPlane) (pSrc, pDst, pShadowGC, srcx, srcy, w, h,
517: dstx, dsty, plane);
518: }
519:
520: /*-
521: *-----------------------------------------------------------------------
522: * sunPolyPoint --
523: * See if any of the points lies within the area covered by the
524: * cursor and remove the cursor if one does. Then put the points
525: * down.
526: *
527: * Results:
528: * None.
529: *
530: * Side Effects:
531: *
532: *-----------------------------------------------------------------------
533: */
534: void
535: sunPolyPoint (pDrawable, pGC, mode, npt, pptInit)
536: DrawablePtr pDrawable;
537: GCPtr pGC;
538: int mode; /* Origin or Previous */
539: int npt;
540: xPoint *pptInit;
541: {
542: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
543: register xPoint *pts;
544: register int nPts;
545: register int xorg;
546: register int yorg;
547: BoxRec cursorBox;
548:
549: if (pDrawable->type == DRAWABLE_WINDOW &&
550: sunCursorLoc (pDrawable->pScreen, &cursorBox)) {
551: xorg = ((WindowPtr)pDrawable)->absCorner.x;
552: yorg = ((WindowPtr)pDrawable)->absCorner.y;
553:
554: if (mode == CoordModeOrigin) {
555: for (pts = pptInit, nPts = npt; nPts--; pts++) {
556: if (ORG_OVERLAP(&cursorBox,xorg,yorg,pts->x,pts->y,0,0)){
557: sunRemoveCursor();
558: break;
559: }
560: }
561: } else {
562: for (pts = pptInit, nPts = npt; nPts--; pts++) {
563: if (ORG_OVERLAP(&cursorBox,xorg,yorg,pts->x,pts->y,0,0)){
564: sunRemoveCursor();
565: break;
566: } else {
567: xorg += pts->x;
568: yorg += pts->y;
569: }
570: }
571: }
572: }
573:
574: COMPARE_GCS(pGC,pShadowGC);
575: (* pShadowGC->PolyPoint) (pDrawable, pShadowGC, mode, npt, pptInit);
576: }
577:
578: /*-
579: *-----------------------------------------------------------------------
580: * sunPolylines --
581: * Find the bounding box of the lines and remove the cursor if
582: * the box overlaps the area covered by the cursor. Then call
583: * the screen's Polylines function to draw the lines themselves.
584: *
585: * Results:
586: *
587: * Side Effects:
588: *
589: *-----------------------------------------------------------------------
590: */
591: void
592: sunPolylines (pDrawable, pGC, mode, npt, pptInit)
593: DrawablePtr pDrawable;
594: GCPtr pGC;
595: int mode;
596: int npt;
597: DDXPointPtr pptInit;
598: {
599: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
600: BoxRec cursorBox;
601:
602: if (pDrawable->type == DRAWABLE_WINDOW &&
603: sunCursorLoc (pDrawable->pScreen, &cursorBox)) {
604: sunSaveCursorBox(((WindowPtr)pDrawable)->absCorner.x,
605: ((WindowPtr)pDrawable)->absCorner.y,
606: mode,
607: pptInit,
608: npt,
609: &cursorBox);
610: }
611: COMPARE_GCS(pGC,pShadowGC);
612: (*pShadowGC->Polylines) (pDrawable, pShadowGC, mode, npt, pptInit);
613: }
614:
615: /*-
616: *-----------------------------------------------------------------------
617: * sunPolySegment --
618: * Treat each segment as a box and remove the cursor if any box
619: * overlaps the cursor's area. Then draw the segments. Note that
620: * the endpoints of the segments are in no way guaranteed to be
621: * in the right order, so we find the bounding box of the segment
622: * in two comparisons and use that to figure things out.
623: *
624: * Results:
625: * None.
626: *
627: * Side Effects:
628: *
629: *-----------------------------------------------------------------------
630: */
631: void
632: sunPolySegment(pDraw, pGC, nseg, pSegs)
633: DrawablePtr pDraw;
634: GCPtr pGC;
635: int nseg;
636: xSegment *pSegs;
637: {
638: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
639: register xSegment *pSeg;
640: register int nSeg;
641: register int xorg,
642: yorg;
643: BoxRec cursorBox;
644: Bool nuke = FALSE;
645:
646: if (pDraw->type == DRAWABLE_WINDOW &&
647: sunCursorLoc (pDraw->pScreen, &cursorBox)) {
648: xorg = ((WindowPtr)pDraw)->absCorner.x;
649: yorg = ((WindowPtr)pDraw)->absCorner.y;
650:
651: for (nSeg = nseg, pSeg = pSegs; nSeg--; pSeg++) {
652: if (pSeg->x1 < pSeg->x2) {
653: if (pSeg->y1 < pSeg->y2) {
654: nuke = BOX_OVERLAP(&cursorBox,
655: pSeg->x1+xorg,pSeg->y1+yorg,
656: pSeg->x2+xorg,pSeg->y2+yorg);
657: } else {
658: nuke = BOX_OVERLAP(&cursorBox,
659: pSeg->x1+xorg,pSeg->y2+yorg,
660: pSeg->x2+xorg,pSeg->y1+yorg);
661: }
662: } else if (pSeg->y1 < pSeg->y2) {
663: nuke = BOX_OVERLAP(&cursorBox,
664: pSeg->x2+xorg,pSeg->y1+yorg,
665: pSeg->x1+xorg,pSeg->y2+yorg);
666: } else {
667: nuke = BOX_OVERLAP(&cursorBox,
668: pSeg->x2+xorg,pSeg->y2+yorg,
669: pSeg->x1+xorg,pSeg->y1+yorg);
670: }
671: if (nuke) {
672: sunRemoveCursor();
673: break;
674: }
675: }
676: }
677:
678: COMPARE_GCS(pGC,pShadowGC);
679: (* pShadowGC->PolySegment) (pDraw, pShadowGC, nseg, pSegs);
680: }
681:
682: /*-
683: *-----------------------------------------------------------------------
684: * sunPolyRectangle --
685: * Remove the cursor if it overlaps any of the rectangles to be
686: * drawn, then draw them.
687: *
688: * Results:
689: * None
690: *
691: * Side Effects:
692: *
693: *-----------------------------------------------------------------------
694: */
695: void
696: sunPolyRectangle(pDraw, pGC, nrects, pRects)
697: DrawablePtr pDraw;
698: GCPtr pGC;
699: int nrects;
700: xRectangle *pRects;
701: {
702: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
703: register xRectangle *pRect;
704: register int nRect;
705: register int xorg,
706: yorg;
707: BoxRec cursorBox;
708:
709: if (pDraw->type == DRAWABLE_WINDOW &&
710: sunCursorLoc (pDraw->pScreen, &cursorBox)) {
711: xorg = ((WindowPtr)pDraw)->absCorner.x;
712: yorg = ((WindowPtr)pDraw)->absCorner.y;
713:
714: for (nRect = nrects, pRect = pRects; nRect--; pRect++) {
715: if (ORGRECT_OVERLAP(&cursorBox,xorg,yorg,pRect)){
716: sunRemoveCursor();
717: break;
718: }
719: }
720: }
721:
722: COMPARE_GCS(pGC,pShadowGC);
723: (* pShadowGC->PolyRectangle) (pDraw, pShadowGC, nrects, pRects);
724: }
725:
726: /*-
727: *-----------------------------------------------------------------------
728: * sunPolyArc --
729: * Using the bounding rectangle of each arc, remove the cursor
730: * if it overlaps any arc, then draw all the arcs.
731: *
732: * Results:
733: *
734: * Side Effects:
735: *
736: *-----------------------------------------------------------------------
737: */
738: void
739: sunPolyArc(pDraw, pGC, narcs, parcs)
740: DrawablePtr pDraw;
741: GCPtr pGC;
742: int narcs;
743: xArc *parcs;
744: {
745: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
746: register xArc *pArc;
747: register int nArc;
748: register int xorg,
749: yorg;
750: BoxRec cursorBox;
751:
752: if (pDraw->type == DRAWABLE_WINDOW &&
753: sunCursorLoc (pDraw->pScreen, &cursorBox)) {
754: xorg = ((WindowPtr)pDraw)->absCorner.x;
755: yorg = ((WindowPtr)pDraw)->absCorner.y;
756:
757: for (nArc = narcs, pArc = parcs; nArc--; pArc++) {
758: if (ORGRECT_OVERLAP(&cursorBox,xorg,yorg,pArc)){
759: sunRemoveCursor();
760: break;
761: }
762: }
763: }
764:
765: COMPARE_GCS(pGC,pShadowGC);
766: (* pShadowGC->PolyArc) (pDraw, pShadowGC, narcs, parcs);
767: }
768:
769: /*-
770: *-----------------------------------------------------------------------
771: * sunFillPolygon --
772: * Find the bounding box of the polygon to fill and remove the
773: * cursor if it overlaps this box...
774: *
775: * Results:
776: * None.
777: *
778: * Side Effects:
779: *
780: *-----------------------------------------------------------------------
781: */
782: void
783: sunFillPolygon(pDraw, pGC, shape, mode, count, pPts)
784: DrawablePtr pDraw;
785: register GCPtr pGC;
786: int shape, mode;
787: register int count;
788: DDXPointPtr pPts;
789: {
790: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
791: BoxRec cursorBox;
792:
793: if (pDraw->type == DRAWABLE_WINDOW &&
794: sunCursorLoc (pDraw->pScreen, &cursorBox)) {
795: sunSaveCursorBox(((WindowPtr)pDraw)->absCorner.x,
796: ((WindowPtr)pDraw)->absCorner.y,
797: mode,
798: pPts,
799: count,
800: &cursorBox);
801: }
802:
803: COMPARE_GCS(pGC,pShadowGC);
804: (* pShadowGC->FillPolygon) (pDraw, pShadowGC, shape, mode, count, pPts);
805: }
806:
807: /*-
808: *-----------------------------------------------------------------------
809: * sunPolyFillRect --
810: * Remove the cursor if it overlaps any of the filled rectangles
811: * to be drawn by the output routines.
812: *
813: * Results:
814: * None.
815: *
816: * Side Effects:
817: *
818: *-----------------------------------------------------------------------
819: */
820: void
821: sunPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
822: DrawablePtr pDrawable;
823: GCPtr pGC;
824: int nrectFill; /* number of rectangles to fill */
825: xRectangle *prectInit; /* Pointer to first rectangle to fill */
826: {
827: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
828: register xRectangle *pRect;
829: register int nRect;
830: register int xorg,
831: yorg;
832: BoxRec cursorBox;
833:
834: if (pDrawable->type == DRAWABLE_WINDOW &&
835: sunCursorLoc (pDrawable->pScreen, &cursorBox)) {
836: xorg = ((WindowPtr)pDrawable)->absCorner.x;
837: yorg = ((WindowPtr)pDrawable)->absCorner.y;
838:
839: for (nRect = nrectFill, pRect = prectInit; nRect--; pRect++) {
840: if (ORGRECT_OVERLAP(&cursorBox,xorg,yorg,pRect)){
841: sunRemoveCursor();
842: break;
843: }
844: }
845: }
846:
847: COMPARE_GCS(pGC,pShadowGC);
848: (* pShadowGC->PolyFillRect) (pDrawable, pShadowGC, nrectFill, prectInit);
849: }
850:
851: /*-
852: *-----------------------------------------------------------------------
853: * sunPolyFillArc --
854: * See if the cursor overlaps any of the bounding boxes for the
855: * filled arc and remove it if it does.
856: *
857: * Results:
858: * None.
859: *
860: * Side Effects:
861: *
862: *-----------------------------------------------------------------------
863: */
864: void
865: sunPolyFillArc(pDraw, pGC, narcs, parcs)
866: DrawablePtr pDraw;
867: GCPtr pGC;
868: int narcs;
869: xArc *parcs;
870: {
871: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
872: register xArc *pArc;
873: register int nArc;
874: register int xorg,
875: yorg;
876: BoxRec cursorBox;
877:
878: if (pDraw->type == DRAWABLE_WINDOW &&
879: sunCursorLoc (pDraw->pScreen, &cursorBox)) {
880: xorg = ((WindowPtr)pDraw)->absCorner.x;
881: yorg = ((WindowPtr)pDraw)->absCorner.y;
882:
883: for (nArc = narcs, pArc = parcs; nArc--; pArc++) {
884: if (ORGRECT_OVERLAP(&cursorBox,xorg,yorg,pArc)){
885: sunRemoveCursor();
886: break;
887: }
888: }
889: }
890:
891: COMPARE_GCS(pGC,pShadowGC);
892: (* pShadowGC->PolyFillArc) (pDraw, pShadowGC, narcs, parcs);
893: }
894:
895: /*-
896: *-----------------------------------------------------------------------
897: * sunText --
898: * Find the extent of a text operation and remove the cursor if they
899: * overlap. pDraw is assumed to be a window.
900: *
901: * Results:
902: *
903: * Side Effects:
904: *
905: *-----------------------------------------------------------------------
906: */
907: int
908: sunText(pDraw, pGC, x, y, count, chars, fontEncoding, drawFunc)
909: DrawablePtr pDraw;
910: GCPtr pGC;
911: int x,
912: y;
913: int count;
914: char *chars;
915: FontEncoding fontEncoding;
916: void (*drawFunc)();
917: {
918: CharInfoPtr *charinfo;
919: unsigned int n, w = 0;
920: register int xorg, yorg;
921: ExtentInfoRec extents;
922: BoxRec cursorBox;
923:
924: charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr));
925: if (charinfo == (CharInfoPtr *) NULL) {
926: return x;
927: }
928:
929: GetGlyphs(pGC->font, count, chars, fontEncoding, &n, charinfo);
930:
931: if (n != 0) {
932: QueryGlyphExtents(pGC->font, charinfo, n, &extents);
933: w = extents.overallWidth;
934:
935: if (sunCursorLoc(pDraw->pScreen, &cursorBox)) {
936: xorg = ((WindowPtr) pDraw)->absCorner.x;
937: yorg = ((WindowPtr) pDraw)->absCorner.y;
938:
939: if (BOX_OVERLAP(&cursorBox,
940: x + xorg + extents.overallLeft,
941: y + yorg - extents.overallAscent,
942: x + xorg + extents.overallRight,
943: y + yorg + extents.overallDescent)) {
944: sunRemoveCursor();
945: }
946: }
947:
948: (*drawFunc) (pDraw, pGC, x, y, n, charinfo, pGC->font->pGlyphs);
949:
950: }
951: DEALLOCATE_LOCAL(charinfo);
952: return x + w;
953: }
954:
955: /*-
956: *-----------------------------------------------------------------------
957: * sunPolyText8 --
958: *
959: * Results:
960: *
961: * Side Effects:
962: *
963: *-----------------------------------------------------------------------
964: */
965: int
966: sunPolyText8(pDraw, pGC, x, y, count, chars)
967: DrawablePtr pDraw;
968: GCPtr pGC;
969: int x, y;
970: int count;
971: char *chars;
972: {
973: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
974:
975: COMPARE_GCS(pGC,pShadowGC);
976: if (pDraw->type == DRAWABLE_WINDOW) {
977: return sunText (pDraw, pShadowGC, x, y, count, chars, Linear8Bit,
978: pShadowGC->PolyGlyphBlt);
979: } else {
980: return (* pShadowGC->PolyText8)(pDraw, pShadowGC, x, y, count, chars);
981: }
982: }
983:
984: /*-
985: *-----------------------------------------------------------------------
986: * sunPolyText16 --
987: *
988: * Results:
989: *
990: * Side Effects:
991: *
992: *-----------------------------------------------------------------------
993: */
994: int
995: sunPolyText16(pDraw, pGC, x, y, count, chars)
996: DrawablePtr pDraw;
997: GCPtr pGC;
998: int x, y;
999: int count;
1000: unsigned short *chars;
1001: {
1002: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
1003:
1004: COMPARE_GCS(pGC,pShadowGC);
1005: if (pDraw->type == DRAWABLE_WINDOW) {
1006: return sunText (pDraw, pShadowGC, x, y, count, chars,
1007: (pShadowGC->font->pFI->lastRow == 0 ?
1008: Linear16Bit : TwoD16Bit),
1009: pShadowGC->PolyGlyphBlt);
1010: } else {
1011: return (* pShadowGC->PolyText16) (pDraw, pShadowGC, x, y,
1012: count, chars);
1013: }
1014: }
1015:
1016: /*-
1017: *-----------------------------------------------------------------------
1018: * sunImageText8 --
1019: *
1020: * Results:
1021: *
1022: * Side Effects:
1023: *
1024: *-----------------------------------------------------------------------
1025: */
1026: void
1027: sunImageText8(pDraw, pGC, x, y, count, chars)
1028: DrawablePtr pDraw;
1029: GCPtr pGC;
1030: int x, y;
1031: int count;
1032: char *chars;
1033: {
1034: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
1035:
1036: COMPARE_GCS(pGC,pShadowGC);
1037: if (pDraw->type == DRAWABLE_WINDOW) {
1038: (void) sunText (pDraw, pShadowGC, x, y, count, chars,
1039: Linear8Bit, pShadowGC->ImageGlyphBlt);
1040: } else {
1041: (* pShadowGC->ImageText8) (pDraw, pShadowGC, x, y, count, chars);
1042: }
1043: }
1044:
1045: /*-
1046: *-----------------------------------------------------------------------
1047: * sunImageText16 --
1048: *
1049: * Results:
1050: *
1051: * Side Effects:
1052: *
1053: *-----------------------------------------------------------------------
1054: */
1055: void
1056: sunImageText16(pDraw, pGC, x, y, count, chars)
1057: DrawablePtr pDraw;
1058: GCPtr pGC;
1059: int x, y;
1060: int count;
1061: unsigned short *chars;
1062: {
1063: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
1064:
1065: COMPARE_GCS(pGC,pShadowGC);
1066: if (pDraw->type == DRAWABLE_WINDOW) {
1067: (void) sunText (pDraw, pShadowGC, x, y, count, chars,
1068: (pShadowGC->font->pFI->lastRow == 0 ?
1069: Linear16Bit : TwoD16Bit),
1070: pShadowGC->ImageGlyphBlt);
1071: } else {
1072: (* pShadowGC->ImageText16) (pDraw, pShadowGC, x, y, count, chars);
1073: }
1074: }
1075:
1076: /*-
1077: *-----------------------------------------------------------------------
1078: * sunImageGlyphBlt --
1079: *
1080: * Results:
1081: *
1082: * Side Effects:
1083: *
1084: *-----------------------------------------------------------------------
1085: */
1086: void
1087: sunImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
1088: DrawablePtr pDrawable;
1089: GC *pGC;
1090: int x, y;
1091: unsigned int nglyph;
1092: CharInfoPtr *ppci; /* array of character info */
1093: pointer pglyphBase; /* start of array of glyphs */
1094: {
1095: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
1096: BoxRec cursorBox;
1097: ExtentInfoRec extents;
1098: register int xorg,
1099: yorg;
1100:
1101: if (pDrawable->type == DRAWABLE_WINDOW &&
1102: sunCursorLoc (pDrawable->pScreen, &cursorBox)) {
1103: QueryGlyphExtents (pGC->font, ppci, nglyph, &extents);
1104: xorg = ((WindowPtr)pDrawable)->absCorner.x + x;
1105: yorg = ((WindowPtr)pDrawable)->absCorner.y + y;
1106: if (BOX_OVERLAP(&cursorBox,xorg+extents.overallLeft,
1107: yorg+extents.overallAscent,
1108: xorg+extents.overallRight,
1109: yorg+extents.overallDescent)) {
1110: sunRemoveCursor();
1111: }
1112: }
1113:
1114: COMPARE_GCS(pGC,pShadowGC);
1115: (* pShadowGC->ImageGlyphBlt) (pDrawable, pShadowGC, x, y, nglyph,
1116: ppci, pglyphBase);
1117: }
1118:
1119: /*-
1120: *-----------------------------------------------------------------------
1121: * sunPolyGlyphBlt --
1122: *
1123: * Results:
1124: *
1125: * Side Effects:
1126: *
1127: *-----------------------------------------------------------------------
1128: */
1129: void
1130: sunPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
1131: DrawablePtr pDrawable;
1132: GCPtr pGC;
1133: int x, y;
1134: unsigned int nglyph;
1135: CharInfoPtr *ppci; /* array of character info */
1136: char *pglyphBase; /* start of array of glyphs */
1137: {
1138: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
1139: BoxRec cursorBox;
1140: ExtentInfoRec extents;
1141: register int xorg,
1142: yorg;
1143:
1144: if (pDrawable->type == DRAWABLE_WINDOW &&
1145: sunCursorLoc (pDrawable->pScreen, &cursorBox)) {
1146: QueryGlyphExtents (pGC->font, ppci, nglyph, &extents);
1147: xorg = ((WindowPtr)pDrawable)->absCorner.x + x;
1148: yorg = ((WindowPtr)pDrawable)->absCorner.y + y;
1149: if (BOX_OVERLAP(&cursorBox,xorg+extents.overallLeft,
1150: yorg+extents.overallAscent,
1151: xorg+extents.overallRight,
1152: yorg+extents.overallDescent)){
1153: sunRemoveCursor();
1154: }
1155: }
1156:
1157: COMPARE_GCS(pGC,pShadowGC);
1158: (* pShadowGC->PolyGlyphBlt) (pDrawable, pShadowGC, x, y,
1159: nglyph, ppci, pglyphBase);
1160: }
1161:
1162: /*-
1163: *-----------------------------------------------------------------------
1164: * sunPushPixels --
1165: *
1166: * Results:
1167: *
1168: * Side Effects:
1169: *
1170: *-----------------------------------------------------------------------
1171: */
1172: void
1173: sunPushPixels(pGC, pBitMap, pDst, w, h, x, y)
1174: GCPtr pGC;
1175: PixmapPtr pBitMap;
1176: DrawablePtr pDst;
1177: int w, h, x, y;
1178: {
1179:
1180: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
1181: BoxRec cursorBox;
1182: register int xorg,
1183: yorg;
1184:
1185: if (pDst->type == DRAWABLE_WINDOW &&
1186: sunCursorLoc (pDst->pScreen, &cursorBox)) {
1187: xorg = ((WindowPtr)pDst)->absCorner.x + x;
1188: yorg = ((WindowPtr)pDst)->absCorner.y + y;
1189:
1190: if (BOX_OVERLAP(&cursorBox,xorg,yorg,xorg+w,yorg+h)){
1191: sunRemoveCursor();
1192: }
1193: }
1194:
1195: COMPARE_GCS(pGC,pShadowGC);
1196: (* pShadowGC->PushPixels) (pShadowGC, pBitMap, pDst, w, h, x, y);
1197: }
1198:
1199: /*-
1200: *-----------------------------------------------------------------------
1201: * sunLineHelper --
1202: *
1203: * Results:
1204: *
1205: * Side Effects:
1206: *
1207: *-----------------------------------------------------------------------
1208: */
1209: void
1210: sunLineHelper (pDraw, pGC, caps, npt, pPts, xOrg, yOrg)
1211: DrawablePtr pDraw;
1212: GCPtr pGC;
1213: int caps;
1214: int npt;
1215: SppPointPtr pPts;
1216: int xOrg, yOrg;
1217: {
1218: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
1219:
1220: COMPARE_GCS(pGC,pShadowGC);
1221: (* pShadowGC->LineHelper) (pDraw, pShadowGC, caps, npt, pPts, xOrg, yOrg);
1222: }
1223:
1224: /*-
1225: *-----------------------------------------------------------------------
1226: * sunChangeClip --
1227: * Front end for changing the clip in the GC. Just passes the command
1228: * on through the shadow GC.
1229: *
1230: *
1231: * Results:
1232: * None.
1233: *
1234: * Side Effects:
1235: * ???
1236: *
1237: *-----------------------------------------------------------------------
1238: */
1239: void
1240: sunChangeClip (pGC, type, pValue, numRects)
1241: GCPtr pGC;
1242: int type;
1243: pointer pValue;
1244: int numRects;
1245: {
1246: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
1247:
1248: COMPARE_GCS(pGC,pShadowGC);
1249: (* pShadowGC->ChangeClip) (pShadowGC, type, pValue, numRects);
1250: /*
1251: * Now copy the clip info back from the shadow to the real
1252: * GC so that if we use it as the source for a CopyGC,
1253: * the clip info will get copied along with everything
1254: * else.
1255: */
1256: pGC->clientClip = pShadowGC->clientClip;
1257: pGC->clientClipType = pShadowGC->clientClipType;
1258: }
1259:
1260: /*-
1261: *-----------------------------------------------------------------------
1262: * sunDestroyClip --
1263: * Ditto for destroying the clipping region of the GC.
1264: *
1265: * Results:
1266: * None.
1267: *
1268: * Side Effects:
1269: * ???
1270: *
1271: *-----------------------------------------------------------------------
1272: */
1273: void
1274: sunDestroyClip (pGC)
1275: GCPtr pGC;
1276: {
1277: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
1278:
1279: COMPARE_GCS(pGC,pShadowGC);
1280: (* pShadowGC->DestroyClip) (pShadowGC);
1281: }
1282:
1283: /*-
1284: *-----------------------------------------------------------------------
1285: * sunCopyClip --
1286: * Ditto for copying the clipping region of the GC.
1287: *
1288: * Results:
1289: * None.
1290: *
1291: * Side Effects:
1292: * ???
1293: *
1294: *-----------------------------------------------------------------------
1295: */
1296: void
1297: sunCopyClip (pgcDst, pgcSrc)
1298: GCPtr pgcDst, pgcSrc;
1299: {
1300: register GCPtr pShadowSrcGC = (GCPtr) pgcSrc->devPriv;
1301: register GCPtr pShadowDstGC = (GCPtr) pgcDst->devPriv;
1302:
1303: COMPARE_GCS(pgcSrc, pShadowSrcGC);
1304: COMPARE_GCS(pgcDst, pShadowDstGC);
1305: (* pShadowDstGC->CopyClip) (pShadowDstGC, pShadowSrcGC);
1306: }
1307:
1308: /*-
1309: *-----------------------------------------------------------------------
1310: * sunDestroyGC --
1311: * Function called when a GC is being freed. Simply unlinks and frees
1312: * the GCInterest structure.
1313: *
1314: * Results:
1315: * None.
1316: *
1317: * Side Effects:
1318: * The GCInterest structure is removed from the chain but its own
1319: * links are untouched (so FreeGC has something to follow...)
1320: *
1321: *-----------------------------------------------------------------------
1322: */
1323: void
1324: sunDestroyGC (pGC, pGCI)
1325: GCPtr pGC; /* GC pGCI is attached to */
1326: GCInterestPtr pGCI; /* GCInterest being destroyed */
1327: {
1328: if (pGC->devPriv)
1329: FreeGC ((GCPtr)pGC->devPriv);
1330: Xfree (pGCI);
1331: }
1332:
1333: /*-
1334: *-----------------------------------------------------------------------
1335: * sunValidateGC --
1336: * Called when a GC is about to be used for drawing. Copies all
1337: * changes from the GC to its shadow and validates the shadow.
1338: *
1339: * Results:
1340: * TRUE, for no readily apparent reason.
1341: *
1342: * Side Effects:
1343: * Vectors in the shadow GC will likely be changed.
1344: *
1345: *-----------------------------------------------------------------------
1346: */
1347: /*ARGSUSED*/
1348: static void
1349: sunValidateGC (pGC, pGCI, changes, pDrawable)
1350: GCPtr pGC;
1351: GCInterestPtr pGCI;
1352: Mask changes;
1353: DrawablePtr pDrawable;
1354: {
1355: register GCPtr pShadowGC = (GCPtr) pGC->devPriv;
1356:
1357: if ( pGC->depth != pDrawable->depth )
1358: FatalError( "sunValidateGC: depth mismatch.\n" );
1359:
1360: /*
1361: * sunValidateGC copies the GC to the shadow. Alas,
1362: * sunChangeClip has stored the new clip in the shadow,
1363: * where it will be overwritten, unless we pretend
1364: * that the clip hasn't changed.
1365: */
1366: changes &= ~GCClipMask;
1367:
1368: CopyGC (pGC, pShadowGC, changes);
1369: pShadowGC->serialNumber = pGC->serialNumber;
1370: COMPARE_GCS(pGC,pShadowGC);
1371: ValidateGC (pDrawable, pShadowGC);
1372: }
1373:
1374: /*-
1375: *-----------------------------------------------------------------------
1376: * sunCopyGC --
1377: * Called when a GC with its shadow is the destination of a copy.
1378: * Calls CopyGC to transfer the changes to the shadow GC as well.
1379: * Should not be used for the CopyGCSource since we like to copy from
1380: * the real GC to the shadow using CopyGC...
1381: *
1382: * Results:
1383: * None.
1384: *
1385: * Side Effects:
1386: * Any changes in the real GC are copied to the shadow.
1387: *
1388: *-----------------------------------------------------------------------
1389: */
1390: /*ARGSUSED*/
1391: void
1392: sunCopyGC (pGCDst, pGCI, changes, pGCSrc)
1393: GCPtr pGCDst;
1394: GCInterestPtr pGCI;
1395: int changes;
1396: GCPtr pGCSrc;
1397: {
1398: CopyGC (pGCSrc, (GCPtr) pGCDst->devPriv, changes);
1399: COMPARE_GCS(pGCSrc,(GCPtr) pGCDst->devPriv);
1400: }
1401:
1402: /*
1403: * Array of functions to replace the functions in the GC.
1404: * Caveat: Depends on the ordering of functions in the GC structure.
1405: */
1406: static void (* sunGCFuncs[]) () = {
1407: sunFillSpans,
1408: sunSetSpans,
1409:
1410: sunPutImage,
1411: sunCopyArea,
1412: sunCopyPlane,
1413: sunPolyPoint,
1414: sunPolylines,
1415: sunPolySegment,
1416: sunPolyRectangle,
1417: sunPolyArc,
1418: sunFillPolygon,
1419: sunPolyFillRect,
1420: sunPolyFillArc,
1421: (void(*)())sunPolyText8,
1422: (void(*)())sunPolyText16,
1423: sunImageText8,
1424: sunImageText16,
1425: sunImageGlyphBlt,
1426: sunPolyGlyphBlt,
1427: sunPushPixels,
1428: sunLineHelper,
1429: sunChangeClip,
1430: sunDestroyClip,
1431: sunCopyClip,
1432: };
1433:
1434: /*-
1435: *-----------------------------------------------------------------------
1436: * sunCreatePrivGC --
1437: * Create a GC private to the Sun DDX code. Such a GC is unhampered
1438: * by any shadow GC and should only be used by functions which know
1439: * what they are doing. This substitutes the old CreateGC function
1440: * in the drawable's screen's vector and calls the DIX CreateGC
1441: * function. Once done, it restores the CreateGC vector to its
1442: * proper state and returns the GCPtr CreateGC gave back.
1443: *
1444: * Results:
1445: * A pointer to the new GC.
1446: *
1447: * Side Effects:
1448: * The GC's graphicsExposures field is set FALSE.
1449: *
1450: *-----------------------------------------------------------------------
1451: */
1452: /*ARGSUSED*/
1453: GCPtr
1454: sunCreatePrivGC(pDrawable, mask, pval, pStatus)
1455: DrawablePtr pDrawable;
1456: BITS32 mask;
1457: long *pval;
1458: BITS32 *pStatus;
1459: {
1460: fbFd *fb;
1461: GCPtr pGC;
1462: BITS32 ge = FALSE;
1463:
1464: fb = &sunFbs[pDrawable->pScreen->myNum];
1465: pDrawable->pScreen->CreateGC = fb->CreateGC;
1466:
1467: pGC = GetScratchGC (pDrawable->depth, pDrawable->pScreen);
1468: ChangeGC (pGC, mask, pval);
1469: ChangeGC (pGC, GCGraphicsExposures, &ge);
1470:
1471: pDrawable->pScreen->CreateGC = sunCreateGC;
1472:
1473: return pGC;
1474: }
1475:
1476: /*-
1477: *-----------------------------------------------------------------------
1478: * sunCreateGC --
1479: * This function is used to get our own validation hooks into each
1480: * GC to preserve the cursor. It calls the regular creation routine
1481: * for the screen and then, if that was successful, tacks another
1482: * GCInterest structure onto the GC *after* the one placed on by
1483: * the screen-specific CreateGC...
1484: *
1485: * Results:
1486: * TRUE if created ok. FALSE otherwise.
1487: *
1488: * Side Effects:
1489: * A GCInterest structure is stuck on the end of the GC's list.
1490: *
1491: *-----------------------------------------------------------------------
1492: */
1493: Bool
1494: sunCreateGC (pGC)
1495: GCPtr pGC; /* The GC to play with */
1496: {
1497: GCInterestPtr pGCI;
1498: register GCPtr pShadowGC;
1499: int i;
1500:
1501: if ((*sunFbs[pGC->pScreen->myNum].CreateGC) (pGC)) {
1502:
1503: if (pGC->depth != pGC->pScreen->rootDepth) {
1504: /* This GC will never be used for painting the screen, so no shadow needed */
1505: return TRUE;
1506: }
1507:
1508: pShadowGC = (GCPtr) Xalloc (sizeof (GC));
1509: if (pShadowGC == (GCPtr)NULL) {
1510: return FALSE;
1511: }
1512:
1513: *pShadowGC = *pGC;
1514: pGC->devPriv = (pointer)pShadowGC;
1515: bcopy (sunGCFuncs, &pGC->FillSpans, sizeof (sunGCFuncs));
1516:
1517: pGCI = (GCInterestPtr) Xalloc (sizeof (GCInterestRec));
1518: if (!pGCI) {
1519: return FALSE;
1520: }
1521:
1522: /*
1523: * Any structure being shared between these two GCs must have its
1524: * reference count incremented. This includes:
1525: * font, tile, stipple.
1526: * Anything which doesn't have a reference count must be duplicated:
1527: * pCompositeClip, pAbsClientRegion.
1528: *
1529: */
1530: if (pGC->font) {
1531: pGC->font->refcnt++;
1532: }
1533: if (pGC->tile) {
1534: pGC->tile->refcnt++;
1535: }
1536: if (pGC->stipple) {
1537: pGC->stipple->refcnt++;
1538: }
1539: pShadowGC->dash = (unsigned char *)
1540: Xalloc(2 * sizeof(unsigned char));
1541: for (i=0; i<pGC->numInDashList; i++)
1542: pShadowGC->dash[i] = pGC->dash[i];
1543:
1544: #ifdef notdef
1545: if (pGC->pCompositeClip) {
1546: pShadowGC->pCompositeClip =
1547: (* pGC->pScreen->RegionCreate) (NULL, 1);
1548: (* pGC->pScreen->RegionCopy) (pShadowGC->pCompositeClip,
1549: pGC->pCompositeClip);
1550: }
1551: if (pGC->pAbsClientRegion) {
1552: pShadowGC->pAbsClientRegion=
1553: (* pGC->pScreen->RegionCreate) (NULL, 1);
1554: (* pGC->pScreen->RegionCopy) (pShadowGC->pAbsClientRegion,
1555: pGC->pAbsClientRegion);
1556: }
1557: #endif notdef
1558:
1559: pGC->pNextGCInterest = pGCI;
1560: pGC->pLastGCInterest = pGCI;
1561: pGCI->pNextGCInterest = (GCInterestPtr) &pGC->pNextGCInterest;
1562: pGCI->pLastGCInterest = (GCInterestPtr) &pGC->pNextGCInterest;
1563: pGCI->length = sizeof(GCInterestRec);
1564: pGCI->owner = 0; /* server owns this */
1565: pGCI->ValInterestMask = ~0; /* interested in everything */
1566: pGCI->ValidateGC = sunValidateGC;
1567: pGCI->ChangeInterestMask = 0; /* interested in nothing */
1568: pGCI->ChangeGC = (int (*)()) NULL;
1569: pGCI->CopyGCSource = (void (*)())NULL;
1570: pGCI->CopyGCDest = sunCopyGC;
1571: pGCI->DestroyGC = sunDestroyGC;
1572:
1573:
1574: /*
1575: * Because of this weird way of handling the GCInterest lists,
1576: * we need to modify the output library's GCInterest structure to
1577: * point to the pNextGCInterest field of the shadow GC...
1578: */
1579: pGCI = pShadowGC->pNextGCInterest;
1580: pGCI->pLastGCInterest = pGCI->pNextGCInterest =
1581: (GCInterestPtr) &pShadowGC->pNextGCInterest;
1582:
1583: return TRUE;
1584: } else {
1585: return FALSE;
1586: }
1587: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.