rootlessScreen.c revision 9ace9065
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 33#ifdef HAVE_DIX_CONFIG_H 34#include <dix-config.h> 35#endif 36 37#include "mi.h" 38#include "scrnintstr.h" 39#include "gcstruct.h" 40#include "pixmapstr.h" 41#include "windowstr.h" 42#include "propertyst.h" 43#include "mivalidate.h" 44#include "picturestr.h" 45#include "colormapst.h" 46 47#include <sys/types.h> 48#include <sys/stat.h> 49#include <fcntl.h> 50#include <string.h> 51 52#include "rootlessCommon.h" 53#include "rootlessWindow.h" 54 55/* In milliseconds */ 56#ifndef ROOTLESS_REDISPLAY_DELAY 57#define ROOTLESS_REDISPLAY_DELAY 10 58#endif 59 60extern int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild, 61 VTKind kind); 62extern Bool RootlessCreateGC(GCPtr pGC); 63 64// Initialize globals 65DevPrivateKeyRec rootlessGCPrivateKeyRec; 66DevPrivateKeyRec rootlessScreenPrivateKeyRec; 67DevPrivateKeyRec rootlessWindowPrivateKeyRec; 68DevPrivateKeyRec rootlessWindowOldPixmapPrivateKeyRec; 69 70/* 71 * RootlessUpdateScreenPixmap 72 * miCreateScreenResources does not like a null framebuffer pointer, 73 * it leaves the screen pixmap with an uninitialized data pointer. 74 * Thus, rootless implementations typically set the framebuffer width 75 * to zero so that miCreateScreenResources does not allocate a screen 76 * pixmap for us. We allocate our own screen pixmap here since we need 77 * the screen pixmap to be valid (e.g. CopyArea from the root window). 78 */ 79void 80RootlessUpdateScreenPixmap(ScreenPtr pScreen) 81{ 82 RootlessScreenRec *s = SCREENREC(pScreen); 83 PixmapPtr pPix; 84 unsigned int rowbytes; 85 86 pPix = (*pScreen->GetScreenPixmap)(pScreen); 87 if (pPix == NULL) { 88 pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0); 89 (*pScreen->SetScreenPixmap)(pPix); 90 } 91 92 rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth); 93 94 if (s->pixmap_data_size < rowbytes) { 95 free(s->pixmap_data); 96 97 s->pixmap_data_size = rowbytes; 98 s->pixmap_data = malloc(s->pixmap_data_size); 99 if (s->pixmap_data == NULL) 100 return; 101 102 memset(s->pixmap_data, 0xFF, s->pixmap_data_size); 103 104 pScreen->ModifyPixmapHeader(pPix, pScreen->width, pScreen->height, 105 pScreen->rootDepth, 106 BitsPerPixel(pScreen->rootDepth), 107 0, s->pixmap_data); 108 /* ModifyPixmapHeader ignores zero arguments, so install rowbytes 109 by hand. */ 110 pPix->devKind = 0; 111 } 112} 113 114 115/* 116 * RootlessCreateScreenResources 117 * Rootless implementations typically set a null framebuffer pointer, which 118 * causes problems with miCreateScreenResources. We fix things up here. 119 */ 120static Bool 121RootlessCreateScreenResources(ScreenPtr pScreen) 122{ 123 Bool ret = TRUE; 124 125 SCREEN_UNWRAP(pScreen, CreateScreenResources); 126 127 if (pScreen->CreateScreenResources != NULL) 128 ret = (*pScreen->CreateScreenResources)(pScreen); 129 130 SCREEN_WRAP(pScreen, CreateScreenResources); 131 132 if (!ret) 133 return ret; 134 135 /* Make sure we have a valid screen pixmap. */ 136 137 RootlessUpdateScreenPixmap(pScreen); 138 139 return ret; 140} 141 142 143static Bool 144RootlessCloseScreen(int i, ScreenPtr pScreen) 145{ 146 RootlessScreenRec *s; 147 148 s = SCREENREC(pScreen); 149 150 // fixme unwrap everything that was wrapped? 151 pScreen->CloseScreen = s->CloseScreen; 152 153 if (s->pixmap_data != NULL) { 154 free(s->pixmap_data); 155 s->pixmap_data = NULL; 156 s->pixmap_data_size = 0; 157 } 158 159 free(s); 160 return pScreen->CloseScreen(i, pScreen); 161} 162 163 164static void 165RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, 166 unsigned int format, unsigned long planeMask, char *pdstLine) 167{ 168 ScreenPtr pScreen = pDrawable->pScreen; 169 SCREEN_UNWRAP(pScreen, GetImage); 170 171 if (pDrawable->type == DRAWABLE_WINDOW) { 172 int x0, y0, x1, y1; 173 RootlessWindowRec *winRec; 174 175 // Many apps use GetImage to sync with the visible frame buffer 176 // FIXME: entire screen or just window or all screens? 177 RootlessRedisplayScreen(pScreen); 178 179 // RedisplayScreen stops drawing, so we need to start it again 180 RootlessStartDrawing((WindowPtr)pDrawable); 181 182 /* Check that we have some place to read from. */ 183 winRec = WINREC(TopLevelParent((WindowPtr) pDrawable)); 184 if (winRec == NULL) 185 goto out; 186 187 /* Clip to top-level window bounds. */ 188 /* FIXME: fbGetImage uses the width parameter to calculate the 189 stride of the destination pixmap. If w is clipped, the data 190 returned will be garbage, although we will not crash. */ 191 192 x0 = pDrawable->x + sx; 193 y0 = pDrawable->y + sy; 194 x1 = x0 + w; 195 y1 = y0 + h; 196 197 x0 = max (x0, winRec->x); 198 y0 = max (y0, winRec->y); 199 x1 = min (x1, winRec->x + winRec->width); 200 y1 = min (y1, winRec->y + winRec->height); 201 202 sx = x0 - pDrawable->x; 203 sy = y0 - pDrawable->y; 204 w = x1 - x0; 205 h = y1 - y0; 206 207 if (w <= 0 || h <= 0) 208 goto out; 209 } 210 211 pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); 212 213out: 214 SCREEN_WRAP(pScreen, GetImage); 215} 216 217 218/* 219 * RootlessSourceValidate 220 * CopyArea and CopyPlane use a GC tied to the destination drawable. 221 * StartDrawing/StopDrawing wrappers won't be called if source is 222 * a visible window but the destination isn't. So, we call StartDrawing 223 * here and leave StopDrawing for the block handler. 224 */ 225static void 226RootlessSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h, 227 unsigned int subWindowMode) 228{ 229 SCREEN_UNWRAP(pDrawable->pScreen, SourceValidate); 230 if (pDrawable->type == DRAWABLE_WINDOW) { 231 WindowPtr pWin = (WindowPtr)pDrawable; 232 RootlessStartDrawing(pWin); 233 } 234 if (pDrawable->pScreen->SourceValidate) { 235 pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h, subWindowMode); 236 } 237 SCREEN_WRAP(pDrawable->pScreen, SourceValidate); 238} 239 240static void 241RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, 242 INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, 243 INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) 244{ 245 ScreenPtr pScreen = pDst->pDrawable->pScreen; 246 PictureScreenPtr ps = GetPictureScreen(pScreen); 247 WindowPtr srcWin, dstWin, maskWin = NULL; 248 249 if (pMask) { // pMask can be NULL 250 maskWin = (pMask->pDrawable->type == DRAWABLE_WINDOW) ? 251 (WindowPtr)pMask->pDrawable : NULL; 252 } 253 srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ? 254 (WindowPtr)pSrc->pDrawable : NULL; 255 dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ? 256 (WindowPtr)pDst->pDrawable : NULL; 257 258 // SCREEN_UNWRAP(ps, Composite); 259 ps->Composite = SCREENREC(pScreen)->Composite; 260 261 if (srcWin && IsFramedWindow(srcWin)) 262 RootlessStartDrawing(srcWin); 263 if (maskWin && IsFramedWindow(maskWin)) 264 RootlessStartDrawing(maskWin); 265 if (dstWin && IsFramedWindow(dstWin)) 266 RootlessStartDrawing(dstWin); 267 268 ps->Composite(op, pSrc, pMask, pDst, 269 xSrc, ySrc, xMask, yMask, 270 xDst, yDst, width, height); 271 272 if (dstWin && IsFramedWindow(dstWin)) { 273 RootlessDamageRect(dstWin, xDst, yDst, width, height); 274 } 275 276 ps->Composite = RootlessComposite; 277 // SCREEN_WRAP(ps, Composite); 278} 279 280 281static void 282RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, 283 PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, 284 int nlist, GlyphListPtr list, GlyphPtr *glyphs) 285{ 286 ScreenPtr pScreen = pDst->pDrawable->pScreen; 287 PictureScreenPtr ps = GetPictureScreen(pScreen); 288 int x, y; 289 int n; 290 GlyphPtr glyph; 291 WindowPtr srcWin, dstWin; 292 293 srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ? 294 (WindowPtr)pSrc->pDrawable : NULL; 295 dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ? 296 (WindowPtr)pDst->pDrawable : NULL; 297 298 if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin); 299 if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin); 300 301 //SCREEN_UNWRAP(ps, Glyphs); 302 ps->Glyphs = SCREENREC(pScreen)->Glyphs; 303 ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); 304 ps->Glyphs = RootlessGlyphs; 305 //SCREEN_WRAP(ps, Glyphs); 306 307 if (dstWin && IsFramedWindow(dstWin)) { 308 x = xSrc; 309 y = ySrc; 310 311 while (nlist--) { 312 x += list->xOff; 313 y += list->yOff; 314 n = list->len; 315 316 /* Calling DamageRect for the bounding box of each glyph is 317 inefficient. So compute the union of all glyphs in a list 318 and damage that. */ 319 320 if (n > 0) { 321 BoxRec box; 322 323 glyph = *glyphs++; 324 325 box.x1 = x - glyph->info.x; 326 box.y1 = y - glyph->info.y; 327 box.x2 = box.x1 + glyph->info.width; 328 box.y2 = box.y1 + glyph->info.height; 329 330 x += glyph->info.xOff; 331 y += glyph->info.yOff; 332 333 while (--n > 0) { 334 short x1, y1, x2, y2; 335 336 glyph = *glyphs++; 337 338 x1 = x - glyph->info.x; 339 y1 = y - glyph->info.y; 340 x2 = x1 + glyph->info.width; 341 y2 = y1 + glyph->info.height; 342 343 box.x1 = max (box.x1, x1); 344 box.y1 = max (box.y1, y1); 345 box.x2 = max (box.x2, x2); 346 box.y2 = max (box.y2, y2); 347 348 x += glyph->info.xOff; 349 y += glyph->info.yOff; 350 } 351 352 RootlessDamageBox(dstWin, &box); 353 } 354 list++; 355 } 356 } 357} 358 359 360/* 361 * RootlessValidateTree 362 * ValidateTree is modified in two ways: 363 * - top-level windows don't clip each other 364 * - windows aren't clipped against root. 365 * These only matter when validating from the root. 366 */ 367static int 368RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) 369{ 370 int result; 371 RegionRec saveRoot; 372 ScreenPtr pScreen = pParent->drawable.pScreen; 373 374 SCREEN_UNWRAP(pScreen, ValidateTree); 375 RL_DEBUG_MSG("VALIDATETREE start "); 376 377 // Use our custom version to validate from root 378 if (IsRoot(pParent)) { 379 RL_DEBUG_MSG("custom "); 380 result = RootlessMiValidateTree(pParent, pChild, kind); 381 } else { 382 HUGE_ROOT(pParent); 383 result = pScreen->ValidateTree(pParent, pChild, kind); 384 NORMAL_ROOT(pParent); 385 } 386 387 SCREEN_WRAP(pScreen, ValidateTree); 388 RL_DEBUG_MSG("VALIDATETREE end\n"); 389 390 return result; 391} 392 393 394/* 395 * RootlessMarkOverlappedWindows 396 * MarkOverlappedWindows is modified to ignore overlapping 397 * top-level windows. 398 */ 399static Bool 400RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, 401 WindowPtr *ppLayerWin) 402{ 403 RegionRec saveRoot; 404 Bool result; 405 ScreenPtr pScreen = pWin->drawable.pScreen; 406 SCREEN_UNWRAP(pScreen, MarkOverlappedWindows); 407 RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start "); 408 409 HUGE_ROOT(pWin); 410 if (IsRoot(pWin)) { 411 // root - mark nothing 412 RL_DEBUG_MSG("is root not marking "); 413 result = FALSE; 414 } 415 else if (! IsTopLevel(pWin)) { 416 // not top-level window - mark normally 417 result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin); 418 } 419 else { 420 //top-level window - mark children ONLY - NO overlaps with sibs (?) 421 // This code copied from miMarkOverlappedWindows() 422 423 register WindowPtr pChild; 424 Bool anyMarked = FALSE; 425 MarkWindowProcPtr MarkWindow = pScreen->MarkWindow; 426 427 RL_DEBUG_MSG("is top level! "); 428 /* single layered systems are easy */ 429 if (ppLayerWin) *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 pFirst = pFirst->nextSib; 457 } 458 if (anyMarked) 459 (* MarkWindow)(pWin->parent); 460 result = anyMarked; 461 } 462 NORMAL_ROOT(pWin); 463 SCREEN_WRAP(pScreen, MarkOverlappedWindows); 464 RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n"); 465 466 return result; 467} 468 469static void expose_1 (WindowPtr pWin) { 470 WindowPtr pChild; 471 472 if (!pWin->realized) 473 return; 474 475 miPaintWindow(pWin, &pWin->borderClip, PW_BACKGROUND); 476 477 /* FIXME: comments in windowstr.h indicate that borderClip doesn't 478 include subwindow visibility. But I'm not so sure.. so we may 479 be exposing too much.. */ 480 481 miSendExposures (pWin, &pWin->borderClip, 482 pWin->drawable.x, pWin->drawable.y); 483 484 for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib) 485 expose_1 (pChild); 486} 487 488void 489RootlessScreenExpose (ScreenPtr pScreen) 490{ 491 expose_1 (pScreen->root); 492} 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 556 557static CARD32 558RootlessRedisplayCallback(OsTimerPtr timer, CARD32 time, void *arg) 559{ 560 RootlessScreenRec *screenRec = arg; 561 562 if (!screenRec->redisplay_queued) { 563 /* No update needed. Stop the timer. */ 564 565 screenRec->redisplay_timer_set = FALSE; 566 return 0; 567 } 568 569 screenRec->redisplay_queued = FALSE; 570 571 /* Mark that we should redisplay before waiting for I/O next time */ 572 screenRec->redisplay_expired = TRUE; 573 574 /* Reinstall the timer immediately, so we get as close to our 575 redisplay interval as possible. */ 576 577 return ROOTLESS_REDISPLAY_DELAY; 578} 579 580 581/* 582 * RootlessQueueRedisplay 583 * Queue a redisplay after a timer delay to ensure we do not redisplay 584 * too frequently. 585 */ 586void 587RootlessQueueRedisplay(ScreenPtr pScreen) 588{ 589 RootlessScreenRec *screenRec = SCREENREC(pScreen); 590 591 screenRec->redisplay_queued = TRUE; 592 593 if (screenRec->redisplay_timer_set) 594 return; 595 596 screenRec->redisplay_timer = TimerSet(screenRec->redisplay_timer, 597 0, ROOTLESS_REDISPLAY_DELAY, 598 RootlessRedisplayCallback, 599 screenRec); 600 screenRec->redisplay_timer_set = TRUE; 601} 602 603 604/* 605 * RootlessBlockHandler 606 * If the redisplay timer has expired, flush drawing before blocking 607 * on select(). 608 */ 609static void 610RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask) 611{ 612 ScreenPtr pScreen = pbdata; 613 RootlessScreenRec *screenRec = SCREENREC(pScreen); 614 615 if (screenRec->redisplay_expired) { 616 screenRec->redisplay_expired = FALSE; 617 618 RootlessRedisplayScreen(pScreen); 619 } 620} 621 622 623static void 624RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask) 625{ 626 // nothing here 627} 628 629 630static Bool 631RootlessAllocatePrivates(ScreenPtr pScreen) 632{ 633 RootlessScreenRec *s; 634 635 if (!dixRegisterPrivateKey(&rootlessGCPrivateKeyRec, PRIVATE_GC, sizeof(RootlessGCRec))) 636 return FALSE; 637 if (!dixRegisterPrivateKey(&rootlessScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) 638 return FALSE; 639 if (!dixRegisterPrivateKey(&rootlessWindowPrivateKeyRec, PRIVATE_WINDOW, 0)) 640 return FALSE; 641 if (!dixRegisterPrivateKey(&rootlessWindowOldPixmapPrivateKeyRec, PRIVATE_WINDOW, 0)) 642 return FALSE; 643 644 s = malloc(sizeof(RootlessScreenRec)); 645 if (! s) return FALSE; 646 SETSCREENREC(pScreen, s); 647 648 s->pixmap_data = NULL; 649 s->pixmap_data_size = 0; 650 651 s->redisplay_timer = NULL; 652 s->redisplay_timer_set = FALSE; 653 654 return TRUE; 655} 656 657 658static void 659RootlessWrap(ScreenPtr pScreen) 660{ 661 RootlessScreenRec *s = SCREENREC(pScreen); 662 663#define WRAP(a) \ 664 if (pScreen->a) { \ 665 s->a = pScreen->a; \ 666 } else { \ 667 RL_DEBUG_MSG("null screen fn " #a "\n"); \ 668 s->a = NULL; \ 669 } \ 670 pScreen->a = Rootless##a 671 672 WRAP(CreateScreenResources); 673 WRAP(CloseScreen); 674 WRAP(CreateGC); 675 WRAP(CopyWindow); 676 WRAP(GetImage); 677 WRAP(SourceValidate); 678 WRAP(CreateWindow); 679 WRAP(DestroyWindow); 680 WRAP(RealizeWindow); 681 WRAP(UnrealizeWindow); 682 WRAP(MoveWindow); 683 WRAP(PositionWindow); 684 WRAP(ResizeWindow); 685 WRAP(RestackWindow); 686 WRAP(ReparentWindow); 687 WRAP(ChangeBorderWidth); 688 WRAP(MarkOverlappedWindows); 689 WRAP(ValidateTree); 690 WRAP(ChangeWindowAttributes); 691 WRAP(InstallColormap); 692 WRAP(UninstallColormap); 693 WRAP(StoreColors); 694 695 WRAP(SetShape); 696 697 { 698 // Composite and Glyphs don't use normal screen wrapping 699 PictureScreenPtr ps = GetPictureScreen(pScreen); 700 s->Composite = ps->Composite; 701 ps->Composite = RootlessComposite; 702 s->Glyphs = ps->Glyphs; 703 ps->Glyphs = RootlessGlyphs; 704 } 705 706 // WRAP(ClearToBackground); fixme put this back? useful for shaped wins? 707 708#undef WRAP 709} 710 711 712/* 713 * RootlessInit 714 * Called by the rootless implementation to initialize the rootless layer. 715 * Rootless wraps lots of stuff and needs a bunch of devPrivates. 716 */ 717Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs) 718{ 719 RootlessScreenRec *s; 720 721 if (!RootlessAllocatePrivates(pScreen)) 722 return FALSE; 723 724 s = SCREENREC(pScreen); 725 726 s->imp = procs; 727 s->colormap = NULL; 728 s->redisplay_expired = FALSE; 729 730 RootlessWrap(pScreen); 731 732 if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler, 733 RootlessWakeupHandler, 734 (pointer) pScreen)) 735 { 736 return FALSE; 737 } 738 739 return TRUE; 740} 741 742void RootlessUpdateRooted (Bool state) { 743 int i; 744 745 if (!state) 746 { 747 for (i = 0; i < screenInfo.numScreens; i++) 748 RootlessDisableRoot (screenInfo.screens[i]); 749 } 750 else 751 { 752 for (i = 0; i < screenInfo.numScreens; i++) 753 RootlessEnableRoot (screenInfo.screens[i]); 754 } 755} 756