rootlessScreen.c revision 1b5d61b8
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 pWin->drawable.pScreen->PaintWindow(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(void *pbdata, void *ptimeout) 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(void *data, int result) 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(PaintWindow); 673 WRAP(GetImage); 674 WRAP(SourceValidate); 675 WRAP(CreateWindow); 676 WRAP(DestroyWindow); 677 WRAP(RealizeWindow); 678 WRAP(UnrealizeWindow); 679 WRAP(MoveWindow); 680 WRAP(PositionWindow); 681 WRAP(ResizeWindow); 682 WRAP(RestackWindow); 683 WRAP(ReparentWindow); 684 WRAP(ChangeBorderWidth); 685 WRAP(MarkOverlappedWindows); 686 WRAP(ValidateTree); 687 WRAP(ChangeWindowAttributes); 688 WRAP(InstallColormap); 689 WRAP(UninstallColormap); 690 WRAP(StoreColors); 691 692 WRAP(SetShape); 693 694 { 695 // Composite and Glyphs don't use normal screen wrapping 696 PictureScreenPtr ps = GetPictureScreen(pScreen); 697 698 s->Composite = ps->Composite; 699 ps->Composite = RootlessComposite; 700 s->Glyphs = ps->Glyphs; 701 ps->Glyphs = RootlessGlyphs; 702 } 703 704 // WRAP(ClearToBackground); fixme put this back? useful for shaped wins? 705 706#undef WRAP 707} 708 709/* 710 * RootlessInit 711 * Called by the rootless implementation to initialize the rootless layer. 712 * Rootless wraps lots of stuff and needs a bunch of devPrivates. 713 */ 714Bool 715RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs) 716{ 717 RootlessScreenRec *s; 718 719 if (!RootlessAllocatePrivates(pScreen)) 720 return FALSE; 721 722 s = SCREENREC(pScreen); 723 724 s->imp = procs; 725 s->colormap = NULL; 726 s->redisplay_expired = FALSE; 727 728 RootlessWrap(pScreen); 729 730 if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler, 731 RootlessWakeupHandler, 732 (void *) pScreen)) { 733 return FALSE; 734 } 735 736 return TRUE; 737} 738 739void 740RootlessUpdateRooted(Bool state) 741{ 742 int i; 743 744 if (!state) { 745 for (i = 0; i < screenInfo.numScreens; i++) 746 RootlessDisableRoot(screenInfo.screens[i]); 747 } 748 else { 749 for (i = 0; i < screenInfo.numScreens; i++) 750 RootlessEnableRoot(screenInfo.screens[i]); 751 } 752} 753