xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

winshadddnl.c (41065B)


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