Imported Upstream version 1.15.1
[deb_xorg-server.git] / miext / rootless / rootlessScreen.c
1 /*
2 * Screen routines for generic rootless X server
3 */
4 /*
5 * Copyright (c) 2001 Greg Parker. All Rights Reserved.
6 * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
7 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 * Except as contained in this notice, the name(s) of the above copyright
28 * holders shall not be used in advertising or otherwise to promote the sale,
29 * use or other dealings in this Software without prior written authorization.
30 */
31
32 #ifdef HAVE_DIX_CONFIG_H
33 #include <dix-config.h>
34 #endif
35
36 #include "mi.h"
37 #include "scrnintstr.h"
38 #include "gcstruct.h"
39 #include "pixmapstr.h"
40 #include "windowstr.h"
41 #include "propertyst.h"
42 #include "mivalidate.h"
43 #include "picturestr.h"
44 #include "colormapst.h"
45
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <fcntl.h>
49 #include <string.h>
50
51 #include "rootlessCommon.h"
52 #include "rootlessWindow.h"
53
54 /* In milliseconds */
55 #ifndef ROOTLESS_REDISPLAY_DELAY
56 #define ROOTLESS_REDISPLAY_DELAY 10
57 #endif
58
59 extern int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild,
60 VTKind kind);
61 extern Bool RootlessCreateGC(GCPtr pGC);
62
63 // Initialize globals
64 DevPrivateKeyRec rootlessGCPrivateKeyRec;
65 DevPrivateKeyRec rootlessScreenPrivateKeyRec;
66 DevPrivateKeyRec rootlessWindowPrivateKeyRec;
67 DevPrivateKeyRec rootlessWindowOldPixmapPrivateKeyRec;
68
69 /*
70 * RootlessUpdateScreenPixmap
71 * miCreateScreenResources does not like a null framebuffer pointer,
72 * it leaves the screen pixmap with an uninitialized data pointer.
73 * Thus, rootless implementations typically set the framebuffer width
74 * to zero so that miCreateScreenResources does not allocate a screen
75 * pixmap for us. We allocate our own screen pixmap here since we need
76 * the screen pixmap to be valid (e.g. CopyArea from the root window).
77 */
78 void
79 RootlessUpdateScreenPixmap(ScreenPtr pScreen)
80 {
81 RootlessScreenRec *s = SCREENREC(pScreen);
82 PixmapPtr pPix;
83 unsigned int rowbytes;
84
85 pPix = (*pScreen->GetScreenPixmap) (pScreen);
86 if (pPix == NULL) {
87 pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0);
88 (*pScreen->SetScreenPixmap) (pPix);
89 }
90
91 rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth);
92
93 if (s->pixmap_data_size < rowbytes) {
94 free(s->pixmap_data);
95
96 s->pixmap_data_size = rowbytes;
97 s->pixmap_data = malloc(s->pixmap_data_size);
98 if (s->pixmap_data == NULL)
99 return;
100
101 memset(s->pixmap_data, 0xFF, s->pixmap_data_size);
102
103 pScreen->ModifyPixmapHeader(pPix, pScreen->width, pScreen->height,
104 pScreen->rootDepth,
105 BitsPerPixel(pScreen->rootDepth),
106 0, s->pixmap_data);
107 /* ModifyPixmapHeader ignores zero arguments, so install rowbytes
108 by hand. */
109 pPix->devKind = 0;
110 }
111 }
112
113 /*
114 * RootlessCreateScreenResources
115 * Rootless implementations typically set a null framebuffer pointer, which
116 * causes problems with miCreateScreenResources. We fix things up here.
117 */
118 static Bool
119 RootlessCreateScreenResources(ScreenPtr pScreen)
120 {
121 Bool ret = TRUE;
122
123 SCREEN_UNWRAP(pScreen, CreateScreenResources);
124
125 if (pScreen->CreateScreenResources != NULL)
126 ret = (*pScreen->CreateScreenResources) (pScreen);
127
128 SCREEN_WRAP(pScreen, CreateScreenResources);
129
130 if (!ret)
131 return ret;
132
133 /* Make sure we have a valid screen pixmap. */
134
135 RootlessUpdateScreenPixmap(pScreen);
136
137 return ret;
138 }
139
140 static Bool
141 RootlessCloseScreen(ScreenPtr pScreen)
142 {
143 RootlessScreenRec *s;
144
145 s = SCREENREC(pScreen);
146
147 // fixme unwrap everything that was wrapped?
148 pScreen->CloseScreen = s->CloseScreen;
149
150 if (s->pixmap_data != NULL) {
151 free(s->pixmap_data);
152 s->pixmap_data = NULL;
153 s->pixmap_data_size = 0;
154 }
155
156 free(s);
157 return pScreen->CloseScreen(pScreen);
158 }
159
160 static void
161 RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
162 unsigned int format, unsigned long planeMask, char *pdstLine)
163 {
164 ScreenPtr pScreen = pDrawable->pScreen;
165
166 SCREEN_UNWRAP(pScreen, GetImage);
167
168 if (pDrawable->type == DRAWABLE_WINDOW) {
169 int x0, y0, x1, y1;
170 RootlessWindowRec *winRec;
171
172 // Many apps use GetImage to sync with the visible frame buffer
173 // FIXME: entire screen or just window or all screens?
174 RootlessRedisplayScreen(pScreen);
175
176 // RedisplayScreen stops drawing, so we need to start it again
177 RootlessStartDrawing((WindowPtr) pDrawable);
178
179 /* Check that we have some place to read from. */
180 winRec = WINREC(TopLevelParent((WindowPtr) pDrawable));
181 if (winRec == NULL)
182 goto out;
183
184 /* Clip to top-level window bounds. */
185 /* FIXME: fbGetImage uses the width parameter to calculate the
186 stride of the destination pixmap. If w is clipped, the data
187 returned will be garbage, although we will not crash. */
188
189 x0 = pDrawable->x + sx;
190 y0 = pDrawable->y + sy;
191 x1 = x0 + w;
192 y1 = y0 + h;
193
194 x0 = max(x0, winRec->x);
195 y0 = max(y0, winRec->y);
196 x1 = min(x1, winRec->x + winRec->width);
197 y1 = min(y1, winRec->y + winRec->height);
198
199 sx = x0 - pDrawable->x;
200 sy = y0 - pDrawable->y;
201 w = x1 - x0;
202 h = y1 - y0;
203
204 if (w <= 0 || h <= 0)
205 goto out;
206 }
207
208 pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
209
210 out:
211 SCREEN_WRAP(pScreen, GetImage);
212 }
213
214 /*
215 * RootlessSourceValidate
216 * CopyArea and CopyPlane use a GC tied to the destination drawable.
217 * StartDrawing/StopDrawing wrappers won't be called if source is
218 * a visible window but the destination isn't. So, we call StartDrawing
219 * here and leave StopDrawing for the block handler.
220 */
221 static void
222 RootlessSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h,
223 unsigned int subWindowMode)
224 {
225 SCREEN_UNWRAP(pDrawable->pScreen, SourceValidate);
226 if (pDrawable->type == DRAWABLE_WINDOW) {
227 WindowPtr pWin = (WindowPtr) pDrawable;
228
229 RootlessStartDrawing(pWin);
230 }
231 if (pDrawable->pScreen->SourceValidate) {
232 pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h,
233 subWindowMode);
234 }
235 SCREEN_WRAP(pDrawable->pScreen, SourceValidate);
236 }
237
238 static void
239 RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
240 INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
241 INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
242 {
243 ScreenPtr pScreen = pDst->pDrawable->pScreen;
244 PictureScreenPtr ps = GetPictureScreen(pScreen);
245 WindowPtr srcWin, dstWin, maskWin = NULL;
246
247 if (pMask) { // pMask can be NULL
248 maskWin = (pMask->pDrawable &&
249 pMask->pDrawable->type ==
250 DRAWABLE_WINDOW) ? (WindowPtr) pMask->pDrawable : NULL;
251 }
252 srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
253 (WindowPtr) pSrc->pDrawable : NULL;
254 dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
255 (WindowPtr) pDst->pDrawable : NULL;
256
257 // SCREEN_UNWRAP(ps, Composite);
258 ps->Composite = SCREENREC(pScreen)->Composite;
259
260 if (srcWin && IsFramedWindow(srcWin))
261 RootlessStartDrawing(srcWin);
262 if (maskWin && IsFramedWindow(maskWin))
263 RootlessStartDrawing(maskWin);
264 if (dstWin && IsFramedWindow(dstWin))
265 RootlessStartDrawing(dstWin);
266
267 ps->Composite(op, pSrc, pMask, pDst,
268 xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
269
270 if (dstWin && IsFramedWindow(dstWin)) {
271 RootlessDamageRect(dstWin, xDst, yDst, width, height);
272 }
273
274 ps->Composite = RootlessComposite;
275 // SCREEN_WRAP(ps, Composite);
276 }
277
278 static void
279 RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
280 PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
281 int nlist, GlyphListPtr list, GlyphPtr * glyphs)
282 {
283 ScreenPtr pScreen = pDst->pDrawable->pScreen;
284 PictureScreenPtr ps = GetPictureScreen(pScreen);
285 int x, y;
286 int n;
287 GlyphPtr glyph;
288 WindowPtr srcWin, dstWin;
289
290 srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
291 (WindowPtr) pSrc->pDrawable : NULL;
292 dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
293 (WindowPtr) pDst->pDrawable : NULL;
294
295 if (srcWin && IsFramedWindow(srcWin))
296 RootlessStartDrawing(srcWin);
297 if (dstWin && IsFramedWindow(dstWin))
298 RootlessStartDrawing(dstWin);
299
300 //SCREEN_UNWRAP(ps, Glyphs);
301 ps->Glyphs = SCREENREC(pScreen)->Glyphs;
302 ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
303 ps->Glyphs = RootlessGlyphs;
304 //SCREEN_WRAP(ps, Glyphs);
305
306 if (dstWin && IsFramedWindow(dstWin)) {
307 x = xSrc;
308 y = ySrc;
309
310 while (nlist--) {
311 x += list->xOff;
312 y += list->yOff;
313 n = list->len;
314
315 /* Calling DamageRect for the bounding box of each glyph is
316 inefficient. So compute the union of all glyphs in a list
317 and damage that. */
318
319 if (n > 0) {
320 BoxRec box;
321
322 glyph = *glyphs++;
323
324 box.x1 = x - glyph->info.x;
325 box.y1 = y - glyph->info.y;
326 box.x2 = box.x1 + glyph->info.width;
327 box.y2 = box.y1 + glyph->info.height;
328
329 x += glyph->info.xOff;
330 y += glyph->info.yOff;
331
332 while (--n > 0) {
333 short x1, y1, x2, y2;
334
335 glyph = *glyphs++;
336
337 x1 = x - glyph->info.x;
338 y1 = y - glyph->info.y;
339 x2 = x1 + glyph->info.width;
340 y2 = y1 + glyph->info.height;
341
342 box.x1 = max(box.x1, x1);
343 box.y1 = max(box.y1, y1);
344 box.x2 = max(box.x2, x2);
345 box.y2 = max(box.y2, y2);
346
347 x += glyph->info.xOff;
348 y += glyph->info.yOff;
349 }
350
351 RootlessDamageBox(dstWin, &box);
352 }
353 list++;
354 }
355 }
356 }
357
358 /*
359 * RootlessValidateTree
360 * ValidateTree is modified in two ways:
361 * - top-level windows don't clip each other
362 * - windows aren't clipped against root.
363 * These only matter when validating from the root.
364 */
365 static int
366 RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
367 {
368 int result;
369 RegionRec saveRoot;
370 ScreenPtr pScreen = pParent->drawable.pScreen;
371
372 SCREEN_UNWRAP(pScreen, ValidateTree);
373 RL_DEBUG_MSG("VALIDATETREE start ");
374
375 // Use our custom version to validate from root
376 if (IsRoot(pParent)) {
377 RL_DEBUG_MSG("custom ");
378 result = RootlessMiValidateTree(pParent, pChild, kind);
379 }
380 else {
381 HUGE_ROOT(pParent);
382 result = pScreen->ValidateTree(pParent, pChild, kind);
383 NORMAL_ROOT(pParent);
384 }
385
386 SCREEN_WRAP(pScreen, ValidateTree);
387 RL_DEBUG_MSG("VALIDATETREE end\n");
388
389 return result;
390 }
391
392 /*
393 * RootlessMarkOverlappedWindows
394 * MarkOverlappedWindows is modified to ignore overlapping
395 * top-level windows.
396 */
397 static Bool
398 RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
399 WindowPtr *ppLayerWin)
400 {
401 RegionRec saveRoot;
402 Bool result;
403 ScreenPtr pScreen = pWin->drawable.pScreen;
404
405 SCREEN_UNWRAP(pScreen, MarkOverlappedWindows);
406 RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start ");
407
408 HUGE_ROOT(pWin);
409 if (IsRoot(pWin)) {
410 // root - mark nothing
411 RL_DEBUG_MSG("is root not marking ");
412 result = FALSE;
413 }
414 else if (!IsTopLevel(pWin)) {
415 // not top-level window - mark normally
416 result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin);
417 }
418 else {
419 //top-level window - mark children ONLY - NO overlaps with sibs (?)
420 // This code copied from miMarkOverlappedWindows()
421
422 register WindowPtr pChild;
423 Bool anyMarked = FALSE;
424 MarkWindowProcPtr MarkWindow = pScreen->MarkWindow;
425
426 RL_DEBUG_MSG("is top level! ");
427 /* single layered systems are easy */
428 if (ppLayerWin)
429 *ppLayerWin = pWin;
430
431 if (pWin == pFirst) {
432 /* Blindly mark pWin and all of its inferiors. This is a slight
433 * overkill if there are mapped windows that outside pWin's border,
434 * but it's better than wasting time on RectIn checks.
435 */
436 pChild = pWin;
437 while (1) {
438 if (pChild->viewable) {
439 if (RegionBroken(&pChild->winSize))
440 SetWinSize(pChild);
441 if (RegionBroken(&pChild->borderSize))
442 SetBorderSize(pChild);
443 (*MarkWindow) (pChild);
444 if (pChild->firstChild) {
445 pChild = pChild->firstChild;
446 continue;
447 }
448 }
449 while (!pChild->nextSib && (pChild != pWin))
450 pChild = pChild->parent;
451 if (pChild == pWin)
452 break;
453 pChild = pChild->nextSib;
454 }
455 anyMarked = TRUE;
456 }
457 if (anyMarked)
458 (*MarkWindow) (pWin->parent);
459 result = anyMarked;
460 }
461 NORMAL_ROOT(pWin);
462 SCREEN_WRAP(pScreen, MarkOverlappedWindows);
463 RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n");
464
465 return result;
466 }
467
468 static void
469 expose_1(WindowPtr pWin)
470 {
471 WindowPtr pChild;
472
473 if (!pWin->realized)
474 return;
475
476 miPaintWindow(pWin, &pWin->borderClip, PW_BACKGROUND);
477
478 /* FIXME: comments in windowstr.h indicate that borderClip doesn't
479 include subwindow visibility. But I'm not so sure.. so we may
480 be exposing too much.. */
481
482 miSendExposures(pWin, &pWin->borderClip,
483 pWin->drawable.x, pWin->drawable.y);
484
485 for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib)
486 expose_1(pChild);
487 }
488
489 void
490 RootlessScreenExpose(ScreenPtr pScreen)
491 {
492 expose_1(pScreen->root);
493 }
494
495 ColormapPtr
496 RootlessGetColormap(ScreenPtr pScreen)
497 {
498 RootlessScreenRec *s = SCREENREC(pScreen);
499
500 return s->colormap;
501 }
502
503 static void
504 RootlessInstallColormap(ColormapPtr pMap)
505 {
506 ScreenPtr pScreen = pMap->pScreen;
507 RootlessScreenRec *s = SCREENREC(pScreen);
508
509 SCREEN_UNWRAP(pScreen, InstallColormap);
510
511 if (s->colormap != pMap) {
512 s->colormap = pMap;
513 s->colormap_changed = TRUE;
514 RootlessQueueRedisplay(pScreen);
515 }
516
517 pScreen->InstallColormap(pMap);
518
519 SCREEN_WRAP(pScreen, InstallColormap);
520 }
521
522 static void
523 RootlessUninstallColormap(ColormapPtr pMap)
524 {
525 ScreenPtr pScreen = pMap->pScreen;
526 RootlessScreenRec *s = SCREENREC(pScreen);
527
528 SCREEN_UNWRAP(pScreen, UninstallColormap);
529
530 if (s->colormap == pMap)
531 s->colormap = NULL;
532
533 pScreen->UninstallColormap(pMap);
534
535 SCREEN_WRAP(pScreen, UninstallColormap);
536 }
537
538 static void
539 RootlessStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef)
540 {
541 ScreenPtr pScreen = pMap->pScreen;
542 RootlessScreenRec *s = SCREENREC(pScreen);
543
544 SCREEN_UNWRAP(pScreen, StoreColors);
545
546 if (s->colormap == pMap && ndef > 0) {
547 s->colormap_changed = TRUE;
548 RootlessQueueRedisplay(pScreen);
549 }
550
551 pScreen->StoreColors(pMap, ndef, pdef);
552
553 SCREEN_WRAP(pScreen, StoreColors);
554 }
555
556 static CARD32
557 RootlessRedisplayCallback(OsTimerPtr timer, CARD32 time, void *arg)
558 {
559 RootlessScreenRec *screenRec = arg;
560
561 if (!screenRec->redisplay_queued) {
562 /* No update needed. Stop the timer. */
563
564 screenRec->redisplay_timer_set = FALSE;
565 return 0;
566 }
567
568 screenRec->redisplay_queued = FALSE;
569
570 /* Mark that we should redisplay before waiting for I/O next time */
571 screenRec->redisplay_expired = TRUE;
572
573 /* Reinstall the timer immediately, so we get as close to our
574 redisplay interval as possible. */
575
576 return ROOTLESS_REDISPLAY_DELAY;
577 }
578
579 /*
580 * RootlessQueueRedisplay
581 * Queue a redisplay after a timer delay to ensure we do not redisplay
582 * too frequently.
583 */
584 void
585 RootlessQueueRedisplay(ScreenPtr pScreen)
586 {
587 RootlessScreenRec *screenRec = SCREENREC(pScreen);
588
589 screenRec->redisplay_queued = TRUE;
590
591 if (screenRec->redisplay_timer_set)
592 return;
593
594 screenRec->redisplay_timer = TimerSet(screenRec->redisplay_timer,
595 0, ROOTLESS_REDISPLAY_DELAY,
596 RootlessRedisplayCallback, screenRec);
597 screenRec->redisplay_timer_set = TRUE;
598 }
599
600 /*
601 * RootlessBlockHandler
602 * If the redisplay timer has expired, flush drawing before blocking
603 * on select().
604 */
605 static void
606 RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask)
607 {
608 ScreenPtr pScreen = pbdata;
609 RootlessScreenRec *screenRec = SCREENREC(pScreen);
610
611 if (screenRec->redisplay_expired) {
612 screenRec->redisplay_expired = FALSE;
613
614 RootlessRedisplayScreen(pScreen);
615 }
616 }
617
618 static void
619 RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask)
620 {
621 // nothing here
622 }
623
624 static Bool
625 RootlessAllocatePrivates(ScreenPtr pScreen)
626 {
627 RootlessScreenRec *s;
628
629 if (!dixRegisterPrivateKey
630 (&rootlessGCPrivateKeyRec, PRIVATE_GC, sizeof(RootlessGCRec)))
631 return FALSE;
632 if (!dixRegisterPrivateKey(&rootlessScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
633 return FALSE;
634 if (!dixRegisterPrivateKey(&rootlessWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
635 return FALSE;
636 if (!dixRegisterPrivateKey
637 (&rootlessWindowOldPixmapPrivateKeyRec, PRIVATE_WINDOW, 0))
638 return FALSE;
639
640 s = malloc(sizeof(RootlessScreenRec));
641 if (!s)
642 return FALSE;
643 SETSCREENREC(pScreen, s);
644
645 s->pixmap_data = NULL;
646 s->pixmap_data_size = 0;
647
648 s->redisplay_timer = NULL;
649 s->redisplay_timer_set = FALSE;
650
651 return TRUE;
652 }
653
654 static void
655 RootlessWrap(ScreenPtr pScreen)
656 {
657 RootlessScreenRec *s = SCREENREC(pScreen);
658
659 #define WRAP(a) \
660 if (pScreen->a) { \
661 s->a = pScreen->a; \
662 } else { \
663 RL_DEBUG_MSG("null screen fn " #a "\n"); \
664 s->a = NULL; \
665 } \
666 pScreen->a = Rootless##a
667
668 WRAP(CreateScreenResources);
669 WRAP(CloseScreen);
670 WRAP(CreateGC);
671 WRAP(CopyWindow);
672 WRAP(GetImage);
673 WRAP(SourceValidate);
674 WRAP(CreateWindow);
675 WRAP(DestroyWindow);
676 WRAP(RealizeWindow);
677 WRAP(UnrealizeWindow);
678 WRAP(MoveWindow);
679 WRAP(PositionWindow);
680 WRAP(ResizeWindow);
681 WRAP(RestackWindow);
682 WRAP(ReparentWindow);
683 WRAP(ChangeBorderWidth);
684 WRAP(MarkOverlappedWindows);
685 WRAP(ValidateTree);
686 WRAP(ChangeWindowAttributes);
687 WRAP(InstallColormap);
688 WRAP(UninstallColormap);
689 WRAP(StoreColors);
690
691 WRAP(SetShape);
692
693 {
694 // Composite and Glyphs don't use normal screen wrapping
695 PictureScreenPtr ps = GetPictureScreen(pScreen);
696
697 s->Composite = ps->Composite;
698 ps->Composite = RootlessComposite;
699 s->Glyphs = ps->Glyphs;
700 ps->Glyphs = RootlessGlyphs;
701 }
702
703 // WRAP(ClearToBackground); fixme put this back? useful for shaped wins?
704
705 #undef WRAP
706 }
707
708 /*
709 * RootlessInit
710 * Called by the rootless implementation to initialize the rootless layer.
711 * Rootless wraps lots of stuff and needs a bunch of devPrivates.
712 */
713 Bool
714 RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs)
715 {
716 RootlessScreenRec *s;
717
718 if (!RootlessAllocatePrivates(pScreen))
719 return FALSE;
720
721 s = SCREENREC(pScreen);
722
723 s->imp = procs;
724 s->colormap = NULL;
725 s->redisplay_expired = FALSE;
726
727 RootlessWrap(pScreen);
728
729 if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler,
730 RootlessWakeupHandler,
731 (pointer) pScreen)) {
732 return FALSE;
733 }
734
735 return TRUE;
736 }
737
738 void
739 RootlessUpdateRooted(Bool state)
740 {
741 int i;
742
743 if (!state) {
744 for (i = 0; i < screenInfo.numScreens; i++)
745 RootlessDisableRoot(screenInfo.screens[i]);
746 }
747 else {
748 for (i = 0; i < screenInfo.numScreens; i++)
749 RootlessEnableRoot(screenInfo.screens[i]);
750 }
751 }