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