rootlessScreen.c revision ed6184df
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 pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h, 232 subWindowMode); 233 SCREEN_WRAP(pDrawable->pScreen, SourceValidate); 234} 235 236static void 237RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, 238 INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, 239 INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) 240{ 241 ScreenPtr pScreen = pDst->pDrawable->pScreen; 242 PictureScreenPtr ps = GetPictureScreen(pScreen); 243 WindowPtr srcWin, dstWin, maskWin = NULL; 244 245 if (pMask) { // pMask can be NULL 246 maskWin = (pMask->pDrawable && 247 pMask->pDrawable->type == 248 DRAWABLE_WINDOW) ? (WindowPtr) pMask->pDrawable : NULL; 249 } 250 srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ? 251 (WindowPtr) pSrc->pDrawable : NULL; 252 dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ? 253 (WindowPtr) pDst->pDrawable : NULL; 254 255 // SCREEN_UNWRAP(ps, Composite); 256 ps->Composite = SCREENREC(pScreen)->Composite; 257 258 if (srcWin && IsFramedWindow(srcWin)) 259 RootlessStartDrawing(srcWin); 260 if (maskWin && IsFramedWindow(maskWin)) 261 RootlessStartDrawing(maskWin); 262 if (dstWin && IsFramedWindow(dstWin)) 263 RootlessStartDrawing(dstWin); 264 265 ps->Composite(op, pSrc, pMask, pDst, 266 xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); 267 268 if (dstWin && IsFramedWindow(dstWin)) { 269 RootlessDamageRect(dstWin, xDst, yDst, width, height); 270 } 271 272 ps->Composite = RootlessComposite; 273 // SCREEN_WRAP(ps, Composite); 274} 275 276static void 277RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, 278 PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, 279 int nlist, GlyphListPtr list, GlyphPtr * glyphs) 280{ 281 ScreenPtr pScreen = pDst->pDrawable->pScreen; 282 PictureScreenPtr ps = GetPictureScreen(pScreen); 283 int x, y; 284 int n; 285 GlyphPtr glyph; 286 WindowPtr srcWin, dstWin; 287 288 srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ? 289 (WindowPtr) pSrc->pDrawable : NULL; 290 dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ? 291 (WindowPtr) pDst->pDrawable : NULL; 292 293 if (srcWin && IsFramedWindow(srcWin)) 294 RootlessStartDrawing(srcWin); 295 if (dstWin && IsFramedWindow(dstWin)) 296 RootlessStartDrawing(dstWin); 297 298 //SCREEN_UNWRAP(ps, Glyphs); 299 ps->Glyphs = SCREENREC(pScreen)->Glyphs; 300 ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); 301 ps->Glyphs = RootlessGlyphs; 302 //SCREEN_WRAP(ps, Glyphs); 303 304 if (dstWin && IsFramedWindow(dstWin)) { 305 x = xSrc; 306 y = ySrc; 307 308 while (nlist--) { 309 x += list->xOff; 310 y += list->yOff; 311 n = list->len; 312 313 /* Calling DamageRect for the bounding box of each glyph is 314 inefficient. So compute the union of all glyphs in a list 315 and damage that. */ 316 317 if (n > 0) { 318 BoxRec box; 319 320 glyph = *glyphs++; 321 322 box.x1 = x - glyph->info.x; 323 box.y1 = y - glyph->info.y; 324 box.x2 = box.x1 + glyph->info.width; 325 box.y2 = box.y1 + glyph->info.height; 326 327 x += glyph->info.xOff; 328 y += glyph->info.yOff; 329 330 while (--n > 0) { 331 short x1, y1, x2, y2; 332 333 glyph = *glyphs++; 334 335 x1 = x - glyph->info.x; 336 y1 = y - glyph->info.y; 337 x2 = x1 + glyph->info.width; 338 y2 = y1 + glyph->info.height; 339 340 box.x1 = max(box.x1, x1); 341 box.y1 = max(box.y1, y1); 342 box.x2 = max(box.x2, x2); 343 box.y2 = max(box.y2, y2); 344 345 x += glyph->info.xOff; 346 y += glyph->info.yOff; 347 } 348 349 RootlessDamageBox(dstWin, &box); 350 } 351 list++; 352 } 353 } 354} 355 356/* 357 * RootlessValidateTree 358 * ValidateTree is modified in two ways: 359 * - top-level windows don't clip each other 360 * - windows aren't clipped against root. 361 * These only matter when validating from the root. 362 */ 363static int 364RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) 365{ 366 int result; 367 RegionRec saveRoot; 368 ScreenPtr pScreen = pParent->drawable.pScreen; 369 370 SCREEN_UNWRAP(pScreen, ValidateTree); 371 RL_DEBUG_MSG("VALIDATETREE start "); 372 373 // Use our custom version to validate from root 374 if (IsRoot(pParent)) { 375 RL_DEBUG_MSG("custom "); 376 result = RootlessMiValidateTree(pParent, pChild, kind); 377 } 378 else { 379 HUGE_ROOT(pParent); 380 result = pScreen->ValidateTree(pParent, pChild, kind); 381 NORMAL_ROOT(pParent); 382 } 383 384 SCREEN_WRAP(pScreen, ValidateTree); 385 RL_DEBUG_MSG("VALIDATETREE end\n"); 386 387 return result; 388} 389 390/* 391 * RootlessMarkOverlappedWindows 392 * MarkOverlappedWindows is modified to ignore overlapping 393 * top-level windows. 394 */ 395static Bool 396RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, 397 WindowPtr *ppLayerWin) 398{ 399 RegionRec saveRoot; 400 Bool result; 401 ScreenPtr pScreen = pWin->drawable.pScreen; 402 403 SCREEN_UNWRAP(pScreen, MarkOverlappedWindows); 404 RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start "); 405 406 HUGE_ROOT(pWin); 407 if (IsRoot(pWin)) { 408 // root - mark nothing 409 RL_DEBUG_MSG("is root not marking "); 410 result = FALSE; 411 } 412 else if (!IsTopLevel(pWin)) { 413 // not top-level window - mark normally 414 result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin); 415 } 416 else { 417 //top-level window - mark children ONLY - NO overlaps with sibs (?) 418 // This code copied from miMarkOverlappedWindows() 419 420 register WindowPtr pChild; 421 Bool anyMarked = FALSE; 422 MarkWindowProcPtr MarkWindow = pScreen->MarkWindow; 423 424 RL_DEBUG_MSG("is top level! "); 425 /* single layered systems are easy */ 426 if (ppLayerWin) 427 *ppLayerWin = pWin; 428 429 if (pWin == pFirst) { 430 /* Blindly mark pWin and all of its inferiors. This is a slight 431 * overkill if there are mapped windows that outside pWin's border, 432 * but it's better than wasting time on RectIn checks. 433 */ 434 pChild = pWin; 435 while (1) { 436 if (pChild->viewable) { 437 if (RegionBroken(&pChild->winSize)) 438 SetWinSize(pChild); 439 if (RegionBroken(&pChild->borderSize)) 440 SetBorderSize(pChild); 441 (*MarkWindow) (pChild); 442 if (pChild->firstChild) { 443 pChild = pChild->firstChild; 444 continue; 445 } 446 } 447 while (!pChild->nextSib && (pChild != pWin)) 448 pChild = pChild->parent; 449 if (pChild == pWin) 450 break; 451 pChild = pChild->nextSib; 452 } 453 anyMarked = TRUE; 454 } 455 if (anyMarked) 456 (*MarkWindow) (pWin->parent); 457 result = anyMarked; 458 } 459 NORMAL_ROOT(pWin); 460 SCREEN_WRAP(pScreen, MarkOverlappedWindows); 461 RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n"); 462 463 return result; 464} 465 466static void 467expose_1(WindowPtr pWin) 468{ 469 WindowPtr pChild; 470 471 if (!pWin->realized) 472 return; 473 474 pWin->drawable.pScreen->PaintWindow(pWin, &pWin->borderClip, PW_BACKGROUND); 475 476 /* FIXME: comments in windowstr.h indicate that borderClip doesn't 477 include subwindow visibility. But I'm not so sure.. so we may 478 be exposing too much.. */ 479 480 miSendExposures(pWin, &pWin->borderClip, 481 pWin->drawable.x, pWin->drawable.y); 482 483 for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib) 484 expose_1(pChild); 485} 486 487void 488RootlessScreenExpose(ScreenPtr pScreen) 489{ 490 expose_1(pScreen->root); 491} 492 493ColormapPtr 494RootlessGetColormap(ScreenPtr pScreen) 495{ 496 RootlessScreenRec *s = SCREENREC(pScreen); 497 498 return s->colormap; 499} 500 501static void 502RootlessInstallColormap(ColormapPtr pMap) 503{ 504 ScreenPtr pScreen = pMap->pScreen; 505 RootlessScreenRec *s = SCREENREC(pScreen); 506 507 SCREEN_UNWRAP(pScreen, InstallColormap); 508 509 if (s->colormap != pMap) { 510 s->colormap = pMap; 511 s->colormap_changed = TRUE; 512 RootlessQueueRedisplay(pScreen); 513 } 514 515 pScreen->InstallColormap(pMap); 516 517 SCREEN_WRAP(pScreen, InstallColormap); 518} 519 520static void 521RootlessUninstallColormap(ColormapPtr pMap) 522{ 523 ScreenPtr pScreen = pMap->pScreen; 524 RootlessScreenRec *s = SCREENREC(pScreen); 525 526 SCREEN_UNWRAP(pScreen, UninstallColormap); 527 528 if (s->colormap == pMap) 529 s->colormap = NULL; 530 531 pScreen->UninstallColormap(pMap); 532 533 SCREEN_WRAP(pScreen, UninstallColormap); 534} 535 536static void 537RootlessStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef) 538{ 539 ScreenPtr pScreen = pMap->pScreen; 540 RootlessScreenRec *s = SCREENREC(pScreen); 541 542 SCREEN_UNWRAP(pScreen, StoreColors); 543 544 if (s->colormap == pMap && ndef > 0) { 545 s->colormap_changed = TRUE; 546 RootlessQueueRedisplay(pScreen); 547 } 548 549 pScreen->StoreColors(pMap, ndef, pdef); 550 551 SCREEN_WRAP(pScreen, StoreColors); 552} 553 554static CARD32 555RootlessRedisplayCallback(OsTimerPtr timer, CARD32 time, void *arg) 556{ 557 RootlessScreenRec *screenRec = arg; 558 559 if (!screenRec->redisplay_queued) { 560 /* No update needed. Stop the timer. */ 561 562 screenRec->redisplay_timer_set = FALSE; 563 return 0; 564 } 565 566 screenRec->redisplay_queued = FALSE; 567 568 /* Mark that we should redisplay before waiting for I/O next time */ 569 screenRec->redisplay_expired = TRUE; 570 571 /* Reinstall the timer immediately, so we get as close to our 572 redisplay interval as possible. */ 573 574 return ROOTLESS_REDISPLAY_DELAY; 575} 576 577/* 578 * RootlessQueueRedisplay 579 * Queue a redisplay after a timer delay to ensure we do not redisplay 580 * too frequently. 581 */ 582void 583RootlessQueueRedisplay(ScreenPtr pScreen) 584{ 585 RootlessScreenRec *screenRec = SCREENREC(pScreen); 586 587 screenRec->redisplay_queued = TRUE; 588 589 if (screenRec->redisplay_timer_set) 590 return; 591 592 screenRec->redisplay_timer = TimerSet(screenRec->redisplay_timer, 593 0, ROOTLESS_REDISPLAY_DELAY, 594 RootlessRedisplayCallback, screenRec); 595 screenRec->redisplay_timer_set = TRUE; 596} 597 598/* 599 * RootlessBlockHandler 600 * If the redisplay timer has expired, flush drawing before blocking 601 * on select(). 602 */ 603static void 604RootlessBlockHandler(void *pbdata, void *ptimeout) 605{ 606 ScreenPtr pScreen = pbdata; 607 RootlessScreenRec *screenRec = SCREENREC(pScreen); 608 609 if (screenRec->redisplay_expired) { 610 screenRec->redisplay_expired = FALSE; 611 612 RootlessRedisplayScreen(pScreen); 613 } 614} 615 616static void 617RootlessWakeupHandler(void *data, int result) 618{ 619 // nothing here 620} 621 622static Bool 623RootlessAllocatePrivates(ScreenPtr pScreen) 624{ 625 RootlessScreenRec *s; 626 627 if (!dixRegisterPrivateKey 628 (&rootlessGCPrivateKeyRec, PRIVATE_GC, sizeof(RootlessGCRec))) 629 return FALSE; 630 if (!dixRegisterPrivateKey(&rootlessScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) 631 return FALSE; 632 if (!dixRegisterPrivateKey(&rootlessWindowPrivateKeyRec, PRIVATE_WINDOW, 0)) 633 return FALSE; 634 if (!dixRegisterPrivateKey 635 (&rootlessWindowOldPixmapPrivateKeyRec, PRIVATE_WINDOW, 0)) 636 return FALSE; 637 638 s = malloc(sizeof(RootlessScreenRec)); 639 if (!s) 640 return FALSE; 641 SETSCREENREC(pScreen, s); 642 643 s->pixmap_data = NULL; 644 s->pixmap_data_size = 0; 645 646 s->redisplay_timer = NULL; 647 s->redisplay_timer_set = FALSE; 648 649 return TRUE; 650} 651 652static void 653RootlessWrap(ScreenPtr pScreen) 654{ 655 RootlessScreenRec *s = SCREENREC(pScreen); 656 657#define WRAP(a) \ 658 if (pScreen->a) { \ 659 s->a = pScreen->a; \ 660 } else { \ 661 RL_DEBUG_MSG("null screen fn " #a "\n"); \ 662 s->a = NULL; \ 663 } \ 664 pScreen->a = Rootless##a 665 666 WRAP(CreateScreenResources); 667 WRAP(CloseScreen); 668 WRAP(CreateGC); 669 WRAP(CopyWindow); 670 WRAP(PaintWindow); 671 WRAP(GetImage); 672 WRAP(SourceValidate); 673 WRAP(CreateWindow); 674 WRAP(DestroyWindow); 675 WRAP(RealizeWindow); 676 WRAP(UnrealizeWindow); 677 WRAP(MoveWindow); 678 WRAP(PositionWindow); 679 WRAP(ResizeWindow); 680 WRAP(RestackWindow); 681 WRAP(ReparentWindow); 682 WRAP(ChangeBorderWidth); 683 WRAP(MarkOverlappedWindows); 684 WRAP(ValidateTree); 685 WRAP(ChangeWindowAttributes); 686 WRAP(InstallColormap); 687 WRAP(UninstallColormap); 688 WRAP(StoreColors); 689 690 WRAP(SetShape); 691 692 { 693 // Composite and Glyphs don't use normal screen wrapping 694 PictureScreenPtr ps = GetPictureScreen(pScreen); 695 696 s->Composite = ps->Composite; 697 ps->Composite = RootlessComposite; 698 s->Glyphs = ps->Glyphs; 699 ps->Glyphs = RootlessGlyphs; 700 } 701 702 // WRAP(ClearToBackground); fixme put this back? useful for shaped wins? 703 704#undef WRAP 705} 706 707/* 708 * RootlessInit 709 * Called by the rootless implementation to initialize the rootless layer. 710 * Rootless wraps lots of stuff and needs a bunch of devPrivates. 711 */ 712Bool 713RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs) 714{ 715 RootlessScreenRec *s; 716 717 if (!RootlessAllocatePrivates(pScreen)) 718 return FALSE; 719 720 s = SCREENREC(pScreen); 721 722 s->imp = procs; 723 s->colormap = NULL; 724 s->redisplay_expired = FALSE; 725 726 RootlessWrap(pScreen); 727 728 if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler, 729 RootlessWakeupHandler, 730 (void *) pScreen)) { 731 return FALSE; 732 } 733 734 return TRUE; 735} 736 737void 738RootlessUpdateRooted(Bool state) 739{ 740 int i; 741 742 if (!state) { 743 for (i = 0; i < screenInfo.numScreens; i++) 744 RootlessDisableRoot(screenInfo.screens[i]); 745 } 746 else { 747 for (i = 0; i < screenInfo.numScreens; i++) 748 RootlessEnableRoot(screenInfo.screens[i]); 749 } 750} 751