|
|
1.1 root 1: /***********************************************************
2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
4:
5: All Rights Reserved
6:
7: Permission to use, copy, modify, and distribute this software and its
8: documentation for any purpose and without fee is hereby granted,
9: provided that the above copyright notice appear in all copies and that
10: both that copyright notice and this permission notice appear in
11: supporting documentation, and that the names of Digital or MIT not be
12: used in advertising or publicity pertaining to distribution of the
13: software without specific, written prior permission.
14:
15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21: SOFTWARE.
22:
23: ******************************************************************/
24:
25: /* $Header: miexpose.c,v 1.25 87/09/11 07:19:01 toddb Exp $ */
26:
27: #include "X.h"
28: #define NEED_EVENTS
29: #include "Xproto.h"
30: #include "Xprotostr.h"
31:
32: #include "misc.h"
33: #include "regionstr.h"
34: #include "scrnintstr.h"
35: #include "gcstruct.h"
36: #include "windowstr.h"
37: #include "pixmap.h"
38:
39: #include "dixstruct.h"
40: #include "mi.h"
41: #include "Xmd.h"
42:
43: extern WindowRec WindowTable[];
44:
45: /*
46: machine-independent graphics exposure code. any device that uses
47: the region package can call this.
48: */
49:
50:
51: /* miHandleExposures
52: generate exposures for areas that were copied from obscured or
53: non-existent areas to non-obscured areas of the destination.
54:
55: NOTE:
56: this code sends the exposure events, then paints the background.
57: this will NOT work unless this routine is allowed to complete before
58: the dispatcher looks at this client again.
59:
60: NOTE:
61: this does not deal with backing store.
62: */
63:
64: void
65: miHandleExposures(pSrcDrawable, pDstDrawable,
66: pGC, srcx, srcy, width, height, dstx, dsty)
67: register DrawablePtr pSrcDrawable;
68: register DrawablePtr pDstDrawable;
69: GCPtr pGC;
70: int srcx, srcy;
71: int width, height;
72: int dstx, dsty;
73: {
74: register ScreenPtr pscr = pGC->pScreen;
75: RegionPtr prgnSrcClip; /* drawable-relative source clip */
76: RegionPtr prgnDstClip; /* drawable-relative dest clip */
77: BoxRec srcBox; /* unclipped source */
78: RegionPtr prgnSrc; /* clipped source */
79: RegionPtr prgnExposed; /* exposed region, calculated source-
80: relative, made dst relative to
81: intersect with visible parts of
82: dest and send events to client,
83: and then screen relative to paint
84: the window background
85: */
86:
87: if (pSrcDrawable->type == DRAWABLE_WINDOW)
88: {
89: prgnSrcClip = (*pscr->RegionCreate)(NullBox, 1);
90: (*pscr->RegionCopy)(prgnSrcClip,
91: ((WindowPtr)pSrcDrawable)->clipList);
92: (*pscr->TranslateRegion)(prgnSrcClip,
93: -((WindowPtr)pSrcDrawable)->absCorner.x,
94: -((WindowPtr)pSrcDrawable)->absCorner.y);
95: }
96: else
97: {
98: BoxRec box;
99:
100: box.x1 = 0;
101: box.y1 = 0;
102: box.x2 = ((PixmapPtr)pSrcDrawable)->width;
103: box.y2 = ((PixmapPtr)pSrcDrawable)->height;
104: prgnSrcClip = (*pscr->RegionCreate)(&box, 1);
105: }
106:
107: if (pDstDrawable->type == DRAWABLE_WINDOW)
108: {
109: prgnDstClip = (*pscr->RegionCreate)(NullBox, 1);
110: (*pscr->RegionCopy)(prgnDstClip,
111: ((WindowPtr)pDstDrawable)->clipList);
112: (*pscr->TranslateRegion)(prgnDstClip,
113: -((WindowPtr)pDstDrawable)->absCorner.x,
114: -((WindowPtr)pDstDrawable)->absCorner.y);
115: }
116: else
117: {
118: BoxRec box;
119:
120: box.x1 = 0;
121: box.y1 = 0;
122: box.x2 = ((PixmapPtr)pDstDrawable)->width;
123: box.y2 = ((PixmapPtr)pDstDrawable)->height;
124: prgnDstClip = (*pscr->RegionCreate)(&box, 1);
125: }
126:
127: /* drawable-relative source region */
128: srcBox.x1 = srcx;
129: srcBox.y1 = srcy;
130: srcBox.x2 = srcx+width;
131: srcBox.y2 = srcy+height;
132: prgnSrc = (*pscr->RegionCreate)(&srcBox, 1);
133:
134: /* get the visible parts of the source box */
135: (*pscr->Intersect)(prgnSrc, prgnSrc, prgnSrcClip);
136:
137: /* now get the hidden parts */
138: prgnExposed = (*pscr->RegionCreate)(NullBox, 1);
139: (*pscr->Inverse)(prgnExposed, prgnSrc, &srcBox);
140:
141: /* move them over the destination */
142: (*pscr->TranslateRegion)(prgnExposed, dstx-srcx, dsty-srcy);
143:
144: /* intersect with visible areas of dest */
145: (*pscr->Intersect)(prgnExposed, prgnExposed, prgnDstClip);
146:
147: /* send them to the client */
148: if (pGC->graphicsExposures)
149: {
150: if (REGION_NOT_EMPTY(prgnExposed))
151: {
152: xEvent *pEvent;
153: register xEvent *pe;
154: register BoxPtr pBox = prgnExposed->rects;
155: register int i;
156:
157: if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(prgnExposed->numRects *
158: sizeof(xEvent))))
159: return;
160: pe = pEvent;
161:
162: for (i=1; i<=prgnExposed->numRects; i++, pe++, pBox++)
163: {
164: pe->u.u.type = GraphicsExpose;
165: pe->u.graphicsExposure.drawable =
166: requestingClient->lastDrawableID;
167: pe->u.graphicsExposure.x = pBox->x1;
168: pe->u.graphicsExposure.y = pBox->y1;
169: pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
170: pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
171: pe->u.graphicsExposure.count = prgnExposed->numRects - i;
172:
173: }
174: TryClientEvents(requestingClient, pEvent, prgnExposed->numRects,
175: 0, NoEventMask, 0);
176: DEALLOCATE_LOCAL(pEvent);
177: }
178: else
179: {
180: xEvent event;
181: event.u.u.type = NoExpose;
182: event.u.noExposure.drawable = requestingClient->lastDrawableID;
183: TryClientEvents(requestingClient, &event, 1,
184: 0, NoEventMask, 0);
185: }
186: }
187:
188:
189: if ((pDstDrawable->type == DRAWABLE_WINDOW) &&
190: (((WindowPtr)pDstDrawable)->backgroundTile != None))
191: {
192: WindowPtr pWin = (WindowPtr)pDstDrawable;
193:
194: /* make the exposed area screen-relative */
195: (*pscr->TranslateRegion)(prgnExposed,
196: pWin->absCorner.x, pWin->absCorner.y);
197:
198: (*pWin->PaintWindowBackground)(pDstDrawable, prgnExposed,
199: PW_BACKGROUND);
200: }
201: (*pscr->RegionDestroy)(prgnDstClip);
202: (*pscr->RegionDestroy)(prgnSrcClip);
203: (*pscr->RegionDestroy)(prgnSrc);
204: (*pscr->RegionDestroy)(prgnExposed);
205: }
206:
207: void
208: miSendNoExpose(pGC)
209: GCPtr pGC;
210: {
211: if (pGC->graphicsExposures)
212: {
213: xEvent event;
214: event.u.u.type = NoExpose;
215: event.u.noExposure.drawable =
216: requestingClient->lastDrawableID;
217: TryClientEvents(requestingClient, &event, 1,
218: 0, NoEventMask, 0);
219: }
220: }
221:
222:
223: void
224: miWindowExposures(pWin)
225: WindowPtr pWin;
226: {
227: register RegionPtr prgn;
228:
229: prgn = pWin->exposed;
230: if (prgn->numRects)
231: {
232: xEvent *pEvent;
233: register xEvent *pe;
234: register BoxPtr pBox;
235: register int i;
236:
237: (*pWin->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
238: (* pWin->drawable.pScreen->TranslateRegion)(prgn,
239: -pWin->absCorner.x, -pWin->absCorner.y);
240: if (pWin->backingStore != NotUseful && pWin->backStorage)
241: {
242: /* modifies pWin->exposed */
243: (*pWin->backStorage->RestoreAreas)(pWin);
244: }
245: pBox = prgn->rects;
246:
247: if(!(pEvent = (xEvent *)
248: ALLOCATE_LOCAL(prgn->numRects * sizeof(xEvent))))
249: return;
250: pe = pEvent;
251:
252: for (i=1; i<=prgn->numRects; i++, pe++, pBox++)
253: {
254: pe->u.u.type = Expose;
255: pe->u.expose.window = pWin->wid;
256: pe->u.expose.x = pBox->x1;
257: pe->u.expose.y = pBox->y1;
258: pe->u.expose.width = pBox->x2 - pBox->x1;
259: pe->u.expose.height = pBox->y2 - pBox->y1;
260: pe->u.expose.count = (prgn->numRects - i);
261: }
262: DeliverEvents(pWin, pEvent, prgn->numRects, NullWindow);
263: prgn->numRects = 0;
264: DEALLOCATE_LOCAL(pEvent);
265: }
266: }
267:
268:
269: /*
270: this code is highly unlikely. it is not haile selassie.
271:
272: there is some hair here. we can't just use the window's
273: clip region as it is, because if we are painting the border,
274: the border is not in the client area and so we will be excluded
275: when we validate the GC, and if we are painting a parent-relative
276: background, the area we want to paint is in some other window.
277: since we trust the code calling us to tell us to paint only areas
278: that are really ours, we will temporarily give the window a
279: clipList the size of the whole screen and an origin at (0,0).
280: this more or less assumes that ddX code will do translation
281: based on the window's absCorner, and that ValidateGC will
282: look at clipList, and that no other fields from the
283: window will be used. it's not possible to just draw
284: in the root because it may be a different depth.
285:
286: to get the tile to align correctly we set the GC's tile origin to
287: be the (x,y) of the window's upper left corner, after which we
288: get the right bits when drawing into the root.
289:
290: in order to call ChangeGC, we need to get an id for the pixmap, and
291: enter it in the resource table.
292: */
293: void
294: miPaintWindow(pWin, prgn, what)
295: WindowPtr pWin;
296: RegionPtr prgn;
297: int what;
298: {
299: int gcval[6];
300: int gcmask;
301: RegionPtr prgnWin;
302: DDXPointRec oldCorner;
303: BoxRec box;
304: GCPtr pGC;
305: int pid = 0;
306: register int i;
307: register BoxPtr pbox;
308: register ScreenPtr pScreen = pWin->drawable.pScreen;
309: register xRectangle *prect;
310:
311: gcval[0] = GXcopy;
312: gcval[3] = pWin->absCorner.x;
313: gcval[4] = pWin->absCorner.y;
314: gcval[5] = None;
315: gcmask = GCFunction | GCFillStyle |
316: GCTileStipXOrigin | GCTileStipYOrigin | GCClipMask;
317: if (what == PW_BACKGROUND)
318: {
319: if (pWin->backgroundTile == None)
320: return;
321: else if ((int)pWin->backgroundTile == ParentRelative)
322: {
323: (*pWin->parent->PaintWindowBorder)(pWin->parent, prgn, what);
324: return;
325: }
326: else if ((int)pWin->backgroundTile == USE_BACKGROUND_PIXEL)
327: {
328: gcval[1] = pWin->backgroundPixel;
329: gcval[2] = FillSolid;
330: gcmask |= GCForeground;
331: }
332: else
333: {
334: gcval[1] = FillTiled;
335: pid = FakeClientID(0);
336: AddResource(pid, RT_PIXMAP, pWin->backgroundTile,
337: NoopDDA, RC_CORE);
338: gcval[2] = pid;
339: gcmask |= GCTile;
340: }
341: }
342: else
343: {
344: if (pWin->borderTile == None)
345: return;
346: else if ((int)pWin->borderTile == USE_BORDER_PIXEL)
347: {
348: gcval[1] = pWin->borderPixel;
349: gcval[2] = FillSolid;
350: gcmask |= GCForeground;
351: }
352: else
353: {
354: gcval[1] = FillTiled;
355: pid = FakeClientID(0);
356: AddResource(pid, RT_PIXMAP, pWin->borderTile,
357: NoopDDA, RC_CORE);
358: gcval[2] = pid;
359: gcmask |= GCTile;
360: }
361: }
362: pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
363: DoChangeGC(pGC, gcmask, gcval, 0);
364:
365: box.x1 = 0;
366: box.y1 = 0;
367: box.x2 = pScreen->width;
368: box.y2 = pScreen->height;
369:
370: prgnWin = pWin->clipList;
371: oldCorner = pWin->absCorner;
372: pWin->absCorner.x = pWin->absCorner.y = 0;
373: pWin->clipList = (*pScreen->RegionCreate)(&box, 1);
374: pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
375: ValidateGC(pWin, pGC);
376:
377: prect = (xRectangle *)ALLOCATE_LOCAL(prgn->numRects * sizeof(xRectangle));
378: pbox = prgn->rects;
379: for (i= 0; i < prgn->numRects; i++, pbox++, prect++)
380: {
381: prect->x = pbox->x1;
382: prect->y = pbox->y1;
383: prect->width = pbox->x2 - pbox->x1;
384: prect->height = pbox->y2 - pbox->y1;
385: }
386: prect -= prgn->numRects;
387: (*pGC->PolyFillRect)(pWin, pGC, prgn->numRects, prect);
388: DEALLOCATE_LOCAL(prect);
389:
390: if (pid)
391: FreeResource(pid, RC_CORE);
392: (*pScreen->RegionDestroy)(pWin->clipList);
393: pWin->clipList = prgnWin;
394: pWin->absCorner = oldCorner;
395: pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
396: FreeScratchGC(pGC);
397: }
398:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.