winshadddnl.c revision 706f2543
1/* 2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3 * 4 *Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 *"Software"), to deal in the Software without restriction, including 7 *without limitation the rights to use, copy, modify, merge, publish, 8 *distribute, sublicense, and/or sell copies of the Software, and to 9 *permit persons to whom the Software is furnished to do so, subject to 10 *the following conditions: 11 * 12 *The above copyright notice and this permission notice shall be 13 *included in all copies or substantial portions of the Software. 14 * 15 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR 19 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 * 23 *Except as contained in this notice, the name of the XFree86 Project 24 *shall not be used in advertising or otherwise to promote the sale, use 25 *or other dealings in this Software without prior written authorization 26 *from the XFree86 Project. 27 * 28 * Authors: Dakshinamurthy Karra 29 * Suhaib M Siddiqi 30 * Peter Busch 31 * Harold L Hunt II 32 */ 33 34#ifdef HAVE_XWIN_CONFIG_H 35#include <xwin-config.h> 36#endif 37#include "win.h" 38 39 40/* 41 * FIXME: Headers are broken, DEFINE_GUID doesn't work correctly, 42 * so we have to redefine it here. 43 */ 44#ifdef DEFINE_GUID 45#undef DEFINE_GUID 46#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} 47#endif /* DEFINE_GUID */ 48 49/* 50 * FIXME: Headers are broken, IID_IDirectDraw4 has to be defined 51 * here manually. Should be handled by ddraw.h 52 */ 53#ifndef IID_IDirectDraw4 54DEFINE_GUID( IID_IDirectDraw4, 0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 ); 55#endif /* IID_IDirectDraw4 */ 56 57#define FAIL_MSG_MAX_BLT 10 58 59 60/* 61 * Local prototypes 62 */ 63 64static Bool 65winAllocateFBShadowDDNL (ScreenPtr pScreen); 66 67static void 68winShadowUpdateDDNL (ScreenPtr pScreen, 69 shadowBufPtr pBuf); 70 71static Bool 72winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen); 73 74static Bool 75winInitVisualsShadowDDNL (ScreenPtr pScreen); 76 77static Bool 78winAdjustVideoModeShadowDDNL (ScreenPtr pScreen); 79 80static Bool 81winBltExposedRegionsShadowDDNL (ScreenPtr pScreen); 82 83static Bool 84winActivateAppShadowDDNL (ScreenPtr pScreen); 85 86static Bool 87winRedrawScreenShadowDDNL (ScreenPtr pScreen); 88 89static Bool 90winRealizeInstalledPaletteShadowDDNL (ScreenPtr pScreen); 91 92static Bool 93winInstallColormapShadowDDNL (ColormapPtr pColormap); 94 95static Bool 96winStoreColorsShadowDDNL (ColormapPtr pmap, 97 int ndef, 98 xColorItem *pdefs); 99 100static Bool 101winCreateColormapShadowDDNL (ColormapPtr pColormap); 102 103static Bool 104winDestroyColormapShadowDDNL (ColormapPtr pColormap); 105 106static Bool 107winCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen); 108 109static Bool 110winReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen); 111 112 113/* 114 * Create the primary surface and attach the clipper. 115 * Used for both the initial surface creation and during 116 * WM_DISPLAYCHANGE messages. 117 */ 118 119static Bool 120winCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen) 121{ 122 winScreenPriv(pScreen); 123 HRESULT ddrval = DD_OK; 124 DDSURFACEDESC2 ddsd; 125 126 winDebug ("winCreatePrimarySurfaceShadowDDNL - Creating primary surface\n"); 127 128 /* Describe the primary surface */ 129 ZeroMemory (&ddsd, sizeof (ddsd)); 130 ddsd.dwSize = sizeof (ddsd); 131 ddsd.dwFlags = DDSD_CAPS; 132 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; 133 134 /* Create the primary surface */ 135 ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4, 136 &ddsd, 137 &pScreenPriv->pddsPrimary4, 138 NULL); 139 pScreenPriv->fRetryCreateSurface = FALSE; 140 if (FAILED (ddrval)) 141 { 142 if (ddrval == DDERR_NOEXCLUSIVEMODE) 143 { 144 /* Recreating the surface failed. Mark screen to retry later */ 145 pScreenPriv->fRetryCreateSurface = TRUE; 146 winDebug ("winCreatePrimarySurfaceShadowDDNL - Could not create " 147 "primary surface: DDERR_NOEXCLUSIVEMODE\n"); 148 } 149 else 150 { 151 ErrorF ("winCreatePrimarySurfaceShadowDDNL - Could not create " 152 "primary surface: %08x\n", (unsigned int) ddrval); 153 } 154 return FALSE; 155 } 156 157#if 1 158 winDebug ("winCreatePrimarySurfaceShadowDDNL - Created primary surface\n"); 159#endif 160 161 /* Attach our clipper to our primary surface handle */ 162 ddrval = IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4, 163 pScreenPriv->pddcPrimary); 164 if (FAILED (ddrval)) 165 { 166 ErrorF ("winCreatePrimarySurfaceShadowDDNL - Primary attach clipper " 167 "failed: %08x\n", 168 (unsigned int) ddrval); 169 return FALSE; 170 } 171 172#if 1 173 winDebug ("winCreatePrimarySurfaceShadowDDNL - Attached clipper to primary " 174 "surface\n"); 175#endif 176 177 /* Everything was correct */ 178 return TRUE; 179} 180 181 182/* 183 * Detach the clipper and release the primary surface. 184 * Called from WM_DISPLAYCHANGE. 185 */ 186 187static Bool 188winReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen) 189{ 190 winScreenPriv(pScreen); 191 192 winDebug ("winReleasePrimarySurfaceShadowDDNL - Hello\n"); 193 194 /* Release the primary surface and clipper, if they exist */ 195 if (pScreenPriv->pddsPrimary4) 196 { 197 /* 198 * Detach the clipper from the primary surface. 199 * NOTE: We do this explicity for clarity. The Clipper is not released. 200 */ 201 IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4, 202 NULL); 203 204 winDebug ("winReleasePrimarySurfaceShadowDDNL - Detached clipper\n"); 205 206 /* Release the primary surface */ 207 IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4); 208 pScreenPriv->pddsPrimary4 = NULL; 209 } 210 211 winDebug ("winReleasePrimarySurfaceShadowDDNL - Released primary surface\n"); 212 213 return TRUE; 214} 215 216 217/* 218 * Create a DirectDraw surface for the shadow framebuffer; also create 219 * a primary surface object so we can blit to the display. 220 * 221 * Install a DirectDraw clipper on our primary surface object 222 * that clips our blits to the unobscured client area of our display window. 223 */ 224 225Bool 226winAllocateFBShadowDDNL (ScreenPtr pScreen) 227{ 228 winScreenPriv(pScreen); 229 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 230 HRESULT ddrval = DD_OK; 231 DDSURFACEDESC2 ddsdShadow; 232 char *lpSurface = NULL; 233 DDPIXELFORMAT ddpfPrimary; 234 235#if CYGDEBUG 236 winDebug ("winAllocateFBShadowDDNL - w %d h %d d %d\n", 237 pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwDepth); 238#endif 239 240 /* Set the padded screen width */ 241 pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth, 242 pScreenInfo->dwBPP); 243 244 /* Allocate memory for our shadow surface */ 245 lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); 246 if (lpSurface == NULL) 247 { 248 ErrorF ("winAllocateFBShadowDDNL - Could not allocate bits\n"); 249 return FALSE; 250 } 251 252 /* 253 * Initialize the framebuffer memory so we don't get a 254 * strange display at startup 255 */ 256 ZeroMemory (lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); 257 258 /* Create a clipper */ 259 ddrval = (*g_fpDirectDrawCreateClipper) (0, 260 &pScreenPriv->pddcPrimary, 261 NULL); 262 if (FAILED (ddrval)) 263 { 264 ErrorF ("winAllocateFBShadowDDNL - Could not attach clipper: %08x\n", 265 (unsigned int) ddrval); 266 return FALSE; 267 } 268 269#if CYGDEBUG 270 winDebug ("winAllocateFBShadowDDNL - Created a clipper\n"); 271#endif 272 273 /* Attach the clipper to our display window */ 274 ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary, 275 0, 276 pScreenPriv->hwndScreen); 277 if (FAILED (ddrval)) 278 { 279 ErrorF ("winAllocateFBShadowDDNL - Clipper not attached " 280 "to window: %08x\n", 281 (unsigned int) ddrval); 282 return FALSE; 283 } 284 285#if CYGDEBUG 286 winDebug ("winAllocateFBShadowDDNL - Attached clipper to window\n"); 287#endif 288 289 /* Create a DirectDraw object, store the address at lpdd */ 290 ddrval = (*g_fpDirectDrawCreate) (NULL, 291 (LPDIRECTDRAW*) &pScreenPriv->pdd, 292 NULL); 293 if (FAILED (ddrval)) 294 { 295 ErrorF ("winAllocateFBShadowDDNL - Could not start " 296 "DirectDraw: %08x\n", 297 (unsigned int) ddrval); 298 return FALSE; 299 } 300 301#if CYGDEBUG 302 winDebug ("winAllocateFBShadowDDNL - Created and initialized DD\n"); 303#endif 304 305 /* Get a DirectDraw4 interface pointer */ 306 ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, 307 &IID_IDirectDraw4, 308 (LPVOID*) &pScreenPriv->pdd4); 309 if (FAILED (ddrval)) 310 { 311 ErrorF ("winAllocateFBShadowDDNL - Failed DD4 query: %08x\n", 312 (unsigned int) ddrval); 313 return FALSE; 314 } 315 316 /* Are we full screen? */ 317 if (pScreenInfo->fFullScreen) 318 { 319 DDSURFACEDESC2 ddsdCurrent; 320 DWORD dwRefreshRateCurrent = 0; 321 HDC hdc = NULL; 322 323 /* Set the cooperative level to full screen */ 324 ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4, 325 pScreenPriv->hwndScreen, 326 DDSCL_EXCLUSIVE 327 | DDSCL_FULLSCREEN); 328 if (FAILED (ddrval)) 329 { 330 ErrorF ("winAllocateFBShadowDDNL - Could not set " 331 "cooperative level: %08x\n", 332 (unsigned int) ddrval); 333 return FALSE; 334 } 335 336 /* 337 * We only need to get the current refresh rate for comparison 338 * if a refresh rate has been passed on the command line. 339 */ 340 if (pScreenInfo->dwRefreshRate != 0) 341 { 342 ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent)); 343 ddsdCurrent.dwSize = sizeof (ddsdCurrent); 344 345 /* Get information about current display settings */ 346 ddrval = IDirectDraw4_GetDisplayMode (pScreenPriv->pdd4, 347 &ddsdCurrent); 348 if (FAILED (ddrval)) 349 { 350 ErrorF ("winAllocateFBShadowDDNL - Could not get current " 351 "refresh rate: %08x. Continuing.\n", 352 (unsigned int) ddrval); 353 dwRefreshRateCurrent = 0; 354 } 355 else 356 { 357 /* Grab the current refresh rate */ 358 dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate; 359 } 360 } 361 362 /* Clean up the refresh rate */ 363 if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) 364 { 365 /* 366 * Refresh rate is non-specified or equal to current. 367 */ 368 pScreenInfo->dwRefreshRate = 0; 369 } 370 371 /* Grab a device context for the screen */ 372 hdc = GetDC (NULL); 373 if (hdc == NULL) 374 { 375 ErrorF ("winAllocateFBShadowDDNL - GetDC () failed\n"); 376 return FALSE; 377 } 378 379 /* Only change the video mode when different than current mode */ 380 if (!pScreenInfo->fMultipleMonitors 381 && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN) 382 || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN) 383 || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL) 384 || pScreenInfo->dwRefreshRate != 0)) 385 { 386 winDebug ("winAllocateFBShadowDDNL - Changing video mode\n"); 387 388 /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */ 389 ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4, 390 pScreenInfo->dwWidth, 391 pScreenInfo->dwHeight, 392 pScreenInfo->dwBPP, 393 pScreenInfo->dwRefreshRate, 394 0); 395 if (FAILED (ddrval)) 396 { 397 ErrorF ("winAllocateFBShadowDDNL - Could not set " 398 "full screen display mode: %08x\n", 399 (unsigned int) ddrval); 400 ErrorF ("winAllocateFBShadowDDNL - Using default driver refresh rate\n"); 401 ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4, 402 pScreenInfo->dwWidth, 403 pScreenInfo->dwHeight, 404 pScreenInfo->dwBPP, 405 0, 406 0); 407 if (FAILED(ddrval)) 408 { 409 ErrorF ("winAllocateFBShadowDDNL - Could not set default refresh rate " 410 "full screen display mode: %08x\n", 411 (unsigned int) ddrval); 412 return FALSE; 413 } 414 } 415 } 416 else 417 { 418 winDebug ("winAllocateFBShadowDDNL - Not changing video mode\n"); 419 } 420 421 /* Release our DC */ 422 ReleaseDC (NULL, hdc); 423 hdc = NULL; 424 } 425 else 426 { 427 /* Set the cooperative level for windowed mode */ 428 ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4, 429 pScreenPriv->hwndScreen, 430 DDSCL_NORMAL); 431 if (FAILED (ddrval)) 432 { 433 ErrorF ("winAllocateFBShadowDDNL - Could not set " 434 "cooperative level: %08x\n", 435 (unsigned int) ddrval); 436 return FALSE; 437 } 438 } 439 440 /* Create the primary surface */ 441 if (!winCreatePrimarySurfaceShadowDDNL (pScreen)) 442 { 443 ErrorF ("winAllocateFBShadowDDNL - winCreatePrimarySurfaceShadowDDNL " 444 "failed\n"); 445 return FALSE; 446 } 447 448 /* Get primary surface's pixel format */ 449 ZeroMemory (&ddpfPrimary, sizeof (ddpfPrimary)); 450 ddpfPrimary.dwSize = sizeof (ddpfPrimary); 451 ddrval = IDirectDrawSurface4_GetPixelFormat (pScreenPriv->pddsPrimary4, 452 &ddpfPrimary); 453 if (FAILED (ddrval)) 454 { 455 ErrorF ("winAllocateFBShadowDDNL - Could not get primary " 456 "pixformat: %08x\n", 457 (unsigned int) ddrval); 458 return FALSE; 459 } 460 461#if CYGDEBUG 462 winDebug ("winAllocateFBShadowDDNL - Primary masks: %08x %08x %08x " 463 "dwRGBBitCount: %d\n", 464 ddpfPrimary.u2.dwRBitMask, 465 ddpfPrimary.u3.dwGBitMask, 466 ddpfPrimary.u4.dwBBitMask, 467 ddpfPrimary.u1.dwRGBBitCount); 468#endif 469 470 /* Describe the shadow surface to be created */ 471 /* 472 * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, 473 * as drawing, locking, and unlocking take forever 474 * with video memory surfaces. In addition, 475 * video memory is a somewhat scarce resource, 476 * so you shouldn't be allocating video memory when 477 * you have the option of using system memory instead. 478 */ 479 ZeroMemory (&ddsdShadow, sizeof (ddsdShadow)); 480 ddsdShadow.dwSize = sizeof (ddsdShadow); 481 ddsdShadow.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH 482 | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT; 483 ddsdShadow.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; 484 ddsdShadow.dwHeight = pScreenInfo->dwHeight; 485 ddsdShadow.dwWidth = pScreenInfo->dwWidth; 486 ddsdShadow.u1.lPitch = pScreenInfo->dwPaddedWidth; 487 ddsdShadow.lpSurface = lpSurface; 488 ddsdShadow.u4.ddpfPixelFormat = ddpfPrimary; 489 490 winDebug ("winAllocateFBShadowDDNL - lPitch: %d\n", 491 (int) pScreenInfo->dwPaddedWidth); 492 493 /* Create the shadow surface */ 494 ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4, 495 &ddsdShadow, 496 &pScreenPriv->pddsShadow4, 497 NULL); 498 if (FAILED (ddrval)) 499 { 500 ErrorF ("winAllocateFBShadowDDNL - Could not create shadow " 501 "surface: %08x\n", (unsigned int) ddrval); 502 return FALSE; 503 } 504 505#if CYGDEBUG || YES 506 winDebug ("winAllocateFBShadowDDNL - Created shadow pitch: %d\n", 507 (int) ddsdShadow.u1.lPitch); 508#endif 509 510 /* Grab the pitch from the surface desc */ 511 pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8) 512 / pScreenInfo->dwBPP; 513 514#if CYGDEBUG || YES 515 winDebug ("winAllocateFBShadowDDNL - Created shadow stride: %d\n", 516 (int) pScreenInfo->dwStride); 517#endif 518 519 /* Save the pointer to our surface memory */ 520 pScreenInfo->pfb = lpSurface; 521 522 /* Grab the masks from the surface description */ 523 pScreenPriv->dwRedMask = ddsdShadow.u4.ddpfPixelFormat.u2.dwRBitMask; 524 pScreenPriv->dwGreenMask = ddsdShadow.u4.ddpfPixelFormat.u3.dwGBitMask; 525 pScreenPriv->dwBlueMask = ddsdShadow.u4.ddpfPixelFormat.u4.dwBBitMask; 526 527#if CYGDEBUG 528 winDebug ("winAllocateFBShadowDDNL - Returning\n"); 529#endif 530 531 return TRUE; 532} 533 534static void 535winFreeFBShadowDDNL(ScreenPtr pScreen) 536{ 537 winScreenPriv(pScreen); 538 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 539 540 /* Free the shadow surface, if there is one */ 541 if (pScreenPriv->pddsShadow4) 542 { 543 IDirectDrawSurface4_Release (pScreenPriv->pddsShadow4); 544 free (pScreenInfo->pfb); 545 pScreenInfo->pfb = NULL; 546 pScreenPriv->pddsShadow4 = NULL; 547 } 548 549 /* Detach the clipper from the primary surface and release the primary surface, if there is one */ 550 winReleasePrimarySurfaceShadowDDNL(pScreen); 551 552 /* Release the clipper object */ 553 if (pScreenPriv->pddcPrimary) 554 { 555 IDirectDrawClipper_Release (pScreenPriv->pddcPrimary); 556 pScreenPriv->pddcPrimary = NULL; 557 } 558 559 /* Free the DirectDraw4 object, if there is one */ 560 if (pScreenPriv->pdd4) 561 { 562 IDirectDraw4_RestoreDisplayMode (pScreenPriv->pdd4); 563 IDirectDraw4_Release (pScreenPriv->pdd4); 564 pScreenPriv->pdd4 = NULL; 565 } 566 567 /* Free the DirectDraw object, if there is one */ 568 if (pScreenPriv->pdd) 569 { 570 IDirectDraw_Release (pScreenPriv->pdd); 571 pScreenPriv->pdd = NULL; 572 } 573 574 /* Invalidate the ScreenInfo's fb pointer */ 575 pScreenInfo->pfb = NULL; 576} 577 578#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) 579/* 580 * Create a DirectDraw surface for the new multi-window window 581 */ 582 583static 584Bool 585winFinishCreateWindowsWindowDDNL (WindowPtr pWin) 586{ 587 winWindowPriv(pWin); 588 winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv; 589 HRESULT ddrval = DD_OK; 590 DDSURFACEDESC2 ddsd; 591 int iWidth, iHeight; 592 int iX, iY; 593 594 winDebug ("winFinishCreateWindowsWindowDDNL!\n\n"); 595 596 iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); 597 iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); 598 599 iWidth = pWin->drawable.width; 600 iHeight = pWin->drawable.height; 601 602 /* Describe the primary surface */ 603 ZeroMemory (&ddsd, sizeof (ddsd)); 604 ddsd.dwSize = sizeof (ddsd); 605 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; 606 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; 607 ddsd.dwHeight = iHeight; 608 ddsd.dwWidth = iWidth; 609 610 /* Create the primary surface */ 611 ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4, 612 &ddsd, 613 &pWinPriv->pddsPrimary4, 614 NULL); 615 if (FAILED (ddrval)) 616 { 617 ErrorF ("winFinishCreateWindowsWindowDDNL - Could not create primary " 618 "surface: %08x\n", 619 (unsigned int)ddrval); 620 return FALSE; 621 } 622 return TRUE; 623} 624#endif 625 626 627/* 628 * Transfer the damaged regions of the shadow framebuffer to the display. 629 */ 630 631static void 632winShadowUpdateDDNL (ScreenPtr pScreen, 633 shadowBufPtr pBuf) 634{ 635 winScreenPriv(pScreen); 636 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 637 RegionPtr damage = shadowDamage(pBuf); 638 HRESULT ddrval = DD_OK; 639 RECT rcDest, rcSrc; 640 POINT ptOrigin; 641 DWORD dwBox = RegionNumRects (damage); 642 BoxPtr pBox = RegionRects (damage); 643 HRGN hrgnTemp = NULL, hrgnCombined = NULL; 644 645 /* 646 * Return immediately if the app is not active 647 * and we are fullscreen, or if we have a bad display depth 648 */ 649 if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) 650 || pScreenPriv->fBadDepth) return; 651 652 /* Return immediately if we didn't get needed surfaces */ 653 if (!pScreenPriv->pddsPrimary4 || !pScreenPriv->pddsShadow4) 654 return; 655 656 /* Get the origin of the window in the screen coords */ 657 ptOrigin.x = pScreenInfo->dwXOffset; 658 ptOrigin.y = pScreenInfo->dwYOffset; 659 MapWindowPoints (pScreenPriv->hwndScreen, 660 HWND_DESKTOP, 661 (LPPOINT)&ptOrigin, 1); 662 663 /* 664 * Handle small regions with multiple blits, 665 * handle large regions by creating a clipping region and 666 * doing a single blit constrained to that clipping region. 667 */ 668 if (pScreenInfo->dwClipUpdatesNBoxes == 0 669 || dwBox < pScreenInfo->dwClipUpdatesNBoxes) 670 { 671 /* Loop through all boxes in the damaged region */ 672 while (dwBox--) 673 { 674 /* Assign damage box to source rectangle */ 675 rcSrc.left = pBox->x1; 676 rcSrc.top = pBox->y1; 677 rcSrc.right = pBox->x2; 678 rcSrc.bottom = pBox->y2; 679 680 /* Calculate destination rectangle */ 681 rcDest.left = ptOrigin.x + rcSrc.left; 682 rcDest.top = ptOrigin.y + rcSrc.top; 683 rcDest.right = ptOrigin.x + rcSrc.right; 684 rcDest.bottom = ptOrigin.y + rcSrc.bottom; 685 686 /* Blit the damaged areas */ 687 ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, 688 &rcDest, 689 pScreenPriv->pddsShadow4, 690 &rcSrc, 691 DDBLT_WAIT, 692 NULL); 693 if (FAILED (ddrval)) 694 { 695 static int s_iFailCount = 0; 696 697 if (s_iFailCount < FAIL_MSG_MAX_BLT) 698 { 699 ErrorF ("winShadowUpdateDDNL - IDirectDrawSurface4_Blt () " 700 "failed: %08x\n", 701 (unsigned int) ddrval); 702 703 ++s_iFailCount; 704 705 if (s_iFailCount == FAIL_MSG_MAX_BLT) 706 { 707 ErrorF ("winShadowUpdateDDNL - IDirectDrawSurface4_Blt " 708 "failure message maximum (%d) reached. No " 709 "more failure messages will be printed.\n", 710 FAIL_MSG_MAX_BLT); 711 } 712 } 713 } 714 715 /* Get a pointer to the next box */ 716 ++pBox; 717 } 718 } 719 else 720 { 721 BoxPtr pBoxExtents = RegionExtents(damage); 722 723 /* Compute a GDI region from the damaged region */ 724 hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); 725 dwBox--; 726 pBox++; 727 while (dwBox--) 728 { 729 hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); 730 CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); 731 DeleteObject (hrgnTemp); 732 pBox++; 733 } 734 735 /* Install the GDI region as a clipping region */ 736 SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); 737 DeleteObject (hrgnCombined); 738 hrgnCombined = NULL; 739 740#if CYGDEBUG 741 winDebug ("winShadowUpdateDDNL - be x1 %d y1 %d x2 %d y2 %d\n", 742 pBoxExtents->x1, pBoxExtents->y1, 743 pBoxExtents->x2, pBoxExtents->y2); 744#endif 745 746 /* Calculating a bounding box for the source is easy */ 747 rcSrc.left = pBoxExtents->x1; 748 rcSrc.top = pBoxExtents->y1; 749 rcSrc.right = pBoxExtents->x2; 750 rcSrc.bottom = pBoxExtents->y2; 751 752 /* Calculating a bounding box for the destination is trickier */ 753 rcDest.left = ptOrigin.x + rcSrc.left; 754 rcDest.top = ptOrigin.y + rcSrc.top; 755 rcDest.right = ptOrigin.x + rcSrc.right; 756 rcDest.bottom = ptOrigin.y + rcSrc.bottom; 757 758 /* Our Blt should be clipped to the invalidated region */ 759 ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, 760 &rcDest, 761 pScreenPriv->pddsShadow4, 762 &rcSrc, 763 DDBLT_WAIT, 764 NULL); 765 766 /* Reset the clip region */ 767 SelectClipRgn (pScreenPriv->hdcScreen, NULL); 768 } 769} 770 771static Bool 772winInitScreenShadowDDNL(ScreenPtr pScreen) 773{ 774 winScreenPriv(pScreen); 775 776 /* Get a device context for the screen */ 777 pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); 778 779 return winAllocateFBShadowDDNL(pScreen); 780} 781 782/* 783 * Call the wrapped CloseScreen function. 784 * 785 * Free our resources and private structures. 786 */ 787 788static Bool 789winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen) 790{ 791 winScreenPriv(pScreen); 792 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 793 Bool fReturn; 794 795#if CYGDEBUG 796 winDebug ("winCloseScreenShadowDDNL - Freeing screen resources\n"); 797#endif 798 799 /* Flag that the screen is closed */ 800 pScreenPriv->fClosed = TRUE; 801 pScreenPriv->fActive = FALSE; 802 803 /* Call the wrapped CloseScreen procedure */ 804 WIN_UNWRAP(CloseScreen); 805 fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); 806 807 winFreeFBShadowDDNL(pScreen); 808 809 /* Free the screen DC */ 810 ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); 811 812 /* Delete the window property */ 813 RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); 814 815 /* Delete tray icon, if we have one */ 816 if (!pScreenInfo->fNoTrayIcon) 817 winDeleteNotifyIcon (pScreenPriv); 818 819 /* Free the exit confirmation dialog box, if it exists */ 820 if (g_hDlgExit != NULL) 821 { 822 DestroyWindow (g_hDlgExit); 823 g_hDlgExit = NULL; 824 } 825 826 /* Kill our window */ 827 if (pScreenPriv->hwndScreen) 828 { 829 DestroyWindow (pScreenPriv->hwndScreen); 830 pScreenPriv->hwndScreen = NULL; 831 } 832 833#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) 834 /* Destroy the thread startup mutex */ 835 pthread_mutex_destroy (&pScreenPriv->pmServerStarted); 836#endif 837 838 /* Kill our screeninfo's pointer to the screen */ 839 pScreenInfo->pScreen = NULL; 840 841 /* Free the screen privates for this screen */ 842 free ((pointer) pScreenPriv); 843 844 return fReturn; 845} 846 847 848/* 849 * Tell mi what sort of visuals we need. 850 * 851 * Generally we only need one visual, as our screen can only 852 * handle one format at a time, I believe. You may want 853 * to verify that last sentence. 854 */ 855 856static Bool 857winInitVisualsShadowDDNL (ScreenPtr pScreen) 858{ 859 winScreenPriv(pScreen); 860 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 861 DWORD dwRedBits, dwGreenBits, dwBlueBits; 862 863 /* Count the number of ones in each color mask */ 864 dwRedBits = winCountBits (pScreenPriv->dwRedMask); 865 dwGreenBits = winCountBits (pScreenPriv->dwGreenMask); 866 dwBlueBits = winCountBits (pScreenPriv->dwBlueMask); 867 868 /* Store the maximum number of ones in a color mask as the bitsPerRGB */ 869 if (dwRedBits == 0 || dwGreenBits == 0 || dwBlueBits == 0) 870 pScreenPriv->dwBitsPerRGB = 8; 871 else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) 872 pScreenPriv->dwBitsPerRGB = dwRedBits; 873 else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) 874 pScreenPriv->dwBitsPerRGB = dwGreenBits; 875 else 876 pScreenPriv->dwBitsPerRGB = dwBlueBits; 877 878 winDebug ("winInitVisualsShadowDDNL - Masks %08x %08x %08x BPRGB %d d %d " 879 "bpp %d\n", 880 (unsigned int) pScreenPriv->dwRedMask, 881 (unsigned int) pScreenPriv->dwGreenMask, 882 (unsigned int) pScreenPriv->dwBlueMask, 883 (int) pScreenPriv->dwBitsPerRGB, 884 (int) pScreenInfo->dwDepth, 885 (int) pScreenInfo->dwBPP); 886 887 /* Create a single visual according to the Windows screen depth */ 888 switch (pScreenInfo->dwDepth) 889 { 890 case 24: 891 case 16: 892 case 15: 893 /* Setup the real visual */ 894 if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, 895 TrueColorMask, 896 pScreenPriv->dwBitsPerRGB, 897 -1, 898 pScreenPriv->dwRedMask, 899 pScreenPriv->dwGreenMask, 900 pScreenPriv->dwBlueMask)) 901 { 902 ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks " 903 "failed for TrueColor\n"); 904 return FALSE; 905 } 906 907#ifdef XWIN_EMULATEPSEUDO 908 if (!pScreenInfo->fEmulatePseudo) 909 break; 910 911 /* Setup a pseudocolor visual */ 912 if (!miSetVisualTypesAndMasks (8, 913 PseudoColorMask, 914 8, 915 -1, 916 0, 917 0, 918 0)) 919 { 920 ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks " 921 "failed for PseudoColor\n"); 922 return FALSE; 923 } 924#endif 925 break; 926 927 case 8: 928 if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, 929 pScreenInfo->fFullScreen 930 ? PseudoColorMask : StaticColorMask, 931 pScreenPriv->dwBitsPerRGB, 932 pScreenInfo->fFullScreen 933 ? PseudoColor : StaticColor, 934 pScreenPriv->dwRedMask, 935 pScreenPriv->dwGreenMask, 936 pScreenPriv->dwBlueMask)) 937 { 938 ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks " 939 "failed\n"); 940 return FALSE; 941 } 942 break; 943 944 default: 945 ErrorF ("winInitVisualsShadowDDNL - Unknown screen depth\n"); 946 return FALSE; 947 } 948 949#if CYGDEBUG 950 winDebug ("winInitVisualsShadowDDNL - Returning\n"); 951#endif 952 953 return TRUE; 954} 955 956 957/* 958 * Adjust the user proposed video mode 959 */ 960 961static Bool 962winAdjustVideoModeShadowDDNL (ScreenPtr pScreen) 963{ 964 winScreenPriv(pScreen); 965 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 966 HDC hdc = NULL; 967 DWORD dwBPP; 968 969 /* We're in serious trouble if we can't get a DC */ 970 hdc = GetDC (NULL); 971 if (hdc == NULL) 972 { 973 ErrorF ("winAdjustVideoModeShadowDDNL - GetDC () failed\n"); 974 return FALSE; 975 } 976 977 /* Query GDI for current display depth */ 978 dwBPP = GetDeviceCaps (hdc, BITSPIXEL); 979 980 /* DirectDraw can only change the depth in fullscreen mode */ 981 if (!(pScreenInfo->fFullScreen && 982 (pScreenInfo->dwBPP != WIN_DEFAULT_BPP))) 983 { 984 /* Otherwise, We'll use GDI's depth */ 985 pScreenInfo->dwBPP = dwBPP; 986 } 987 988 /* Release our DC */ 989 ReleaseDC (NULL, hdc); 990 991 return TRUE; 992} 993 994 995/* 996 * Blt exposed regions to the screen 997 */ 998 999static Bool 1000winBltExposedRegionsShadowDDNL (ScreenPtr pScreen) 1001{ 1002 winScreenPriv(pScreen); 1003 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 1004 RECT rcSrc, rcDest; 1005 POINT ptOrigin; 1006 HDC hdcUpdate; 1007 PAINTSTRUCT ps; 1008 HRESULT ddrval = DD_OK; 1009 Bool fReturn = TRUE; 1010 int i; 1011 1012 /* Quite common case. The primary surface was lost (maybe because of depth 1013 * change). Try to create a new primary surface. Bail out if this fails */ 1014 if (pScreenPriv->pddsPrimary4 == NULL && pScreenPriv->fRetryCreateSurface && 1015 !winCreatePrimarySurfaceShadowDDNL(pScreen)) 1016 { 1017 Sleep(100); 1018 return FALSE; 1019 } 1020 if (pScreenPriv->pddsPrimary4 == NULL) 1021 return FALSE; 1022 1023 /* BeginPaint gives us an hdc that clips to the invalidated region */ 1024 hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps); 1025 if (hdcUpdate == NULL) 1026 { 1027 fReturn = FALSE; 1028 ErrorF ("winBltExposedRegionsShadowDDNL - BeginPaint () returned " 1029 "a NULL device context handle. Aborting blit attempt.\n"); 1030 goto winBltExposedRegionsShadowDDNL_Exit; 1031 } 1032 1033 /* Get the origin of the window in the screen coords */ 1034 ptOrigin.x = pScreenInfo->dwXOffset; 1035 ptOrigin.y = pScreenInfo->dwYOffset; 1036 1037 MapWindowPoints (pScreenPriv->hwndScreen, 1038 HWND_DESKTOP, 1039 (LPPOINT)&ptOrigin, 1); 1040 rcDest.left = ptOrigin.x; 1041 rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; 1042 rcDest.top = ptOrigin.y; 1043 rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; 1044 1045 /* Source can be entire shadow surface, as Blt should clip for us */ 1046 rcSrc.left = 0; 1047 rcSrc.top = 0; 1048 rcSrc.right = pScreenInfo->dwWidth; 1049 rcSrc.bottom = pScreenInfo->dwHeight; 1050 1051 /* Try to regain the primary surface and blit again if we've lost it */ 1052 for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) 1053 { 1054 /* Our Blt should be clipped to the invalidated region */ 1055 ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, 1056 &rcDest, 1057 pScreenPriv->pddsShadow4, 1058 &rcSrc, 1059 DDBLT_WAIT, 1060 NULL); 1061 if (ddrval == DDERR_SURFACELOST) 1062 { 1063 /* Surface was lost */ 1064 winErrorFVerb (1, "winBltExposedRegionsShadowDDNL - " 1065 "IDirectDrawSurface4_Blt reported that the primary " 1066 "surface was lost, trying to restore, retry: %d\n", i + 1); 1067 1068 /* Try to restore the surface, once */ 1069 1070 ddrval = IDirectDrawSurface4_Restore (pScreenPriv->pddsPrimary4); 1071 winDebug ("winBltExposedRegionsShadowDDNL - " 1072 "IDirectDrawSurface4_Restore returned: "); 1073 if (ddrval == DD_OK) 1074 winDebug ("DD_OK\n"); 1075 else if (ddrval == DDERR_WRONGMODE) 1076 winDebug ("DDERR_WRONGMODE\n"); 1077 else if (ddrval == DDERR_INCOMPATIBLEPRIMARY) 1078 winDebug ("DDERR_INCOMPATIBLEPRIMARY\n"); 1079 else if (ddrval == DDERR_UNSUPPORTED) 1080 winDebug ("DDERR_UNSUPPORTED\n"); 1081 else if (ddrval == DDERR_INVALIDPARAMS) 1082 winDebug ("DDERR_INVALIDPARAMS\n"); 1083 else if (ddrval == DDERR_INVALIDOBJECT) 1084 winDebug ("DDERR_INVALIDOBJECT\n"); 1085 else 1086 winDebug ("unknown error: %08x\n", (unsigned int) ddrval); 1087 1088 /* Loop around to try the blit one more time */ 1089 continue; 1090 } 1091 else if (FAILED (ddrval)) 1092 { 1093 fReturn = FALSE; 1094 winErrorFVerb (1, "winBltExposedRegionsShadowDDNL - " 1095 "IDirectDrawSurface4_Blt failed, but surface not " 1096 "lost: %08x %d\n", 1097 (unsigned int) ddrval, (int) ddrval); 1098 goto winBltExposedRegionsShadowDDNL_Exit; 1099 } 1100 else 1101 { 1102 /* Success, stop looping */ 1103 break; 1104 } 1105 } 1106 1107 winBltExposedRegionsShadowDDNL_Exit: 1108 /* EndPaint frees the DC */ 1109 if (hdcUpdate != NULL) 1110 EndPaint (pScreenPriv->hwndScreen, &ps); 1111 return fReturn; 1112} 1113 1114 1115/* 1116 * Do any engine-specific application-activation processing 1117 */ 1118 1119static Bool 1120winActivateAppShadowDDNL (ScreenPtr pScreen) 1121{ 1122 winScreenPriv(pScreen); 1123 1124 /* 1125 * Do we have a surface? 1126 * Are we active? 1127 * Are we full screen? 1128 */ 1129 if (pScreenPriv != NULL 1130 && pScreenPriv->pddsPrimary4 != NULL 1131 && pScreenPriv->fActive) 1132 { 1133 /* Primary surface was lost, restore it */ 1134 IDirectDrawSurface4_Restore (pScreenPriv->pddsPrimary4); 1135 } 1136 1137 return TRUE; 1138} 1139 1140 1141/* 1142 * Reblit the shadow framebuffer to the screen. 1143 */ 1144 1145static Bool 1146winRedrawScreenShadowDDNL (ScreenPtr pScreen) 1147{ 1148 winScreenPriv(pScreen); 1149 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 1150 HRESULT ddrval = DD_OK; 1151 RECT rcSrc, rcDest; 1152 POINT ptOrigin; 1153 1154 /* Get the origin of the window in the screen coords */ 1155 ptOrigin.x = pScreenInfo->dwXOffset; 1156 ptOrigin.y = pScreenInfo->dwYOffset; 1157 MapWindowPoints (pScreenPriv->hwndScreen, 1158 HWND_DESKTOP, 1159 (LPPOINT)&ptOrigin, 1); 1160 rcDest.left = ptOrigin.x; 1161 rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; 1162 rcDest.top = ptOrigin.y; 1163 rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; 1164 1165 /* Source can be entire shadow surface, as Blt should clip for us */ 1166 rcSrc.left = 0; 1167 rcSrc.top = 0; 1168 rcSrc.right = pScreenInfo->dwWidth; 1169 rcSrc.bottom = pScreenInfo->dwHeight; 1170 1171 /* Redraw the whole window, to take account for the new colors */ 1172 ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, 1173 &rcDest, 1174 pScreenPriv->pddsShadow4, 1175 &rcSrc, 1176 DDBLT_WAIT, 1177 NULL); 1178 if (FAILED (ddrval)) 1179 { 1180 ErrorF ("winRedrawScreenShadowDDNL - IDirectDrawSurface4_Blt () " 1181 "failed: %08x\n", 1182 (unsigned int) ddrval); 1183 } 1184 1185 return TRUE; 1186} 1187 1188 1189/* 1190 * Realize the currently installed colormap 1191 */ 1192 1193static Bool 1194winRealizeInstalledPaletteShadowDDNL (ScreenPtr pScreen) 1195{ 1196 return TRUE; 1197} 1198 1199 1200/* 1201 * Install the specified colormap 1202 */ 1203 1204static Bool 1205winInstallColormapShadowDDNL (ColormapPtr pColormap) 1206{ 1207 ScreenPtr pScreen = pColormap->pScreen; 1208 winScreenPriv(pScreen); 1209 winCmapPriv(pColormap); 1210 HRESULT ddrval = DD_OK; 1211 1212 /* Install the DirectDraw palette on the primary surface */ 1213 ddrval = IDirectDrawSurface4_SetPalette (pScreenPriv->pddsPrimary4, 1214 pCmapPriv->lpDDPalette); 1215 if (FAILED (ddrval)) 1216 { 1217 ErrorF ("winInstallColormapShadowDDNL - Failed installing the " 1218 "DirectDraw palette.\n"); 1219 return FALSE; 1220 } 1221 1222 /* Save a pointer to the newly installed colormap */ 1223 pScreenPriv->pcmapInstalled = pColormap; 1224 1225 return TRUE; 1226} 1227 1228 1229/* 1230 * Store the specified colors in the specified colormap 1231 */ 1232 1233static Bool 1234winStoreColorsShadowDDNL (ColormapPtr pColormap, 1235 int ndef, 1236 xColorItem *pdefs) 1237{ 1238 ScreenPtr pScreen = pColormap->pScreen; 1239 winScreenPriv(pScreen); 1240 winCmapPriv(pColormap); 1241 ColormapPtr curpmap = pScreenPriv->pcmapInstalled; 1242 HRESULT ddrval = DD_OK; 1243 1244 /* Put the X colormap entries into the Windows logical palette */ 1245 ddrval = IDirectDrawPalette_SetEntries (pCmapPriv->lpDDPalette, 1246 0, 1247 pdefs[0].pixel, 1248 ndef, 1249 pCmapPriv->peColors 1250 + pdefs[0].pixel); 1251 if (FAILED (ddrval)) 1252 { 1253 ErrorF ("winStoreColorsShadowDDNL - SetEntries () failed: %08x\n", (unsigned int) ddrval); 1254 return FALSE; 1255 } 1256 1257 /* Don't install the DirectDraw palette if the colormap is not installed */ 1258 if (pColormap != curpmap) 1259 { 1260 return TRUE; 1261 } 1262 1263 if (!winInstallColormapShadowDDNL (pColormap)) 1264 { 1265 ErrorF ("winStoreColorsShadowDDNL - Failed installing colormap\n"); 1266 return FALSE; 1267 } 1268 1269 return TRUE; 1270} 1271 1272 1273/* 1274 * Colormap initialization procedure 1275 */ 1276 1277static Bool 1278winCreateColormapShadowDDNL (ColormapPtr pColormap) 1279{ 1280 HRESULT ddrval = DD_OK; 1281 ScreenPtr pScreen = pColormap->pScreen; 1282 winScreenPriv(pScreen); 1283 winCmapPriv(pColormap); 1284 1285 /* Create a DirectDraw palette */ 1286 ddrval = IDirectDraw4_CreatePalette (pScreenPriv->pdd4, 1287 DDPCAPS_8BIT | DDPCAPS_ALLOW256, 1288 pCmapPriv->peColors, 1289 &pCmapPriv->lpDDPalette, 1290 NULL); 1291 if (FAILED (ddrval)) 1292 { 1293 ErrorF ("winCreateColormapShadowDDNL - CreatePalette failed\n"); 1294 return FALSE; 1295 } 1296 1297 return TRUE; 1298} 1299 1300 1301/* 1302 * Colormap destruction procedure 1303 */ 1304 1305static Bool 1306winDestroyColormapShadowDDNL (ColormapPtr pColormap) 1307{ 1308 winScreenPriv(pColormap->pScreen); 1309 winCmapPriv(pColormap); 1310 HRESULT ddrval = DD_OK; 1311 1312 /* 1313 * Is colormap to be destroyed the default? 1314 * 1315 * Non-default colormaps should have had winUninstallColormap 1316 * called on them before we get here. The default colormap 1317 * will not have had winUninstallColormap called on it. Thus, 1318 * we need to handle the default colormap in a special way. 1319 */ 1320 if (pColormap->flags & IsDefault) 1321 { 1322#if CYGDEBUG 1323 winDebug ("winDestroyColormapShadowDDNL - Destroying default colormap\n"); 1324#endif 1325 1326 /* 1327 * FIXME: Walk the list of all screens, popping the default 1328 * palette out of each screen device context. 1329 */ 1330 1331 /* Pop the palette out of the primary surface */ 1332 ddrval = IDirectDrawSurface4_SetPalette (pScreenPriv->pddsPrimary4, 1333 NULL); 1334 if (FAILED (ddrval)) 1335 { 1336 ErrorF ("winDestroyColormapShadowDDNL - Failed freeing the " 1337 "default colormap DirectDraw palette.\n"); 1338 return FALSE; 1339 } 1340 1341 /* Clear our private installed colormap pointer */ 1342 pScreenPriv->pcmapInstalled = NULL; 1343 } 1344 1345 /* Release the palette */ 1346 IDirectDrawPalette_Release (pCmapPriv->lpDDPalette); 1347 1348 /* Invalidate the colormap privates */ 1349 pCmapPriv->lpDDPalette = NULL; 1350 1351 return TRUE; 1352} 1353 1354 1355/* 1356 * Set pointers to our engine specific functions 1357 */ 1358 1359Bool 1360winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen) 1361{ 1362 winScreenPriv(pScreen); 1363 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 1364 1365 /* Set our pointers */ 1366 pScreenPriv->pwinAllocateFB = winAllocateFBShadowDDNL; 1367 pScreenPriv->pwinFreeFB = winFreeFBShadowDDNL; 1368 pScreenPriv->pwinShadowUpdate = winShadowUpdateDDNL; 1369 pScreenPriv->pwinInitScreen = winInitScreenShadowDDNL; 1370 pScreenPriv->pwinCloseScreen = winCloseScreenShadowDDNL; 1371 pScreenPriv->pwinInitVisuals = winInitVisualsShadowDDNL; 1372 pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDDNL; 1373 if (pScreenInfo->fFullScreen) 1374 pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; 1375 else 1376 pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; 1377 pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; 1378 pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDDNL; 1379 pScreenPriv->pwinActivateApp = winActivateAppShadowDDNL; 1380 pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDDNL; 1381 pScreenPriv->pwinRealizeInstalledPalette 1382 = winRealizeInstalledPaletteShadowDDNL; 1383 pScreenPriv->pwinInstallColormap = winInstallColormapShadowDDNL; 1384 pScreenPriv->pwinStoreColors = winStoreColorsShadowDDNL; 1385 pScreenPriv->pwinCreateColormap = winCreateColormapShadowDDNL; 1386 pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDDNL; 1387 pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA; 1388 pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDDNL; 1389 pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDDNL; 1390#ifdef XWIN_MULTIWINDOW 1391 pScreenPriv->pwinFinishCreateWindowsWindow 1392 = winFinishCreateWindowsWindowDDNL; 1393#endif 1394 1395 return TRUE; 1396} 1397