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