xserver

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

winshadgdi.c (40699B)


      1 /*
      2  *Copyright (C) 2001-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 Harold L Hunt II
     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 Harold L Hunt II.
     27  *
     28  * Authors:	Harold L Hunt II
     29  */
     30 
     31 #ifdef HAVE_XWIN_CONFIG_H
     32 #include <xwin-config.h>
     33 #endif
     34 #include "win.h"
     35 
     36 /*
     37  * Local function prototypes
     38  */
     39 
     40 static wBOOL CALLBACK winRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam);
     41 
     42 static wBOOL CALLBACK winRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam);
     43 
     44 static Bool
     45  winAllocateFBShadowGDI(ScreenPtr pScreen);
     46 
     47 static void
     48  winShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf);
     49 
     50 static Bool
     51  winCloseScreenShadowGDI(ScreenPtr pScreen);
     52 
     53 static Bool
     54  winInitVisualsShadowGDI(ScreenPtr pScreen);
     55 
     56 static Bool
     57  winAdjustVideoModeShadowGDI(ScreenPtr pScreen);
     58 
     59 static Bool
     60  winBltExposedRegionsShadowGDI(ScreenPtr pScreen);
     61 
     62 static Bool
     63  winBltExposedWindowRegionShadowGDI(ScreenPtr pScreen, WindowPtr pWin);
     64 
     65 static Bool
     66  winActivateAppShadowGDI(ScreenPtr pScreen);
     67 
     68 static Bool
     69  winRedrawScreenShadowGDI(ScreenPtr pScreen);
     70 
     71 static Bool
     72  winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen);
     73 
     74 static Bool
     75  winInstallColormapShadowGDI(ColormapPtr pColormap);
     76 
     77 static Bool
     78  winStoreColorsShadowGDI(ColormapPtr pmap, int ndef, xColorItem * pdefs);
     79 
     80 static Bool
     81  winCreateColormapShadowGDI(ColormapPtr pColormap);
     82 
     83 static Bool
     84  winDestroyColormapShadowGDI(ColormapPtr pColormap);
     85 
     86 /*
     87  * Internal function to get the DIB format that is compatible with the screen
     88  */
     89 
     90 static
     91     Bool
     92 winQueryScreenDIBFormat(ScreenPtr pScreen, BITMAPINFOHEADER * pbmih)
     93 {
     94     winScreenPriv(pScreen);
     95     HBITMAP hbmp;
     96 
     97 #if CYGDEBUG
     98     LPDWORD pdw = NULL;
     99 #endif
    100 
    101     /* Create a memory bitmap compatible with the screen */
    102     hbmp = CreateCompatibleBitmap(pScreenPriv->hdcScreen, 1, 1);
    103     if (hbmp == NULL) {
    104         ErrorF("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n");
    105         return FALSE;
    106     }
    107 
    108     /* Initialize our bitmap info header */
    109     ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
    110     pbmih->biSize = sizeof(BITMAPINFOHEADER);
    111 
    112     /* Get the biBitCount */
    113     if (!GetDIBits(pScreenPriv->hdcScreen,
    114                    hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) {
    115         ErrorF("winQueryScreenDIBFormat - First call to GetDIBits failed\n");
    116         DeleteObject(hbmp);
    117         return FALSE;
    118     }
    119 
    120 #if CYGDEBUG
    121     /* Get a pointer to bitfields */
    122     pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER));
    123 
    124     winDebug("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n",
    125              (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]);
    126 #endif
    127 
    128     /* Get optimal color table, or the optimal bitfields */
    129     if (!GetDIBits(pScreenPriv->hdcScreen,
    130                    hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) {
    131         ErrorF("winQueryScreenDIBFormat - Second call to GetDIBits "
    132                "failed\n");
    133         DeleteObject(hbmp);
    134         return FALSE;
    135     }
    136 
    137     /* Free memory */
    138     DeleteObject(hbmp);
    139 
    140     return TRUE;
    141 }
    142 
    143 /*
    144  * Internal function to determine the GDI bits per rgb and bit masks
    145  */
    146 
    147 static
    148     Bool
    149 winQueryRGBBitsAndMasks(ScreenPtr pScreen)
    150 {
    151     winScreenPriv(pScreen);
    152     BITMAPINFOHEADER *pbmih = NULL;
    153     Bool fReturn = TRUE;
    154     LPDWORD pdw = NULL;
    155     DWORD dwRedBits, dwGreenBits, dwBlueBits;
    156 
    157     /* Color masks for 8 bpp are standardized */
    158     if (GetDeviceCaps(pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) {
    159         /*
    160          * RGB BPP for 8 bit palletes is always 8
    161          * and the color masks are always 0.
    162          */
    163         pScreenPriv->dwBitsPerRGB = 8;
    164         pScreenPriv->dwRedMask = 0x0L;
    165         pScreenPriv->dwGreenMask = 0x0L;
    166         pScreenPriv->dwBlueMask = 0x0L;
    167         return TRUE;
    168     }
    169 
    170     /* Color masks for 24 bpp are standardized */
    171     if (GetDeviceCaps(pScreenPriv->hdcScreen, PLANES)
    172         * GetDeviceCaps(pScreenPriv->hdcScreen, BITSPIXEL) == 24) {
    173         ErrorF("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) "
    174                "returned 24 for the screen.  Using default 24bpp masks.\n");
    175 
    176         /* 8 bits per primary color */
    177         pScreenPriv->dwBitsPerRGB = 8;
    178 
    179         /* Set screen privates masks */
    180         pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED;
    181         pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN;
    182         pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE;
    183 
    184         return TRUE;
    185     }
    186 
    187     /* Allocate a bitmap header and color table */
    188     pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
    189     if (pbmih == NULL) {
    190         ErrorF("winQueryRGBBitsAndMasks - malloc failed\n");
    191         return FALSE;
    192     }
    193 
    194     /* Get screen description */
    195     if (winQueryScreenDIBFormat(pScreen, pbmih)) {
    196         /* Get a pointer to bitfields */
    197         pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER));
    198 
    199 #if CYGDEBUG
    200         winDebug("%s - Masks: %08x %08x %08x\n", __FUNCTION__,
    201                  (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]);
    202         winDebug("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__,
    203                  (int)pbmih->biWidth, (int)pbmih->biHeight, pbmih->biBitCount,
    204                  pbmih->biPlanes);
    205         winDebug("%s - Compression: %u %s\n", __FUNCTION__,
    206                  (unsigned int)pbmih->biCompression,
    207                  (pbmih->biCompression ==
    208                   BI_RGB ? "(BI_RGB)" : (pbmih->biCompression ==
    209                                          BI_RLE8 ? "(BI_RLE8)" : (pbmih->
    210                                                                   biCompression
    211                                                                   ==
    212                                                                   BI_RLE4 ?
    213                                                                   "(BI_RLE4)"
    214                                                                   : (pbmih->
    215                                                                      biCompression
    216                                                                      ==
    217                                                                      BI_BITFIELDS
    218                                                                      ?
    219                                                                      "(BI_BITFIELDS)"
    220                                                                      : "")))));
    221 #endif
    222 
    223         /* Handle BI_RGB case, which is returned by Wine */
    224         if (pbmih->biCompression == BI_RGB) {
    225             dwRedBits = 5;
    226             dwGreenBits = 5;
    227             dwBlueBits = 5;
    228 
    229             pScreenPriv->dwBitsPerRGB = 5;
    230 
    231             /* Set screen privates masks */
    232             pScreenPriv->dwRedMask = 0x7c00;
    233             pScreenPriv->dwGreenMask = 0x03e0;
    234             pScreenPriv->dwBlueMask = 0x001f;
    235         }
    236         else {
    237             /* Count the number of bits in each mask */
    238             dwRedBits = winCountBits(pdw[0]);
    239             dwGreenBits = winCountBits(pdw[1]);
    240             dwBlueBits = winCountBits(pdw[2]);
    241 
    242             /* Find maximum bits per red, green, blue */
    243             if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
    244                 pScreenPriv->dwBitsPerRGB = dwRedBits;
    245             else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
    246                 pScreenPriv->dwBitsPerRGB = dwGreenBits;
    247             else
    248                 pScreenPriv->dwBitsPerRGB = dwBlueBits;
    249 
    250             /* Set screen privates masks */
    251             pScreenPriv->dwRedMask = pdw[0];
    252             pScreenPriv->dwGreenMask = pdw[1];
    253             pScreenPriv->dwBlueMask = pdw[2];
    254         }
    255     }
    256     else {
    257         ErrorF("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n");
    258         fReturn = FALSE;
    259     }
    260 
    261     /* Free memory */
    262     free(pbmih);
    263 
    264     return fReturn;
    265 }
    266 
    267 /*
    268  * Redraw all ---?
    269  */
    270 
    271 static wBOOL CALLBACK
    272 winRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam)
    273 {
    274     if (hwnd == (HWND) lParam)
    275         return TRUE;
    276     InvalidateRect(hwnd, NULL, FALSE);
    277     UpdateWindow(hwnd);
    278     return TRUE;
    279 }
    280 
    281 static wBOOL CALLBACK
    282 winRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam)
    283 {
    284     BoxPtr pDamage = (BoxPtr) lParam;
    285     RECT rcClient, rcDamage, rcRedraw;
    286     POINT topLeft, bottomRight;
    287 
    288     if (IsIconic(hwnd))
    289         return TRUE;            /* Don't care minimized windows */
    290 
    291     /* Convert the damaged area from Screen coords to Client coords */
    292     topLeft.x = pDamage->x1;
    293     topLeft.y = pDamage->y1;
    294     bottomRight.x = pDamage->x2;
    295     bottomRight.y = pDamage->y2;
    296     topLeft.x += GetSystemMetrics(SM_XVIRTUALSCREEN);
    297     bottomRight.x += GetSystemMetrics(SM_XVIRTUALSCREEN);
    298     topLeft.y += GetSystemMetrics(SM_YVIRTUALSCREEN);
    299     bottomRight.y += GetSystemMetrics(SM_YVIRTUALSCREEN);
    300     ScreenToClient(hwnd, &topLeft);
    301     ScreenToClient(hwnd, &bottomRight);
    302     SetRect(&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
    303 
    304     GetClientRect(hwnd, &rcClient);
    305 
    306     if (IntersectRect(&rcRedraw, &rcClient, &rcDamage)) {
    307         InvalidateRect(hwnd, &rcRedraw, FALSE);
    308         UpdateWindow(hwnd);
    309     }
    310     return TRUE;
    311 }
    312 
    313 /*
    314  * Allocate a DIB for the shadow framebuffer GDI server
    315  */
    316 
    317 static Bool
    318 winAllocateFBShadowGDI(ScreenPtr pScreen)
    319 {
    320     winScreenPriv(pScreen);
    321     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
    322     DIBSECTION dibsection;
    323     Bool fReturn = TRUE;
    324 
    325     /* Describe shadow bitmap to be created */
    326     pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth;
    327     pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight;
    328 
    329     ErrorF("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d "
    330            "depth: %d\n",
    331            (int) pScreenPriv->pbmih->biWidth,
    332            (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount);
    333 
    334     /* Create a DI shadow bitmap with a bit pointer */
    335     pScreenPriv->hbmpShadow = CreateDIBSection(pScreenPriv->hdcScreen,
    336                                                (BITMAPINFO *) pScreenPriv->
    337                                                pbmih, DIB_RGB_COLORS,
    338                                                (VOID **) &pScreenInfo->pfb,
    339                                                NULL, 0);
    340     if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) {
    341         winW32Error(2, "winAllocateFBShadowGDI - CreateDIBSection failed:");
    342         return FALSE;
    343     }
    344     else {
    345 #if CYGDEBUG
    346         winDebug("winAllocateFBShadowGDI - Shadow buffer allocated\n");
    347 #endif
    348     }
    349 
    350     /* Get information about the bitmap that was allocated */
    351     GetObject(pScreenPriv->hbmpShadow, sizeof(dibsection), &dibsection);
    352 
    353 #if CYGDEBUG || YES
    354     /* Print information about bitmap allocated */
    355     winDebug("winAllocateFBShadowGDI - Dibsection width: %d height: %d "
    356              "depth: %d size image: %d\n",
    357              (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight,
    358              dibsection.dsBmih.biBitCount, (int) dibsection.dsBmih.biSizeImage);
    359 #endif
    360 
    361     /* Select the shadow bitmap into the shadow DC */
    362     SelectObject(pScreenPriv->hdcShadow, pScreenPriv->hbmpShadow);
    363 
    364 #if CYGDEBUG
    365     winDebug("winAllocateFBShadowGDI - Attempting a shadow blit\n");
    366 #endif
    367 
    368     /* Do a test blit from the shadow to the screen, I think */
    369     fReturn = BitBlt(pScreenPriv->hdcScreen,
    370                      0, 0,
    371                      pScreenInfo->dwWidth, pScreenInfo->dwHeight,
    372                      pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
    373     if (fReturn) {
    374 #if CYGDEBUG
    375         winDebug("winAllocateFBShadowGDI - Shadow blit success\n");
    376 #endif
    377     }
    378     else {
    379         winW32Error(2, "winAllocateFBShadowGDI - Shadow blit failure\n");
    380 #if 0
    381         return FALSE;
    382 #else
    383         /* ago: ignore this error. The blit fails with wine, but does not
    384          * cause any problems later. */
    385 
    386         fReturn = TRUE;
    387 #endif
    388     }
    389 
    390     /* Look for height weirdness */
    391     if (dibsection.dsBmih.biHeight < 0) {
    392         dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight;
    393     }
    394 
    395     /* Set screeninfo stride */
    396     pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage
    397                               / dibsection.dsBmih.biHeight)
    398                              * 8) / pScreenInfo->dwBPP;
    399 
    400 #if CYGDEBUG || YES
    401     winDebug("winAllocateFBShadowGDI - Created shadow stride: %d\n",
    402              (int) pScreenInfo->dwStride);
    403 #endif
    404 
    405     /* Redraw all windows */
    406     if (pScreenInfo->fMultiWindow)
    407         EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
    408 
    409     return fReturn;
    410 }
    411 
    412 static void
    413 winFreeFBShadowGDI(ScreenPtr pScreen)
    414 {
    415     winScreenPriv(pScreen);
    416     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
    417 
    418     /* Free the shadow bitmap */
    419     DeleteObject(pScreenPriv->hbmpShadow);
    420 
    421     /* Invalidate the ScreenInfo's fb pointer */
    422     pScreenInfo->pfb = NULL;
    423 }
    424 
    425 /*
    426  * Blit the damaged regions of the shadow fb to the screen
    427  */
    428 
    429 static void
    430 winShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf)
    431 {
    432     winScreenPriv(pScreen);
    433     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
    434     RegionPtr damage = DamageRegion(pBuf->pDamage);
    435     DWORD dwBox = RegionNumRects(damage);
    436     BoxPtr pBox = RegionRects(damage);
    437     int x, y, w, h;
    438     HRGN hrgnCombined = NULL;
    439 
    440 #ifdef XWIN_UPDATESTATS
    441     static DWORD s_dwNonUnitRegions = 0;
    442     static DWORD s_dwTotalUpdates = 0;
    443     static DWORD s_dwTotalBoxes = 0;
    444 #endif
    445     BoxPtr pBoxExtents = RegionExtents(damage);
    446 
    447     /*
    448      * Return immediately if the app is not active
    449      * and we are fullscreen, or if we have a bad display depth
    450      */
    451     if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
    452         || pScreenPriv->fBadDepth)
    453         return;
    454 
    455 #ifdef XWIN_UPDATESTATS
    456     ++s_dwTotalUpdates;
    457     s_dwTotalBoxes += dwBox;
    458 
    459     if (dwBox != 1) {
    460         ++s_dwNonUnitRegions;
    461         ErrorF("winShadowUpdatGDI - dwBox: %d\n", dwBox);
    462     }
    463 
    464     if ((s_dwTotalUpdates % 100) == 0)
    465         ErrorF("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d "
    466                "nu: %d tu: %d\n",
    467                (s_dwNonUnitRegions * 100) / s_dwTotalUpdates,
    468                s_dwTotalBoxes / s_dwTotalUpdates,
    469                s_dwNonUnitRegions, s_dwTotalUpdates);
    470 #endif                          /* XWIN_UPDATESTATS */
    471 
    472     /*
    473      * Handle small regions with multiple blits,
    474      * handle large regions by creating a clipping region and
    475      * doing a single blit constrained to that clipping region.
    476      */
    477     if (!pScreenInfo->fMultiWindow &&
    478         (pScreenInfo->dwClipUpdatesNBoxes == 0 ||
    479          dwBox < pScreenInfo->dwClipUpdatesNBoxes)) {
    480         /* Loop through all boxes in the damaged region */
    481         while (dwBox--) {
    482             /*
    483              * Calculate x offset, y offset, width, and height for
    484              * current damage box
    485              */
    486             x = pBox->x1;
    487             y = pBox->y1;
    488             w = pBox->x2 - pBox->x1;
    489             h = pBox->y2 - pBox->y1;
    490 
    491             BitBlt(pScreenPriv->hdcScreen,
    492                    x, y, w, h, pScreenPriv->hdcShadow, x, y, SRCCOPY);
    493 
    494             /* Get a pointer to the next box */
    495             ++pBox;
    496         }
    497     }
    498     else if (!pScreenInfo->fMultiWindow) {
    499 
    500         /* Compute a GDI region from the damaged region */
    501         hrgnCombined =
    502             CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
    503                           pBoxExtents->y2);
    504 
    505         /* Install the GDI region as a clipping region */
    506         SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
    507         DeleteObject(hrgnCombined);
    508         hrgnCombined = NULL;
    509 
    510         /*
    511          * Blit the shadow buffer to the screen,
    512          * constrained to the clipping region.
    513          */
    514         BitBlt(pScreenPriv->hdcScreen,
    515                pBoxExtents->x1, pBoxExtents->y1,
    516                pBoxExtents->x2 - pBoxExtents->x1,
    517                pBoxExtents->y2 - pBoxExtents->y1,
    518                pScreenPriv->hdcShadow,
    519                pBoxExtents->x1, pBoxExtents->y1, SRCCOPY);
    520 
    521         /* Reset the clip region */
    522         SelectClipRgn(pScreenPriv->hdcScreen, NULL);
    523     }
    524 
    525     /* Redraw all multiwindow windows */
    526     if (pScreenInfo->fMultiWindow)
    527         EnumThreadWindows(g_dwCurrentThreadID,
    528                           winRedrawDamagedWindowShadowGDI,
    529                           (LPARAM) pBoxExtents);
    530 }
    531 
    532 static Bool
    533 winInitScreenShadowGDI(ScreenPtr pScreen)
    534 {
    535     winScreenPriv(pScreen);
    536 
    537     /* Get device contexts for the screen and shadow bitmap */
    538     pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen);
    539     pScreenPriv->hdcShadow = CreateCompatibleDC(pScreenPriv->hdcScreen);
    540 
    541     /* Allocate bitmap info header */
    542     pScreenPriv->pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
    543     if (pScreenPriv->pbmih == NULL) {
    544         ErrorF("winInitScreenShadowGDI - malloc () failed\n");
    545         return FALSE;
    546     }
    547 
    548     /* Query the screen format */
    549     if (!winQueryScreenDIBFormat(pScreen, pScreenPriv->pbmih)) {
    550         ErrorF("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n");
    551         return FALSE;
    552     }
    553 
    554     /* Determine our color masks */
    555     if (!winQueryRGBBitsAndMasks(pScreen)) {
    556         ErrorF("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n");
    557         return FALSE;
    558     }
    559 
    560     return winAllocateFBShadowGDI(pScreen);
    561 }
    562 
    563 /* See Porting Layer Definition - p. 33 */
    564 /*
    565  * We wrap whatever CloseScreen procedure was specified by fb;
    566  * a pointer to said procedure is stored in our privates.
    567  */
    568 
    569 static Bool
    570 winCloseScreenShadowGDI(ScreenPtr pScreen)
    571 {
    572     winScreenPriv(pScreen);
    573     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
    574     Bool fReturn = TRUE;
    575 
    576 #if CYGDEBUG
    577     winDebug("winCloseScreenShadowGDI - Freeing screen resources\n");
    578 #endif
    579 
    580     /* Flag that the screen is closed */
    581     pScreenPriv->fClosed = TRUE;
    582     pScreenPriv->fActive = FALSE;
    583 
    584     /* Call the wrapped CloseScreen procedure */
    585     WIN_UNWRAP(CloseScreen);
    586     if (pScreen->CloseScreen)
    587         fReturn = (*pScreen->CloseScreen) (pScreen);
    588 
    589     /* Delete the window property */
    590     RemoveProp(pScreenPriv->hwndScreen, WIN_SCR_PROP);
    591 
    592     /* Free the shadow DC; which allows the bitmap to be freed */
    593     DeleteDC(pScreenPriv->hdcShadow);
    594 
    595     winFreeFBShadowGDI(pScreen);
    596 
    597     /* Free the screen DC */
    598     ReleaseDC(pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
    599 
    600     /* Delete tray icon, if we have one */
    601     if (!pScreenInfo->fNoTrayIcon)
    602         winDeleteNotifyIcon(pScreenPriv);
    603 
    604     /* Free the exit confirmation dialog box, if it exists */
    605     if (g_hDlgExit != NULL) {
    606         DestroyWindow(g_hDlgExit);
    607         g_hDlgExit = NULL;
    608     }
    609 
    610     /* Kill our window */
    611     if (pScreenPriv->hwndScreen) {
    612         DestroyWindow(pScreenPriv->hwndScreen);
    613         pScreenPriv->hwndScreen = NULL;
    614     }
    615 
    616     /* Destroy the thread startup mutex */
    617     pthread_mutex_destroy(&pScreenPriv->pmServerStarted);
    618 
    619     /* Invalidate our screeninfo's pointer to the screen */
    620     pScreenInfo->pScreen = NULL;
    621 
    622     /* Free the screen privates for this screen */
    623     free((void *) pScreenPriv);
    624 
    625     return fReturn;
    626 }
    627 
    628 /*
    629  * Tell mi what sort of visuals we need.
    630  *
    631  * Generally we only need one visual, as our screen can only
    632  * handle one format at a time, I believe.  You may want
    633  * to verify that last sentence.
    634  */
    635 
    636 static Bool
    637 winInitVisualsShadowGDI(ScreenPtr pScreen)
    638 {
    639     winScreenPriv(pScreen);
    640     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
    641 
    642     /* Display debugging information */
    643     ErrorF("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d "
    644            "bpp %d\n",
    645            (unsigned int) pScreenPriv->dwRedMask,
    646            (unsigned int) pScreenPriv->dwGreenMask,
    647            (unsigned int) pScreenPriv->dwBlueMask,
    648            (int) pScreenPriv->dwBitsPerRGB,
    649            (int) pScreenInfo->dwDepth, (int) pScreenInfo->dwBPP);
    650 
    651     /* Create a single visual according to the Windows screen depth */
    652     switch (pScreenInfo->dwDepth) {
    653     case 24:
    654     case 16:
    655     case 15:
    656         /* Setup the real visual */
    657         if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
    658                                       TrueColorMask,
    659                                       pScreenPriv->dwBitsPerRGB,
    660                                       -1,
    661                                       pScreenPriv->dwRedMask,
    662                                       pScreenPriv->dwGreenMask,
    663                                       pScreenPriv->dwBlueMask)) {
    664             ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
    665                    "failed\n");
    666             return FALSE;
    667         }
    668 
    669 #ifdef XWIN_EMULATEPSEUDO
    670         if (!pScreenInfo->fEmulatePseudo)
    671             break;
    672 
    673         /* Setup a pseudocolor visual */
    674         if (!miSetVisualTypesAndMasks(8, PseudoColorMask, 8, -1, 0, 0, 0)) {
    675             ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
    676                    "failed for PseudoColor\n");
    677             return FALSE;
    678         }
    679 #endif
    680         break;
    681 
    682     case 8:
    683         if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
    684                                       PseudoColorMask,
    685                                       pScreenPriv->dwBitsPerRGB,
    686                                       PseudoColor,
    687                                       pScreenPriv->dwRedMask,
    688                                       pScreenPriv->dwGreenMask,
    689                                       pScreenPriv->dwBlueMask)) {
    690             ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
    691                    "failed\n");
    692             return FALSE;
    693         }
    694         break;
    695 
    696     default:
    697         ErrorF("winInitVisualsShadowGDI - Unknown screen depth\n");
    698         return FALSE;
    699     }
    700 
    701 #if CYGDEBUG
    702     winDebug("winInitVisualsShadowGDI - Returning\n");
    703 #endif
    704 
    705     return TRUE;
    706 }
    707 
    708 /*
    709  * Adjust the proposed video mode
    710  */
    711 
    712 static Bool
    713 winAdjustVideoModeShadowGDI(ScreenPtr pScreen)
    714 {
    715     winScreenPriv(pScreen);
    716     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
    717     HDC hdc;
    718     DWORD dwBPP;
    719 
    720     hdc = GetDC(NULL);
    721 
    722     /* We're in serious trouble if we can't get a DC */
    723     if (hdc == NULL) {
    724         ErrorF("winAdjustVideoModeShadowGDI - GetDC () failed\n");
    725         return FALSE;
    726     }
    727 
    728     /* Query GDI for current display depth */
    729     dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
    730 
    731     /* GDI cannot change the screen depth, so always use GDI's depth */
    732     pScreenInfo->dwBPP = dwBPP;
    733 
    734     /* Release our DC */
    735     ReleaseDC(NULL, hdc);
    736     hdc = NULL;
    737 
    738     return TRUE;
    739 }
    740 
    741 /*
    742  * Blt exposed regions to the screen
    743  */
    744 
    745 static Bool
    746 winBltExposedRegionsShadowGDI(ScreenPtr pScreen)
    747 {
    748     winScreenPriv(pScreen);
    749     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
    750     winPrivCmapPtr pCmapPriv = NULL;
    751     HDC hdcUpdate;
    752     PAINTSTRUCT ps;
    753 
    754     /* BeginPaint gives us an hdc that clips to the invalidated region */
    755     hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps);
    756     /* Avoid the BitBlt if the PAINTSTRUCT region is bogus */
    757     if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 &&
    758         ps.rcPaint.left == 0 && ps.rcPaint.top == 0) {
    759         EndPaint(pScreenPriv->hwndScreen, &ps);
    760         return 0;
    761     }
    762 
    763     /* Realize the palette, if we have one */
    764     if (pScreenPriv->pcmapInstalled != NULL) {
    765         pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled);
    766 
    767         SelectPalette(hdcUpdate, pCmapPriv->hPalette, FALSE);
    768         RealizePalette(hdcUpdate);
    769     }
    770 
    771     /* Try to copy from the shadow buffer to the invalidated region */
    772     if (!BitBlt(hdcUpdate,
    773                 ps.rcPaint.left, ps.rcPaint.top,
    774                 ps.rcPaint.right - ps.rcPaint.left,
    775                 ps.rcPaint.bottom - ps.rcPaint.top,
    776                 pScreenPriv->hdcShadow,
    777                 ps.rcPaint.left,
    778                 ps.rcPaint.top,
    779                 SRCCOPY)) {
    780         LPVOID lpMsgBuf;
    781 
    782         /* Display an error message */
    783         FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
    784                       FORMAT_MESSAGE_FROM_SYSTEM |
    785                       FORMAT_MESSAGE_IGNORE_INSERTS,
    786                       NULL,
    787                       GetLastError(),
    788                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    789                       (LPTSTR) &lpMsgBuf, 0, NULL);
    790 
    791         ErrorF("winBltExposedRegionsShadowGDI - BitBlt failed: %s\n",
    792                (LPSTR) lpMsgBuf);
    793         LocalFree(lpMsgBuf);
    794     }
    795 
    796     /* EndPaint frees the DC */
    797     EndPaint(pScreenPriv->hwndScreen, &ps);
    798 
    799     /* Redraw all windows */
    800     if (pScreenInfo->fMultiWindow)
    801         EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI,
    802                           (LPARAM) pScreenPriv->hwndScreen);
    803 
    804     return TRUE;
    805 }
    806 
    807 /*
    808  * Blt exposed region to the given HWND
    809  */
    810 
    811 static Bool
    812 winBltExposedWindowRegionShadowGDI(ScreenPtr pScreen, WindowPtr pWin)
    813 {
    814     winScreenPriv(pScreen);
    815     winPrivWinPtr pWinPriv = winGetWindowPriv(pWin);
    816 
    817     HWND hWnd = pWinPriv->hWnd;
    818     HDC hdcUpdate;
    819     PAINTSTRUCT ps;
    820 
    821     hdcUpdate = BeginPaint(hWnd, &ps);
    822     /* Avoid the BitBlt if the PAINTSTRUCT region is bogus */
    823     if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 &&
    824         ps.rcPaint.left == 0 && ps.rcPaint.top == 0) {
    825         EndPaint(hWnd, &ps);
    826         return 0;
    827     }
    828 
    829 #ifdef COMPOSITE
    830     if (pWin->redirectDraw != RedirectDrawNone) {
    831         HBITMAP hBitmap;
    832         HDC hdcPixmap;
    833         PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
    834         winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap);
    835 
    836         /* window pixmap format is the same as the screen pixmap */
    837         assert(pPixmap->drawable.bitsPerPixel > 8);
    838 
    839         /* Get the window bitmap from the pixmap */
    840         hBitmap = pPixmapPriv->hBitmap;
    841 
    842         /* XXX: There may be a need for a slow-path here: If hBitmap is NULL
    843            (because we couldn't back the pixmap with a Windows DIB), we should
    844            fall-back to creating a Windows DIB from the pixmap, then deleting it
    845            after the BitBlt (as this this code did before the fast-path was
    846            added). */
    847         if (!hBitmap) {
    848             ErrorF("winBltExposedWindowRegionShadowGDI - slow path unimplemented\n");
    849         }
    850 
    851         /* Select the window bitmap into a screen-compatible DC */
    852         hdcPixmap = CreateCompatibleDC(pScreenPriv->hdcScreen);
    853         SelectObject(hdcPixmap, hBitmap);
    854 
    855         /* Blt from the window bitmap to the invalidated region */
    856         if (!BitBlt(hdcUpdate,
    857                     ps.rcPaint.left, ps.rcPaint.top,
    858                     ps.rcPaint.right - ps.rcPaint.left,
    859                     ps.rcPaint.bottom - ps.rcPaint.top,
    860                     hdcPixmap,
    861                     ps.rcPaint.left + pWin->borderWidth,
    862                     ps.rcPaint.top + pWin->borderWidth,
    863                     SRCCOPY))
    864             ErrorF("winBltExposedWindowRegionShadowGDI - BitBlt failed: 0x%08x\n",
    865                    GetLastError());
    866 
    867         /* Release DC */
    868         DeleteDC(hdcPixmap);
    869     }
    870     else
    871 #endif
    872     {
    873     /* Try to copy from the shadow buffer to the invalidated region */
    874     if (!BitBlt(hdcUpdate,
    875                 ps.rcPaint.left, ps.rcPaint.top,
    876                 ps.rcPaint.right - ps.rcPaint.left,
    877                 ps.rcPaint.bottom - ps.rcPaint.top,
    878                 pScreenPriv->hdcShadow,
    879                 ps.rcPaint.left + pWin->drawable.x,
    880                 ps.rcPaint.top + pWin->drawable.y,
    881                 SRCCOPY)) {
    882         LPVOID lpMsgBuf;
    883 
    884         /* Display an error message */
    885         FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
    886                       FORMAT_MESSAGE_FROM_SYSTEM |
    887                       FORMAT_MESSAGE_IGNORE_INSERTS,
    888                       NULL,
    889                       GetLastError(),
    890                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    891                       (LPTSTR) &lpMsgBuf, 0, NULL);
    892 
    893         ErrorF("winBltExposedWindowRegionShadowGDI - BitBlt failed: %s\n",
    894                (LPSTR) lpMsgBuf);
    895         LocalFree(lpMsgBuf);
    896     }
    897     }
    898 
    899     /* If part of the invalidated region is outside the window (which can happen
    900        if the native window is being re-sized), fill that area with black */
    901     if (ps.rcPaint.right > ps.rcPaint.left + pWin->drawable.width) {
    902         BitBlt(hdcUpdate,
    903                ps.rcPaint.left + pWin->drawable.width,
    904                ps.rcPaint.top,
    905                ps.rcPaint.right - (ps.rcPaint.left + pWin->drawable.width),
    906                ps.rcPaint.bottom - ps.rcPaint.top,
    907                NULL,
    908                0, 0,
    909                BLACKNESS);
    910     }
    911 
    912     if (ps.rcPaint.bottom > ps.rcPaint.top + pWin->drawable.height) {
    913         BitBlt(hdcUpdate,
    914                ps.rcPaint.left,
    915                ps.rcPaint.top + pWin->drawable.height,
    916                ps.rcPaint.right - ps.rcPaint.left,
    917                ps.rcPaint.bottom - (ps.rcPaint.top + pWin->drawable.height),
    918                NULL,
    919                0, 0,
    920                BLACKNESS);
    921     }
    922 
    923     /* EndPaint frees the DC */
    924     EndPaint(hWnd, &ps);
    925 
    926     return TRUE;
    927 }
    928 
    929 /*
    930  * Do any engine-specific appliation-activation processing
    931  */
    932 
    933 static Bool
    934 winActivateAppShadowGDI(ScreenPtr pScreen)
    935 {
    936     winScreenPriv(pScreen);
    937     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
    938 
    939     /*
    940      * 2004/04/12 - Harold - We perform the restoring or minimizing
    941      * manually for ShadowGDI in fullscreen modes so that this engine
    942      * will perform just like ShadowDD and ShadowDDNL in fullscreen mode;
    943      * if we do not do this then our fullscreen window will appear in the
    944      * z-order when it is deactivated and it can be uncovered by resizing
    945      * or minimizing another window that is on top of it, which is not how
    946      * the DirectDraw engines work.  Therefore we keep this code here to
    947      * make sure that all engines work the same in fullscreen mode.
    948      */
    949 
    950     /*
    951      * Are we active?
    952      * Are we fullscreen?
    953      */
    954     if (pScreenPriv->fActive && pScreenInfo->fFullScreen) {
    955         /*
    956          * Activating, attempt to bring our window
    957          * to the top of the display
    958          */
    959         ShowWindow(pScreenPriv->hwndScreen, SW_RESTORE);
    960     }
    961     else if (!pScreenPriv->fActive && pScreenInfo->fFullScreen) {
    962         /*
    963          * Deactivating, stuff our window onto the
    964          * task bar.
    965          */
    966         ShowWindow(pScreenPriv->hwndScreen, SW_MINIMIZE);
    967     }
    968 
    969     return TRUE;
    970 }
    971 
    972 /*
    973  * Reblit the shadow framebuffer to the screen.
    974  */
    975 
    976 static Bool
    977 winRedrawScreenShadowGDI(ScreenPtr pScreen)
    978 {
    979     winScreenPriv(pScreen);
    980     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
    981 
    982     /* Redraw the whole window, to take account for the new colors */
    983     BitBlt(pScreenPriv->hdcScreen,
    984            0, 0,
    985            pScreenInfo->dwWidth, pScreenInfo->dwHeight,
    986            pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
    987 
    988     /* Redraw all windows */
    989     if (pScreenInfo->fMultiWindow)
    990         EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
    991 
    992     return TRUE;
    993 }
    994 
    995 /*
    996  * Realize the currently installed colormap
    997  */
    998 
    999 static Bool
   1000 winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen)
   1001 {
   1002     winScreenPriv(pScreen);
   1003     winPrivCmapPtr pCmapPriv = NULL;
   1004 
   1005 #if CYGDEBUG
   1006     winDebug("winRealizeInstalledPaletteShadowGDI\n");
   1007 #endif
   1008 
   1009     /* Don't do anything if there is not a colormap */
   1010     if (pScreenPriv->pcmapInstalled == NULL) {
   1011 #if CYGDEBUG
   1012         winDebug("winRealizeInstalledPaletteShadowGDI - No colormap "
   1013                  "installed\n");
   1014 #endif
   1015         return TRUE;
   1016     }
   1017 
   1018     pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled);
   1019 
   1020     /* Realize our palette for the screen */
   1021     if (RealizePalette(pScreenPriv->hdcScreen) == GDI_ERROR) {
   1022         ErrorF("winRealizeInstalledPaletteShadowGDI - RealizePalette () "
   1023                "failed\n");
   1024         return FALSE;
   1025     }
   1026 
   1027     /* Set the DIB color table */
   1028     if (SetDIBColorTable(pScreenPriv->hdcShadow,
   1029                          0,
   1030                          WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) {
   1031         ErrorF("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () "
   1032                "failed\n");
   1033         return FALSE;
   1034     }
   1035 
   1036     return TRUE;
   1037 }
   1038 
   1039 /*
   1040  * Install the specified colormap
   1041  */
   1042 
   1043 static Bool
   1044 winInstallColormapShadowGDI(ColormapPtr pColormap)
   1045 {
   1046     ScreenPtr pScreen = pColormap->pScreen;
   1047 
   1048     winScreenPriv(pScreen);
   1049     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
   1050 
   1051     winCmapPriv(pColormap);
   1052 
   1053     /*
   1054      * Tell Windows to install the new colormap
   1055      */
   1056     if (SelectPalette(pScreenPriv->hdcScreen,
   1057                       pCmapPriv->hPalette, FALSE) == NULL) {
   1058         ErrorF("winInstallColormapShadowGDI - SelectPalette () failed\n");
   1059         return FALSE;
   1060     }
   1061 
   1062     /* Realize the palette */
   1063     if (GDI_ERROR == RealizePalette(pScreenPriv->hdcScreen)) {
   1064         ErrorF("winInstallColormapShadowGDI - RealizePalette () failed\n");
   1065         return FALSE;
   1066     }
   1067 
   1068     /* Set the DIB color table */
   1069     if (SetDIBColorTable(pScreenPriv->hdcShadow,
   1070                          0,
   1071                          WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) {
   1072         ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
   1073         return FALSE;
   1074     }
   1075 
   1076     /* Redraw the whole window, to take account for the new colors */
   1077     BitBlt(pScreenPriv->hdcScreen,
   1078            0, 0,
   1079            pScreenInfo->dwWidth, pScreenInfo->dwHeight,
   1080            pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
   1081 
   1082     /* Save a pointer to the newly installed colormap */
   1083     pScreenPriv->pcmapInstalled = pColormap;
   1084 
   1085     /* Redraw all windows */
   1086     if (pScreenInfo->fMultiWindow)
   1087         EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
   1088 
   1089     return TRUE;
   1090 }
   1091 
   1092 /*
   1093  * Store the specified colors in the specified colormap
   1094  */
   1095 
   1096 static Bool
   1097 winStoreColorsShadowGDI(ColormapPtr pColormap, int ndef, xColorItem * pdefs)
   1098 {
   1099     ScreenPtr pScreen = pColormap->pScreen;
   1100 
   1101     winScreenPriv(pScreen);
   1102     winCmapPriv(pColormap);
   1103     ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
   1104 
   1105     /* Put the X colormap entries into the Windows logical palette */
   1106     if (SetPaletteEntries(pCmapPriv->hPalette,
   1107                           pdefs[0].pixel,
   1108                           ndef, pCmapPriv->peColors + pdefs[0].pixel) == 0) {
   1109         ErrorF("winStoreColorsShadowGDI - SetPaletteEntries () failed\n");
   1110         return FALSE;
   1111     }
   1112 
   1113     /* Don't install the Windows palette if the colormap is not installed */
   1114     if (pColormap != curpmap) {
   1115         return TRUE;
   1116     }
   1117 
   1118     /* Try to install the newly modified colormap */
   1119     if (!winInstallColormapShadowGDI(pColormap)) {
   1120         ErrorF("winInstallColormapShadowGDI - winInstallColormapShadowGDI "
   1121                "failed\n");
   1122         return FALSE;
   1123     }
   1124 
   1125 #if 0
   1126     /* Tell Windows that the palette has changed */
   1127     RealizePalette(pScreenPriv->hdcScreen);
   1128 
   1129     /* Set the DIB color table */
   1130     if (SetDIBColorTable(pScreenPriv->hdcShadow,
   1131                          pdefs[0].pixel,
   1132                          ndef, pCmapPriv->rgbColors + pdefs[0].pixel) == 0) {
   1133         ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
   1134         return FALSE;
   1135     }
   1136 
   1137     /* Save a pointer to the newly installed colormap */
   1138     pScreenPriv->pcmapInstalled = pColormap;
   1139 #endif
   1140 
   1141     return TRUE;
   1142 }
   1143 
   1144 /*
   1145  * Colormap initialization procedure
   1146  */
   1147 
   1148 static Bool
   1149 winCreateColormapShadowGDI(ColormapPtr pColormap)
   1150 {
   1151     LPLOGPALETTE lpPaletteNew = NULL;
   1152     DWORD dwEntriesMax;
   1153     VisualPtr pVisual;
   1154     HPALETTE hpalNew = NULL;
   1155 
   1156     winCmapPriv(pColormap);
   1157 
   1158     /* Get a pointer to the visual that the colormap belongs to */
   1159     pVisual = pColormap->pVisual;
   1160 
   1161     /* Get the maximum number of palette entries for this visual */
   1162     dwEntriesMax = pVisual->ColormapEntries;
   1163 
   1164     /* Allocate a Windows logical color palette with max entries */
   1165     lpPaletteNew = malloc(sizeof(LOGPALETTE)
   1166                           + (dwEntriesMax - 1) * sizeof(PALETTEENTRY));
   1167     if (lpPaletteNew == NULL) {
   1168         ErrorF("winCreateColormapShadowGDI - Couldn't allocate palette "
   1169                "with %d entries\n", (int) dwEntriesMax);
   1170         return FALSE;
   1171     }
   1172 
   1173     /* Zero out the colormap */
   1174     ZeroMemory(lpPaletteNew, sizeof(LOGPALETTE)
   1175                + (dwEntriesMax - 1) * sizeof(PALETTEENTRY));
   1176 
   1177     /* Set the logical palette structure */
   1178     lpPaletteNew->palVersion = 0x0300;
   1179     lpPaletteNew->palNumEntries = dwEntriesMax;
   1180 
   1181     /* Tell Windows to create the palette */
   1182     hpalNew = CreatePalette(lpPaletteNew);
   1183     if (hpalNew == NULL) {
   1184         ErrorF("winCreateColormapShadowGDI - CreatePalette () failed\n");
   1185         free(lpPaletteNew);
   1186         return FALSE;
   1187     }
   1188 
   1189     /* Save the Windows logical palette handle in the X colormaps' privates */
   1190     pCmapPriv->hPalette = hpalNew;
   1191 
   1192     /* Free the palette initialization memory */
   1193     free(lpPaletteNew);
   1194 
   1195     return TRUE;
   1196 }
   1197 
   1198 /*
   1199  * Colormap destruction procedure
   1200  */
   1201 
   1202 static Bool
   1203 winDestroyColormapShadowGDI(ColormapPtr pColormap)
   1204 {
   1205     winScreenPriv(pColormap->pScreen);
   1206     winCmapPriv(pColormap);
   1207 
   1208     /*
   1209      * Is colormap to be destroyed the default?
   1210      *
   1211      * Non-default colormaps should have had winUninstallColormap
   1212      * called on them before we get here.  The default colormap
   1213      * will not have had winUninstallColormap called on it.  Thus,
   1214      * we need to handle the default colormap in a special way.
   1215      */
   1216     if (pColormap->flags & IsDefault) {
   1217 #if CYGDEBUG
   1218         winDebug("winDestroyColormapShadowGDI - Destroying default "
   1219                  "colormap\n");
   1220 #endif
   1221 
   1222         /*
   1223          * FIXME: Walk the list of all screens, popping the default
   1224          * palette out of each screen device context.
   1225          */
   1226 
   1227         /* Pop the palette out of the device context */
   1228         SelectPalette(pScreenPriv->hdcScreen,
   1229                       GetStockObject(DEFAULT_PALETTE), FALSE);
   1230 
   1231         /* Clear our private installed colormap pointer */
   1232         pScreenPriv->pcmapInstalled = NULL;
   1233     }
   1234 
   1235     /* Try to delete the logical palette */
   1236     if (DeleteObject(pCmapPriv->hPalette) == 0) {
   1237         ErrorF("winDestroyColormap - DeleteObject () failed\n");
   1238         return FALSE;
   1239     }
   1240 
   1241     /* Invalidate the colormap privates */
   1242     pCmapPriv->hPalette = NULL;
   1243 
   1244     return TRUE;
   1245 }
   1246 
   1247 /*
   1248  * Set engine specific functions
   1249  */
   1250 
   1251 Bool
   1252 winSetEngineFunctionsShadowGDI(ScreenPtr pScreen)
   1253 {
   1254     winScreenPriv(pScreen);
   1255     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
   1256 
   1257     /* Set our pointers */
   1258     pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI;
   1259     pScreenPriv->pwinFreeFB = winFreeFBShadowGDI;
   1260     pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI;
   1261     pScreenPriv->pwinInitScreen = winInitScreenShadowGDI;
   1262     pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI;
   1263     pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI;
   1264     pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI;
   1265     if (pScreenInfo->fFullScreen)
   1266         pScreenPriv->pwinCreateBoundingWindow =
   1267             winCreateBoundingWindowFullScreen;
   1268     else
   1269         pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
   1270     pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
   1271     pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI;
   1272     pScreenPriv->pwinBltExposedWindowRegion = winBltExposedWindowRegionShadowGDI;
   1273     pScreenPriv->pwinActivateApp = winActivateAppShadowGDI;
   1274     pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI;
   1275     pScreenPriv->pwinRealizeInstalledPalette =
   1276         winRealizeInstalledPaletteShadowGDI;
   1277     pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI;
   1278     pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI;
   1279     pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI;
   1280     pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI;
   1281     pScreenPriv->pwinCreatePrimarySurface = NULL;
   1282     pScreenPriv->pwinReleasePrimarySurface = NULL;
   1283 
   1284     return TRUE;
   1285 }