1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | #ifdef HAVE_DIX_CONFIG_H1 |
75 | #include <dix-config.h> |
76 | #endif |
77 | |
78 | #include <X11/X.h> |
79 | #include <X11/Xproto.h> |
80 | #include <X11/Xprotostr.h> |
81 | |
82 | #include "misc.h" |
83 | #include "regionstr.h" |
84 | #include "scrnintstr.h" |
85 | #include "gcstruct.h" |
86 | #include "windowstr.h" |
87 | #include "pixmap.h" |
88 | #include "input.h" |
89 | |
90 | #include "dixstruct.h" |
91 | #include "mi.h" |
92 | #include <X11/Xmd.h> |
93 | |
94 | #include "globals.h" |
95 | |
96 | #ifdef PANORAMIX1 |
97 | #include "panoramiX.h" |
98 | #include "panoramiXsrv.h" |
99 | #endif |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | #ifndef RECTLIMIT25 |
107 | #define RECTLIMIT25 25 /* pick a number, any number > 8 */ |
108 | #endif |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | RegionPtr |
122 | miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, |
123 | GCPtr pGC, int srcx, int srcy, int width, int height, |
124 | int dstx, int dsty) |
125 | { |
126 | RegionPtr prgnSrcClip; |
127 | RegionRec rgnSrcRec; |
128 | RegionPtr prgnDstClip; |
129 | RegionRec rgnDstRec; |
130 | BoxRec srcBox; |
131 | RegionRec rgnExposed; |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | WindowPtr pSrcWin; |
139 | BoxRec expBox; |
140 | Bool extents; |
141 | |
142 | |
143 | if (!pGC->graphicsExposures && |
144 | (pDstDrawable->type == DRAWABLE_PIXMAP1) && |
145 | ((pSrcDrawable->type == DRAWABLE_PIXMAP1) || |
146 | (((WindowPtr) pSrcDrawable)->backStorage == 0))) |
147 | return NULL((void*)0); |
148 | |
149 | srcBox.x1 = srcx; |
150 | srcBox.y1 = srcy; |
151 | srcBox.x2 = srcx + width; |
152 | srcBox.y2 = srcy + height; |
153 | |
154 | if (pSrcDrawable->type != DRAWABLE_PIXMAP1) { |
155 | BoxRec TsrcBox; |
156 | |
157 | TsrcBox.x1 = srcx + pSrcDrawable->x; |
158 | TsrcBox.y1 = srcy + pSrcDrawable->y; |
159 | TsrcBox.x2 = TsrcBox.x1 + width; |
160 | TsrcBox.y2 = TsrcBox.y1 + height; |
161 | pSrcWin = (WindowPtr) pSrcDrawable; |
162 | if (pGC->subWindowMode == IncludeInferiors1) { |
163 | prgnSrcClip = NotClippedByChildren(pSrcWin); |
164 | if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN1) { |
165 | RegionDestroy(prgnSrcClip); |
166 | return NULL((void*)0); |
167 | } |
168 | } |
169 | else { |
170 | if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN1) |
171 | return NULL((void*)0); |
172 | prgnSrcClip = &rgnSrcRec; |
173 | RegionNull(prgnSrcClip); |
174 | RegionCopy(prgnSrcClip, &pSrcWin->clipList); |
175 | } |
176 | RegionTranslate(prgnSrcClip, -pSrcDrawable->x, -pSrcDrawable->y); |
177 | } |
178 | else { |
179 | BoxRec box; |
180 | |
181 | if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) && |
182 | (srcBox.x2 <= pSrcDrawable->width) && |
183 | (srcBox.y2 <= pSrcDrawable->height)) |
184 | return NULL((void*)0); |
185 | |
186 | box.x1 = 0; |
187 | box.y1 = 0; |
188 | box.x2 = pSrcDrawable->width; |
189 | box.y2 = pSrcDrawable->height; |
190 | prgnSrcClip = &rgnSrcRec; |
191 | RegionInit(prgnSrcClip, &box, 1); |
192 | pSrcWin = NULL((void*)0); |
193 | } |
194 | |
195 | if (pDstDrawable == pSrcDrawable) { |
196 | prgnDstClip = prgnSrcClip; |
197 | } |
198 | else if (pDstDrawable->type != DRAWABLE_PIXMAP1) { |
199 | if (pGC->subWindowMode == IncludeInferiors1) { |
200 | prgnDstClip = NotClippedByChildren((WindowPtr) pDstDrawable); |
201 | } |
202 | else { |
203 | prgnDstClip = &rgnDstRec; |
204 | RegionNull(prgnDstClip); |
205 | RegionCopy(prgnDstClip, &((WindowPtr) pDstDrawable)->clipList); |
206 | } |
207 | RegionTranslate(prgnDstClip, -pDstDrawable->x, -pDstDrawable->y); |
208 | } |
209 | else { |
210 | BoxRec box; |
211 | |
212 | box.x1 = 0; |
213 | box.y1 = 0; |
214 | box.x2 = pDstDrawable->width; |
215 | box.y2 = pDstDrawable->height; |
216 | prgnDstClip = &rgnDstRec; |
217 | RegionInit(prgnDstClip, &box, 1); |
218 | } |
219 | |
220 | |
221 | RegionInit(&rgnExposed, &srcBox, 1); |
222 | |
223 | |
224 | RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip); |
225 | |
226 | |
227 | RegionTranslate(&rgnExposed, dstx - srcx, dsty - srcy); |
228 | |
229 | |
230 | RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip); |
231 | |
232 | |
233 | if (pGC->clientClip) |
234 | RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip); |
235 | |
236 | |
237 | |
238 | |
239 | |
240 | |
241 | |
242 | |
243 | extents = pGC->graphicsExposures && |
244 | (RegionNumRects(&rgnExposed) > RECTLIMIT25) && |
245 | (pDstDrawable->type != DRAWABLE_PIXMAP1); |
246 | if (pSrcWin) { |
247 | RegionPtr region; |
248 | |
249 | if (!(region = wClipShape(pSrcWin)((pSrcWin)->optional ? (pSrcWin)->optional->clipShape : ((void*)0)))) |
250 | region = wBoundingShape(pSrcWin)((pSrcWin)->optional ? (pSrcWin)->optional->boundingShape : ((void*)0)); |
251 | |
252 | |
253 | |
254 | |
255 | if (extents && pSrcWin && region && |
256 | (RegionContainsRect(region, &srcBox) != rgnIN1)) |
257 | extents = FALSE0; |
258 | } |
259 | if (extents) { |
260 | expBox = *RegionExtents(&rgnExposed); |
261 | RegionReset(&rgnExposed, &expBox); |
262 | } |
263 | if ((pDstDrawable->type != DRAWABLE_PIXMAP1) && |
264 | (((WindowPtr) pDstDrawable)->backgroundState != None0L)) { |
265 | WindowPtr pWin = (WindowPtr) pDstDrawable; |
266 | |
267 | |
268 | RegionTranslate(&rgnExposed, pDstDrawable->x, pDstDrawable->y); |
269 | |
270 | if (extents) { |
271 | |
272 | RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList); |
273 | } |
274 | miPaintWindow((WindowPtr) pDstDrawable, &rgnExposed, PW_BACKGROUND0); |
275 | |
276 | if (extents) { |
277 | RegionReset(&rgnExposed, &expBox); |
278 | } |
279 | else |
280 | RegionTranslate(&rgnExposed, -pDstDrawable->x, -pDstDrawable->y); |
281 | } |
282 | if (prgnDstClip == &rgnDstRec) { |
283 | RegionUninit(prgnDstClip); |
284 | } |
285 | else if (prgnDstClip != prgnSrcClip) { |
286 | RegionDestroy(prgnDstClip); |
287 | } |
288 | |
289 | if (prgnSrcClip == &rgnSrcRec) { |
290 | RegionUninit(prgnSrcClip); |
291 | } |
292 | else { |
293 | RegionDestroy(prgnSrcClip); |
294 | } |
295 | |
296 | if (pGC->graphicsExposures) { |
297 | |
298 | RegionPtr exposed = RegionCreate(NullBox((BoxPtr)0), 0); |
299 | |
300 | *exposed = rgnExposed; |
301 | return exposed; |
302 | } |
303 | else { |
304 | RegionUninit(&rgnExposed); |
305 | return NULL((void*)0); |
306 | } |
307 | } |
308 | |
309 | void |
310 | miSendExposures(WindowPtr pWin, RegionPtr pRgn, int dx, int dy) |
311 | { |
312 | BoxPtr pBox; |
313 | int numRects; |
314 | xEvent *pEvent, *pe; |
315 | int i; |
316 | |
317 | pBox = RegionRects(pRgn); |
318 | numRects = RegionNumRects(pRgn); |
319 | if (!(pEvent = calloc(1, numRects * sizeof(xEvent)))) |
320 | return; |
321 | |
322 | for (i = numRects, pe = pEvent; --i >= 0; pe++, pBox++) { |
323 | pe->u.u.type = Expose12; |
324 | pe->u.expose.window = pWin->drawable.id; |
325 | pe->u.expose.x = pBox->x1 - dx; |
326 | pe->u.expose.y = pBox->y1 - dy; |
327 | pe->u.expose.width = pBox->x2 - pBox->x1; |
328 | pe->u.expose.height = pBox->y2 - pBox->y1; |
329 | pe->u.expose.count = i; |
330 | } |
331 | |
332 | #ifdef PANORAMIX1 |
333 | if (!noPanoramiXExtension) { |
334 | int scrnum = pWin->drawable.pScreen->myNum; |
335 | int x = 0, y = 0; |
336 | XID realWin = 0; |
337 | |
338 | if (!pWin->parent) { |
339 | x = screenInfo.screens[scrnum]->x; |
340 | y = screenInfo.screens[scrnum]->y; |
341 | pWin = screenInfo.screens[0]->root; |
342 | realWin = pWin->drawable.id; |
343 | } |
344 | else if (scrnum) { |
345 | PanoramiXRes *win; |
346 | |
347 | win = PanoramiXFindIDByScrnum(XRT_WINDOW, |
348 | pWin->drawable.id, scrnum); |
349 | if (!win) { |
350 | free(pEvent); |
351 | return; |
352 | } |
353 | realWin = win->info[0].id; |
354 | dixLookupWindow(&pWin, realWin, serverClient, DixSendAccess(1<<22)); |
355 | } |
356 | if (x || y || scrnum) |
357 | for (i = 0; i < numRects; i++) { |
358 | pEvent[i].u.expose.window = realWin; |
359 | pEvent[i].u.expose.x += x; |
360 | pEvent[i].u.expose.y += y; |
361 | } |
362 | } |
363 | #endif |
364 | |
365 | DeliverEvents(pWin, pEvent, numRects, NullWindow((WindowPtr) 0)); |
366 | |
367 | free(pEvent); |
368 | } |
369 | |
370 | void |
371 | miWindowExposures(WindowPtr pWin, RegionPtr prgn) |
372 | { |
373 | RegionPtr exposures = prgn; |
374 | |
375 | if (prgn && !RegionNil(prgn)) { |
| |
376 | RegionRec expRec; |
377 | int clientInterested = |
378 | (pWin->eventMask | wOtherEventMasks(pWin)((pWin)->optional ? (pWin)->optional->otherEventMasks : 0)) & ExposureMask(1L<<15); |
379 | if (clientInterested && (RegionNumRects(prgn) > RECTLIMIT25)) { |
380 | |
381 | |
382 | |
383 | |
384 | |
385 | |
386 | BoxRec box; |
387 | |
388 | box = *RegionExtents(prgn); |
389 | exposures = &expRec; |
390 | RegionInit(exposures, &box, 1); |
391 | RegionReset(prgn, &box); |
392 | |
393 | RegionIntersect(prgn, prgn, &pWin->clipList); |
394 | } |
395 | miPaintWindow(pWin, prgn, PW_BACKGROUND0); |
| |
396 | if (clientInterested) |
397 | miSendExposures(pWin, exposures, |
398 | pWin->drawable.x, pWin->drawable.y); |
399 | if (exposures == &expRec) |
400 | RegionUninit(exposures); |
401 | RegionEmpty(prgn); |
402 | } |
403 | } |
404 | |
405 | #ifdef ROOTLESS1 |
406 | |
407 | void RootlessSetPixmapOfAncestors(WindowPtr pWin); |
408 | void RootlessStartDrawing(WindowPtr pWin); |
409 | void RootlessDamageRegion(WindowPtr pWin, RegionPtr prgn); |
410 | Bool IsFramedWindow(WindowPtr pWin); |
411 | #endif |
412 | |
413 | void |
414 | miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) |
415 | { |
416 | ScreenPtr pScreen = pWin->drawable.pScreen; |
417 | ChangeGCVal gcval[6]; |
418 | BITS32 gcmask; |
419 | GCPtr pGC; |
420 | int i; |
421 | BoxPtr pbox; |
422 | xRectangle *prect; |
423 | int numRects; |
424 | |
425 | |
426 | |
427 | |
428 | |
429 | int draw_x_off, draw_y_off; |
430 | |
431 | |
432 | |
433 | |
434 | |
435 | int tile_x_off, tile_y_off; |
436 | PixUnion fill; |
437 | Bool solid = TRUE1; |
438 | DrawablePtr drawable = &pWin->drawable; |
439 | |
440 | #ifdef ROOTLESS1 |
441 | if (!drawable || drawable->type == UNDRAWABLE_WINDOW2) |
| |
442 | return; |
443 | |
444 | if (IsFramedWindow(pWin)) { |
| |
445 | RootlessStartDrawing(pWin); |
446 | RootlessDamageRegion(pWin, prgn); |
447 | |
448 | if (pWin->backgroundState == ParentRelative1L) { |
| |
449 | if ((what == PW_BACKGROUND0) || |
450 | (what == PW_BORDER1 && !pWin->borderIsPixel)) |
451 | RootlessSetPixmapOfAncestors(pWin); |
452 | } |
453 | } |
454 | #endif |
455 | |
456 | if (what == PW_BACKGROUND0) { |
| |
457 | while (pWin->backgroundState == ParentRelative1L) |
| 7 | | Loop condition is false. Execution continues on line 460 | |
|
458 | pWin = pWin->parent; |
459 | |
460 | draw_x_off = drawable->x; |
461 | draw_y_off = drawable->y; |
462 | |
463 | tile_x_off = pWin->drawable.x - draw_x_off; |
464 | tile_y_off = pWin->drawable.y - draw_y_off; |
465 | fill = pWin->background; |
466 | #ifdef COMPOSITE |
467 | if (pWin->inhibitBGPaint) |
468 | return; |
469 | #endif |
470 | switch (pWin->backgroundState) { |
| 8 | | 'Default' branch taken. Execution continues on line 507 | |
|
471 | case None0L: |
472 | return; |
473 | case BackgroundPixmap3L: |
474 | solid = FALSE0; |
475 | break; |
476 | } |
477 | } |
478 | else { |
479 | PixmapPtr pixmap; |
480 | |
481 | fill = pWin->border; |
482 | solid = pWin->borderIsPixel; |
483 | |
484 | |
485 | if (!pScreen->GetWindowPixmap) |
486 | return; |
487 | pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); |
488 | drawable = &pixmap->drawable; |
489 | |
490 | while (pWin->backgroundState == ParentRelative1L) |
491 | pWin = pWin->parent; |
492 | |
493 | tile_x_off = pWin->drawable.x; |
494 | tile_y_off = pWin->drawable.y; |
495 | |
496 | #ifdef COMPOSITE |
497 | draw_x_off = pixmap->screen_x; |
498 | draw_y_off = pixmap->screen_y; |
499 | tile_x_off -= draw_x_off; |
500 | tile_y_off -= draw_y_off; |
501 | #else |
502 | draw_x_off = 0; |
503 | draw_y_off = 0; |
504 | #endif |
505 | } |
506 | |
507 | gcval[0].val = GXcopy0x3; |
508 | gcmask = GCFunction(1L<<0); |
509 | |
510 | #ifdef ROOTLESS_SAFEALPHA1 |
511 | |
512 | |
513 | |
514 | |
515 | #define RootlessAlphaMask(bpp)((bpp) == 32 ? 0xFF000000 : 0) ((bpp) == 32 ? 0xFF000000 : 0) |
516 | #endif |
517 | |
518 | if (solid) { |
| |
519 | #ifdef ROOTLESS_SAFEALPHA1 |
520 | gcval[1].val = |
521 | fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel)((pWin->drawable.bitsPerPixel) == 32 ? 0xFF000000 : 0); |
522 | #else |
523 | gcval[1].val = fill.pixel; |
524 | #endif |
525 | gcval[2].val = FillSolid0; |
526 | gcmask |= GCForeground(1L<<2) | GCFillStyle(1L<<8); |
527 | } |
528 | else { |
529 | int c = 1; |
530 | |
531 | #ifdef ROOTLESS_SAFEALPHA1 |
532 | gcval[c++].val = |
533 | ((CARD32) -1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel)((pWin->drawable.bitsPerPixel) == 32 ? 0xFF000000 : 0); |
534 | gcmask |= GCPlaneMask(1L<<1); |
535 | #endif |
536 | gcval[c++].val = FillTiled1; |
537 | gcval[c++].ptr = (void *) fill.pixmap; |
538 | gcval[c++].val = tile_x_off; |
539 | gcval[c++].val = tile_y_off; |
540 | gcmask |= GCFillStyle(1L<<8) | GCTile(1L<<10) | GCTileStipXOrigin(1L<<12) | GCTileStipYOrigin(1L<<13); |
541 | } |
542 | |
543 | prect = malloc(RegionNumRects(prgn) * sizeof(xRectangle)); |
| |
544 | if (!prect) |
| 11 | | Assuming 'prect' is non-null | |
|
| |
545 | return; |
546 | |
547 | pGC = GetScratchGC(drawable->depth, drawable->pScreen); |
548 | if (!pGC) { |
| 13 | | Assuming 'pGC' is non-null | |
|
| |
549 | free(prect); |
550 | return; |
551 | } |
552 | |
553 | ChangeGC(NullClient((ClientPtr) 0), pGC, gcmask, gcval); |
554 | ValidateGC(drawable, pGC); |
555 | |
556 | numRects = RegionNumRects(prgn); |
557 | pbox = RegionRects(prgn); |
558 | for (i = numRects; --i >= 0; pbox++, prect++) { |
| 15 | | Loop condition is false. Execution continues on line 564 | |
|
559 | prect->x = pbox->x1 - draw_x_off; |
560 | prect->y = pbox->y1 - draw_y_off; |
561 | prect->width = pbox->x2 - pbox->x1; |
562 | prect->height = pbox->y2 - pbox->y1; |
563 | } |
564 | prect -= numRects; |
565 | (*pGC->ops->PolyFillRect) (drawable, pGC, numRects, prect); |
| 16 | | Potential leak of memory pointed to by 'prect' |
|
566 | free(prect); |
567 | |
568 | FreeScratchGC(pGC); |
569 | } |
570 | |
571 | |
572 | |
573 | |
574 | void |
575 | miClearDrawable(DrawablePtr pDraw, GCPtr pGC) |
576 | { |
577 | ChangeGCVal fg, bg; |
578 | xRectangle rect; |
579 | |
580 | fg.val = pGC->fgPixel; |
581 | bg.val = pGC->bgPixel; |
582 | rect.x = 0; |
583 | rect.y = 0; |
584 | rect.width = pDraw->width; |
585 | rect.height = pDraw->height; |
586 | ChangeGC(NullClient((ClientPtr) 0), pGC, GCForeground(1L<<2), &bg); |
587 | ValidateGC(pDraw, pGC); |
588 | (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect); |
589 | ChangeGC(NullClient((ClientPtr) 0), pGC, GCForeground(1L<<2), &fg); |
590 | ValidateGC(pDraw, pGC); |
591 | } |