Imported Upstream version 1.15.1
[deb_xorg-server.git] / miext / rootless / rootlessScreen.c
CommitLineData
a09e091a
JB
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
59extern int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild,
60 VTKind kind);
61extern Bool RootlessCreateGC(GCPtr pGC);
62
63// Initialize globals
64DevPrivateKeyRec rootlessGCPrivateKeyRec;
65DevPrivateKeyRec rootlessScreenPrivateKeyRec;
66DevPrivateKeyRec rootlessWindowPrivateKeyRec;
67DevPrivateKeyRec 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 */
78void
79RootlessUpdateScreenPixmap(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 */
118static Bool
119RootlessCreateScreenResources(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
140static Bool
141RootlessCloseScreen(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
160static void
161RootlessGetImage(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 */
221static void
222RootlessSourceValidate(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
238static void
239RootlessComposite(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
278static void
279RootlessGlyphs(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 */
365static int
366RootlessValidateTree(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 */
397static Bool
398RootlessMarkOverlappedWindows(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
468static void
469expose_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
489void
490RootlessScreenExpose(ScreenPtr pScreen)
491{
492 expose_1(pScreen->root);
493}
494
495ColormapPtr
496RootlessGetColormap(ScreenPtr pScreen)
497{
498 RootlessScreenRec *s = SCREENREC(pScreen);
499
500 return s->colormap;
501}
502
503static void
504RootlessInstallColormap(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
522static void
523RootlessUninstallColormap(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
538static void
539RootlessStoreColors(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
556static CARD32
557RootlessRedisplayCallback(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 */
584void
585RootlessQueueRedisplay(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 */
605static void
606RootlessBlockHandler(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
618static void
619RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask)
620{
621 // nothing here
622}
623
624static Bool
625RootlessAllocatePrivates(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
654static void
655RootlessWrap(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 */
713Bool
714RootlessInit(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
738void
739RootlessUpdateRooted(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}