rootlessScreen.c (21448B)
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 pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h, 232 subWindowMode); 233 SCREEN_WRAP(pDrawable->pScreen, SourceValidate); 234 } 235 236 static void 237 RootlessComposite(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 276 static void 277 RootlessGlyphs(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 */ 363 static int 364 RootlessValidateTree(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 */ 395 static Bool 396 RootlessMarkOverlappedWindows(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 466 static void 467 expose_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 487 void 488 RootlessScreenExpose(ScreenPtr pScreen) 489 { 490 expose_1(pScreen->root); 491 } 492 493 ColormapPtr 494 RootlessGetColormap(ScreenPtr pScreen) 495 { 496 RootlessScreenRec *s = SCREENREC(pScreen); 497 498 return s->colormap; 499 } 500 501 static void 502 RootlessInstallColormap(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 520 static void 521 RootlessUninstallColormap(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 536 static void 537 RootlessStoreColors(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 554 static CARD32 555 RootlessRedisplayCallback(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 */ 582 void 583 RootlessQueueRedisplay(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 */ 603 static void 604 RootlessBlockHandler(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 616 static void 617 RootlessWakeupHandler(void *data, int result) 618 { 619 // nothing here 620 } 621 622 static Bool 623 RootlessAllocatePrivates(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 652 static void 653 RootlessWrap(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 */ 712 Bool 713 RootlessInit(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 737 void 738 RootlessUpdateRooted(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 }