105b261ecSmrg/*
205b261ecSmrg *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved.
305b261ecSmrg *
405b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining
505b261ecSmrg * a copy of this software and associated documentation files (the
605b261ecSmrg *"Software"), to deal in the Software without restriction, including
705b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish,
805b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to
905b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to
1005b261ecSmrg *the following conditions:
1105b261ecSmrg *
1205b261ecSmrg *The above copyright notice and this permission notice shall be
1305b261ecSmrg *included in all copies or substantial portions of the Software.
1405b261ecSmrg *
1505b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1605b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1705b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1805b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR
1905b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
2005b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2105b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2205b261ecSmrg *
2305b261ecSmrg *Except as contained in this notice, the name of Harold L Hunt II
2405b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use
2505b261ecSmrg *or other dealings in this Software without prior written authorization
2605b261ecSmrg *from Harold L Hunt II.
2705b261ecSmrg *
2805b261ecSmrg * Authors:	Harold L Hunt II
2905b261ecSmrg */
3005b261ecSmrg
3105b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H
3205b261ecSmrg#include <xwin-config.h>
3305b261ecSmrg#endif
3405b261ecSmrg#include "win.h"
3505b261ecSmrg
3605b261ecSmrg/*
3705b261ecSmrg * Local function prototypes
3805b261ecSmrg */
3905b261ecSmrg
4035c4bbdfSmrgstatic wBOOL CALLBACK winRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam);
4105b261ecSmrg
4235c4bbdfSmrgstatic wBOOL CALLBACK winRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam);
4305b261ecSmrg
4405b261ecSmrgstatic Bool
4535c4bbdfSmrg winAllocateFBShadowGDI(ScreenPtr pScreen);
4605b261ecSmrg
4705b261ecSmrgstatic void
4835c4bbdfSmrg winShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf);
4905b261ecSmrg
5005b261ecSmrgstatic Bool
5135c4bbdfSmrg winCloseScreenShadowGDI(ScreenPtr pScreen);
5205b261ecSmrg
5305b261ecSmrgstatic Bool
5435c4bbdfSmrg winInitVisualsShadowGDI(ScreenPtr pScreen);
5505b261ecSmrg
5605b261ecSmrgstatic Bool
5735c4bbdfSmrg winAdjustVideoModeShadowGDI(ScreenPtr pScreen);
5805b261ecSmrg
5905b261ecSmrgstatic Bool
6035c4bbdfSmrg winBltExposedRegionsShadowGDI(ScreenPtr pScreen);
6105b261ecSmrg
62ed6184dfSmrgstatic Bool
63ed6184dfSmrg winBltExposedWindowRegionShadowGDI(ScreenPtr pScreen, WindowPtr pWin);
64ed6184dfSmrg
6505b261ecSmrgstatic Bool
6635c4bbdfSmrg winActivateAppShadowGDI(ScreenPtr pScreen);
6705b261ecSmrg
6805b261ecSmrgstatic Bool
6935c4bbdfSmrg winRedrawScreenShadowGDI(ScreenPtr pScreen);
7005b261ecSmrg
7105b261ecSmrgstatic Bool
7235c4bbdfSmrg winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen);
7305b261ecSmrg
7405b261ecSmrgstatic Bool
7535c4bbdfSmrg winInstallColormapShadowGDI(ColormapPtr pColormap);
7605b261ecSmrg
7705b261ecSmrgstatic Bool
7835c4bbdfSmrg winStoreColorsShadowGDI(ColormapPtr pmap, int ndef, xColorItem * pdefs);
7905b261ecSmrg
8005b261ecSmrgstatic Bool
8135c4bbdfSmrg winCreateColormapShadowGDI(ColormapPtr pColormap);
8205b261ecSmrg
8305b261ecSmrgstatic Bool
8435c4bbdfSmrg winDestroyColormapShadowGDI(ColormapPtr pColormap);
8505b261ecSmrg
8605b261ecSmrg/*
8705b261ecSmrg * Internal function to get the DIB format that is compatible with the screen
8805b261ecSmrg */
8905b261ecSmrg
9005b261ecSmrgstatic
9135c4bbdfSmrg    Bool
9235c4bbdfSmrgwinQueryScreenDIBFormat(ScreenPtr pScreen, BITMAPINFOHEADER * pbmih)
9305b261ecSmrg{
9435c4bbdfSmrg    winScreenPriv(pScreen);
9535c4bbdfSmrg    HBITMAP hbmp;
9635c4bbdfSmrg
9705b261ecSmrg#if CYGDEBUG
9835c4bbdfSmrg    LPDWORD pdw = NULL;
9905b261ecSmrg#endif
10035c4bbdfSmrg
10135c4bbdfSmrg    /* Create a memory bitmap compatible with the screen */
10235c4bbdfSmrg    hbmp = CreateCompatibleBitmap(pScreenPriv->hdcScreen, 1, 1);
10335c4bbdfSmrg    if (hbmp == NULL) {
10435c4bbdfSmrg        ErrorF("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n");
10535c4bbdfSmrg        return FALSE;
10605b261ecSmrg    }
10735c4bbdfSmrg
10835c4bbdfSmrg    /* Initialize our bitmap info header */
10935c4bbdfSmrg    ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
11035c4bbdfSmrg    pbmih->biSize = sizeof(BITMAPINFOHEADER);
11135c4bbdfSmrg
11235c4bbdfSmrg    /* Get the biBitCount */
11335c4bbdfSmrg    if (!GetDIBits(pScreenPriv->hdcScreen,
11435c4bbdfSmrg                   hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) {
11535c4bbdfSmrg        ErrorF("winQueryScreenDIBFormat - First call to GetDIBits failed\n");
11635c4bbdfSmrg        DeleteObject(hbmp);
11735c4bbdfSmrg        return FALSE;
11805b261ecSmrg    }
11905b261ecSmrg
12005b261ecSmrg#if CYGDEBUG
12135c4bbdfSmrg    /* Get a pointer to bitfields */
12235c4bbdfSmrg    pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER));
12305b261ecSmrg
12435c4bbdfSmrg    winDebug("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n",
12535c4bbdfSmrg             (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]);
12605b261ecSmrg#endif
12705b261ecSmrg
12835c4bbdfSmrg    /* Get optimal color table, or the optimal bitfields */
12935c4bbdfSmrg    if (!GetDIBits(pScreenPriv->hdcScreen,
13035c4bbdfSmrg                   hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) {
13135c4bbdfSmrg        ErrorF("winQueryScreenDIBFormat - Second call to GetDIBits "
13235c4bbdfSmrg               "failed\n");
13335c4bbdfSmrg        DeleteObject(hbmp);
13435c4bbdfSmrg        return FALSE;
13505b261ecSmrg    }
13605b261ecSmrg
13735c4bbdfSmrg    /* Free memory */
13835c4bbdfSmrg    DeleteObject(hbmp);
13905b261ecSmrg
14035c4bbdfSmrg    return TRUE;
14135c4bbdfSmrg}
14205b261ecSmrg
14305b261ecSmrg/*
14405b261ecSmrg * Internal function to determine the GDI bits per rgb and bit masks
14505b261ecSmrg */
14605b261ecSmrg
14705b261ecSmrgstatic
14835c4bbdfSmrg    Bool
14935c4bbdfSmrgwinQueryRGBBitsAndMasks(ScreenPtr pScreen)
15005b261ecSmrg{
15135c4bbdfSmrg    winScreenPriv(pScreen);
15235c4bbdfSmrg    BITMAPINFOHEADER *pbmih = NULL;
15335c4bbdfSmrg    Bool fReturn = TRUE;
15435c4bbdfSmrg    LPDWORD pdw = NULL;
15535c4bbdfSmrg    DWORD dwRedBits, dwGreenBits, dwBlueBits;
15635c4bbdfSmrg
15735c4bbdfSmrg    /* Color masks for 8 bpp are standardized */
15835c4bbdfSmrg    if (GetDeviceCaps(pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) {
15935c4bbdfSmrg        /*
16035c4bbdfSmrg         * RGB BPP for 8 bit palletes is always 8
16135c4bbdfSmrg         * and the color masks are always 0.
16235c4bbdfSmrg         */
16335c4bbdfSmrg        pScreenPriv->dwBitsPerRGB = 8;
16435c4bbdfSmrg        pScreenPriv->dwRedMask = 0x0L;
16535c4bbdfSmrg        pScreenPriv->dwGreenMask = 0x0L;
16635c4bbdfSmrg        pScreenPriv->dwBlueMask = 0x0L;
16735c4bbdfSmrg        return TRUE;
16805b261ecSmrg    }
16905b261ecSmrg
17035c4bbdfSmrg    /* Color masks for 24 bpp are standardized */
17135c4bbdfSmrg    if (GetDeviceCaps(pScreenPriv->hdcScreen, PLANES)
17235c4bbdfSmrg        * GetDeviceCaps(pScreenPriv->hdcScreen, BITSPIXEL) == 24) {
17335c4bbdfSmrg        ErrorF("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) "
17435c4bbdfSmrg               "returned 24 for the screen.  Using default 24bpp masks.\n");
17535c4bbdfSmrg
17635c4bbdfSmrg        /* 8 bits per primary color */
17735c4bbdfSmrg        pScreenPriv->dwBitsPerRGB = 8;
17835c4bbdfSmrg
17935c4bbdfSmrg        /* Set screen privates masks */
18035c4bbdfSmrg        pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED;
18135c4bbdfSmrg        pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN;
18235c4bbdfSmrg        pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE;
18335c4bbdfSmrg
18435c4bbdfSmrg        return TRUE;
18505b261ecSmrg    }
18605b261ecSmrg
18735c4bbdfSmrg    /* Allocate a bitmap header and color table */
18835c4bbdfSmrg    pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
18935c4bbdfSmrg    if (pbmih == NULL) {
19035c4bbdfSmrg        ErrorF("winQueryRGBBitsAndMasks - malloc failed\n");
19135c4bbdfSmrg        return FALSE;
19205b261ecSmrg    }
19305b261ecSmrg
19435c4bbdfSmrg    /* Get screen description */
19535c4bbdfSmrg    if (winQueryScreenDIBFormat(pScreen, pbmih)) {
19635c4bbdfSmrg        /* Get a pointer to bitfields */
19735c4bbdfSmrg        pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER));
19835c4bbdfSmrg
19905b261ecSmrg#if CYGDEBUG
20035c4bbdfSmrg        winDebug("%s - Masks: %08x %08x %08x\n", __FUNCTION__,
20135c4bbdfSmrg                 (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]);
20235c4bbdfSmrg        winDebug("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__,
20335c4bbdfSmrg                 (int)pbmih->biWidth, (int)pbmih->biHeight, pbmih->biBitCount,
20435c4bbdfSmrg                 pbmih->biPlanes);
20535c4bbdfSmrg        winDebug("%s - Compression: %u %s\n", __FUNCTION__,
20635c4bbdfSmrg                 (unsigned int)pbmih->biCompression,
20735c4bbdfSmrg                 (pbmih->biCompression ==
20835c4bbdfSmrg                  BI_RGB ? "(BI_RGB)" : (pbmih->biCompression ==
20935c4bbdfSmrg                                         BI_RLE8 ? "(BI_RLE8)" : (pbmih->
21035c4bbdfSmrg                                                                  biCompression
21135c4bbdfSmrg                                                                  ==
21235c4bbdfSmrg                                                                  BI_RLE4 ?
21335c4bbdfSmrg                                                                  "(BI_RLE4)"
21435c4bbdfSmrg                                                                  : (pbmih->
21535c4bbdfSmrg                                                                     biCompression
21635c4bbdfSmrg                                                                     ==
21735c4bbdfSmrg                                                                     BI_BITFIELDS
21835c4bbdfSmrg                                                                     ?
21935c4bbdfSmrg                                                                     "(BI_BITFIELDS)"
22035c4bbdfSmrg                                                                     : "")))));
22105b261ecSmrg#endif
22205b261ecSmrg
22335c4bbdfSmrg        /* Handle BI_RGB case, which is returned by Wine */
22435c4bbdfSmrg        if (pbmih->biCompression == BI_RGB) {
22535c4bbdfSmrg            dwRedBits = 5;
22635c4bbdfSmrg            dwGreenBits = 5;
22735c4bbdfSmrg            dwBlueBits = 5;
22835c4bbdfSmrg
22935c4bbdfSmrg            pScreenPriv->dwBitsPerRGB = 5;
23035c4bbdfSmrg
23135c4bbdfSmrg            /* Set screen privates masks */
23235c4bbdfSmrg            pScreenPriv->dwRedMask = 0x7c00;
23335c4bbdfSmrg            pScreenPriv->dwGreenMask = 0x03e0;
23435c4bbdfSmrg            pScreenPriv->dwBlueMask = 0x001f;
23535c4bbdfSmrg        }
23635c4bbdfSmrg        else {
23735c4bbdfSmrg            /* Count the number of bits in each mask */
23835c4bbdfSmrg            dwRedBits = winCountBits(pdw[0]);
23935c4bbdfSmrg            dwGreenBits = winCountBits(pdw[1]);
24035c4bbdfSmrg            dwBlueBits = winCountBits(pdw[2]);
24135c4bbdfSmrg
24235c4bbdfSmrg            /* Find maximum bits per red, green, blue */
24335c4bbdfSmrg            if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
24435c4bbdfSmrg                pScreenPriv->dwBitsPerRGB = dwRedBits;
24535c4bbdfSmrg            else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
24635c4bbdfSmrg                pScreenPriv->dwBitsPerRGB = dwGreenBits;
24735c4bbdfSmrg            else
24835c4bbdfSmrg                pScreenPriv->dwBitsPerRGB = dwBlueBits;
24935c4bbdfSmrg
25035c4bbdfSmrg            /* Set screen privates masks */
25135c4bbdfSmrg            pScreenPriv->dwRedMask = pdw[0];
25235c4bbdfSmrg            pScreenPriv->dwGreenMask = pdw[1];
25335c4bbdfSmrg            pScreenPriv->dwBlueMask = pdw[2];
25405b261ecSmrg        }
25505b261ecSmrg    }
25635c4bbdfSmrg    else {
25735c4bbdfSmrg        ErrorF("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n");
25835c4bbdfSmrg        fReturn = FALSE;
25905b261ecSmrg    }
26005b261ecSmrg
26135c4bbdfSmrg    /* Free memory */
26235c4bbdfSmrg    free(pbmih);
26305b261ecSmrg
26435c4bbdfSmrg    return fReturn;
26505b261ecSmrg}
26605b261ecSmrg
26705b261ecSmrg/*
26805b261ecSmrg * Redraw all ---?
26905b261ecSmrg */
27005b261ecSmrg
27105b261ecSmrgstatic wBOOL CALLBACK
27235c4bbdfSmrgwinRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam)
27305b261ecSmrg{
27435c4bbdfSmrg    if (hwnd == (HWND) lParam)
27535c4bbdfSmrg        return TRUE;
27635c4bbdfSmrg    InvalidateRect(hwnd, NULL, FALSE);
27735c4bbdfSmrg    UpdateWindow(hwnd);
27835c4bbdfSmrg    return TRUE;
27905b261ecSmrg}
28005b261ecSmrg
28105b261ecSmrgstatic wBOOL CALLBACK
28235c4bbdfSmrgwinRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam)
28305b261ecSmrg{
28435c4bbdfSmrg    BoxPtr pDamage = (BoxPtr) lParam;
28535c4bbdfSmrg    RECT rcClient, rcDamage, rcRedraw;
28635c4bbdfSmrg    POINT topLeft, bottomRight;
28735c4bbdfSmrg
28835c4bbdfSmrg    if (IsIconic(hwnd))
28935c4bbdfSmrg        return TRUE;            /* Don't care minimized windows */
29035c4bbdfSmrg
29135c4bbdfSmrg    /* Convert the damaged area from Screen coords to Client coords */
29235c4bbdfSmrg    topLeft.x = pDamage->x1;
29335c4bbdfSmrg    topLeft.y = pDamage->y1;
29435c4bbdfSmrg    bottomRight.x = pDamage->x2;
29535c4bbdfSmrg    bottomRight.y = pDamage->y2;
29635c4bbdfSmrg    topLeft.x += GetSystemMetrics(SM_XVIRTUALSCREEN);
29735c4bbdfSmrg    bottomRight.x += GetSystemMetrics(SM_XVIRTUALSCREEN);
29835c4bbdfSmrg    topLeft.y += GetSystemMetrics(SM_YVIRTUALSCREEN);
29935c4bbdfSmrg    bottomRight.y += GetSystemMetrics(SM_YVIRTUALSCREEN);
30035c4bbdfSmrg    ScreenToClient(hwnd, &topLeft);
30135c4bbdfSmrg    ScreenToClient(hwnd, &bottomRight);
30235c4bbdfSmrg    SetRect(&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
30335c4bbdfSmrg
30435c4bbdfSmrg    GetClientRect(hwnd, &rcClient);
30535c4bbdfSmrg
30635c4bbdfSmrg    if (IntersectRect(&rcRedraw, &rcClient, &rcDamage)) {
30735c4bbdfSmrg        InvalidateRect(hwnd, &rcRedraw, FALSE);
30835c4bbdfSmrg        UpdateWindow(hwnd);
30905b261ecSmrg    }
31035c4bbdfSmrg    return TRUE;
31105b261ecSmrg}
31205b261ecSmrg
31305b261ecSmrg/*
31405b261ecSmrg * Allocate a DIB for the shadow framebuffer GDI server
31505b261ecSmrg */
31605b261ecSmrg
31705b261ecSmrgstatic Bool
31835c4bbdfSmrgwinAllocateFBShadowGDI(ScreenPtr pScreen)
31905b261ecSmrg{
32035c4bbdfSmrg    winScreenPriv(pScreen);
32135c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
32235c4bbdfSmrg    DIBSECTION dibsection;
32335c4bbdfSmrg    Bool fReturn = TRUE;
32435c4bbdfSmrg
32535c4bbdfSmrg    /* Describe shadow bitmap to be created */
32635c4bbdfSmrg    pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth;
32735c4bbdfSmrg    pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight;
32835c4bbdfSmrg
32935c4bbdfSmrg    ErrorF("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d "
33035c4bbdfSmrg           "depth: %d\n",
33135c4bbdfSmrg           (int) pScreenPriv->pbmih->biWidth,
33235c4bbdfSmrg           (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount);
33335c4bbdfSmrg
33435c4bbdfSmrg    /* Create a DI shadow bitmap with a bit pointer */
33535c4bbdfSmrg    pScreenPriv->hbmpShadow = CreateDIBSection(pScreenPriv->hdcScreen,
33635c4bbdfSmrg                                               (BITMAPINFO *) pScreenPriv->
33735c4bbdfSmrg                                               pbmih, DIB_RGB_COLORS,
33835c4bbdfSmrg                                               (VOID **) &pScreenInfo->pfb,
33935c4bbdfSmrg                                               NULL, 0);
34035c4bbdfSmrg    if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) {
34135c4bbdfSmrg        winW32Error(2, "winAllocateFBShadowGDI - CreateDIBSection failed:");
34235c4bbdfSmrg        return FALSE;
34305b261ecSmrg    }
34435c4bbdfSmrg    else {
34505b261ecSmrg#if CYGDEBUG
34635c4bbdfSmrg        winDebug("winAllocateFBShadowGDI - Shadow buffer allocated\n");
34705b261ecSmrg#endif
34805b261ecSmrg    }
34905b261ecSmrg
35035c4bbdfSmrg    /* Get information about the bitmap that was allocated */
35135c4bbdfSmrg    GetObject(pScreenPriv->hbmpShadow, sizeof(dibsection), &dibsection);
35205b261ecSmrg
35305b261ecSmrg#if CYGDEBUG || YES
35435c4bbdfSmrg    /* Print information about bitmap allocated */
35535c4bbdfSmrg    winDebug("winAllocateFBShadowGDI - Dibsection width: %d height: %d "
35635c4bbdfSmrg             "depth: %d size image: %d\n",
35735c4bbdfSmrg             (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight,
35835c4bbdfSmrg             dibsection.dsBmih.biBitCount, (int) dibsection.dsBmih.biSizeImage);
35905b261ecSmrg#endif
36005b261ecSmrg
36135c4bbdfSmrg    /* Select the shadow bitmap into the shadow DC */
36235c4bbdfSmrg    SelectObject(pScreenPriv->hdcShadow, pScreenPriv->hbmpShadow);
36305b261ecSmrg
36405b261ecSmrg#if CYGDEBUG
36535c4bbdfSmrg    winDebug("winAllocateFBShadowGDI - Attempting a shadow blit\n");
36605b261ecSmrg#endif
36705b261ecSmrg
36835c4bbdfSmrg    /* Do a test blit from the shadow to the screen, I think */
36935c4bbdfSmrg    fReturn = BitBlt(pScreenPriv->hdcScreen,
37035c4bbdfSmrg                     0, 0,
37135c4bbdfSmrg                     pScreenInfo->dwWidth, pScreenInfo->dwHeight,
37235c4bbdfSmrg                     pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
37335c4bbdfSmrg    if (fReturn) {
37405b261ecSmrg#if CYGDEBUG
37535c4bbdfSmrg        winDebug("winAllocateFBShadowGDI - Shadow blit success\n");
37605b261ecSmrg#endif
37705b261ecSmrg    }
37835c4bbdfSmrg    else {
37935c4bbdfSmrg        winW32Error(2, "winAllocateFBShadowGDI - Shadow blit failure\n");
38035c4bbdfSmrg#if 0
38135c4bbdfSmrg        return FALSE;
38235c4bbdfSmrg#else
38335c4bbdfSmrg        /* ago: ignore this error. The blit fails with wine, but does not
38435c4bbdfSmrg         * cause any problems later. */
38535c4bbdfSmrg
38635c4bbdfSmrg        fReturn = TRUE;
38735c4bbdfSmrg#endif
38805b261ecSmrg    }
38905b261ecSmrg
39035c4bbdfSmrg    /* Look for height weirdness */
39135c4bbdfSmrg    if (dibsection.dsBmih.biHeight < 0) {
39235c4bbdfSmrg        dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight;
39305b261ecSmrg    }
39405b261ecSmrg
39535c4bbdfSmrg    /* Set screeninfo stride */
39635c4bbdfSmrg    pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage
39735c4bbdfSmrg                              / dibsection.dsBmih.biHeight)
39835c4bbdfSmrg                             * 8) / pScreenInfo->dwBPP;
39905b261ecSmrg
40005b261ecSmrg#if CYGDEBUG || YES
40135c4bbdfSmrg    winDebug("winAllocateFBShadowGDI - Created shadow stride: %d\n",
40235c4bbdfSmrg             (int) pScreenInfo->dwStride);
40305b261ecSmrg#endif
40405b261ecSmrg
40535c4bbdfSmrg    /* Redraw all windows */
40635c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
40735c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
40805b261ecSmrg
40935c4bbdfSmrg    return fReturn;
41005b261ecSmrg}
41105b261ecSmrg
4129ace9065Smrgstatic void
41335c4bbdfSmrgwinFreeFBShadowGDI(ScreenPtr pScreen)
4149ace9065Smrg{
41535c4bbdfSmrg    winScreenPriv(pScreen);
41635c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
4179ace9065Smrg
41835c4bbdfSmrg    /* Free the shadow bitmap */
41935c4bbdfSmrg    DeleteObject(pScreenPriv->hbmpShadow);
4209ace9065Smrg
42135c4bbdfSmrg    /* Invalidate the ScreenInfo's fb pointer */
42235c4bbdfSmrg    pScreenInfo->pfb = NULL;
4239ace9065Smrg}
42405b261ecSmrg
42505b261ecSmrg/*
42605b261ecSmrg * Blit the damaged regions of the shadow fb to the screen
42705b261ecSmrg */
42805b261ecSmrg
42905b261ecSmrgstatic void
43035c4bbdfSmrgwinShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf)
43105b261ecSmrg{
43235c4bbdfSmrg    winScreenPriv(pScreen);
43335c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
4341b5d61b8Smrg    RegionPtr damage = DamageRegion(pBuf->pDamage);
43535c4bbdfSmrg    DWORD dwBox = RegionNumRects(damage);
43635c4bbdfSmrg    BoxPtr pBox = RegionRects(damage);
43735c4bbdfSmrg    int x, y, w, h;
43835c4bbdfSmrg    HRGN hrgnCombined = NULL;
43935c4bbdfSmrg
44005b261ecSmrg#ifdef XWIN_UPDATESTATS
44135c4bbdfSmrg    static DWORD s_dwNonUnitRegions = 0;
44235c4bbdfSmrg    static DWORD s_dwTotalUpdates = 0;
44335c4bbdfSmrg    static DWORD s_dwTotalBoxes = 0;
44405b261ecSmrg#endif
44535c4bbdfSmrg    BoxPtr pBoxExtents = RegionExtents(damage);
44605b261ecSmrg
44735c4bbdfSmrg    /*
44835c4bbdfSmrg     * Return immediately if the app is not active
44935c4bbdfSmrg     * and we are fullscreen, or if we have a bad display depth
45035c4bbdfSmrg     */
45135c4bbdfSmrg    if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
45235c4bbdfSmrg        || pScreenPriv->fBadDepth)
45335c4bbdfSmrg        return;
45405b261ecSmrg
45505b261ecSmrg#ifdef XWIN_UPDATESTATS
45635c4bbdfSmrg    ++s_dwTotalUpdates;
45735c4bbdfSmrg    s_dwTotalBoxes += dwBox;
45805b261ecSmrg
45935c4bbdfSmrg    if (dwBox != 1) {
46035c4bbdfSmrg        ++s_dwNonUnitRegions;
46135c4bbdfSmrg        ErrorF("winShadowUpdatGDI - dwBox: %d\n", dwBox);
46205b261ecSmrg    }
46335c4bbdfSmrg
46435c4bbdfSmrg    if ((s_dwTotalUpdates % 100) == 0)
46535c4bbdfSmrg        ErrorF("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d "
46635c4bbdfSmrg               "nu: %d tu: %d\n",
46735c4bbdfSmrg               (s_dwNonUnitRegions * 100) / s_dwTotalUpdates,
46835c4bbdfSmrg               s_dwTotalBoxes / s_dwTotalUpdates,
46935c4bbdfSmrg               s_dwNonUnitRegions, s_dwTotalUpdates);
47035c4bbdfSmrg#endif                          /* XWIN_UPDATESTATS */
47135c4bbdfSmrg
47235c4bbdfSmrg    /*
47335c4bbdfSmrg     * Handle small regions with multiple blits,
47435c4bbdfSmrg     * handle large regions by creating a clipping region and
47535c4bbdfSmrg     * doing a single blit constrained to that clipping region.
47635c4bbdfSmrg     */
47735c4bbdfSmrg    if (!pScreenInfo->fMultiWindow &&
47835c4bbdfSmrg        (pScreenInfo->dwClipUpdatesNBoxes == 0 ||
47935c4bbdfSmrg         dwBox < pScreenInfo->dwClipUpdatesNBoxes)) {
48035c4bbdfSmrg        /* Loop through all boxes in the damaged region */
48135c4bbdfSmrg        while (dwBox--) {
48235c4bbdfSmrg            /*
48335c4bbdfSmrg             * Calculate x offset, y offset, width, and height for
48435c4bbdfSmrg             * current damage box
48535c4bbdfSmrg             */
48635c4bbdfSmrg            x = pBox->x1;
48735c4bbdfSmrg            y = pBox->y1;
48835c4bbdfSmrg            w = pBox->x2 - pBox->x1;
48935c4bbdfSmrg            h = pBox->y2 - pBox->y1;
49035c4bbdfSmrg
49135c4bbdfSmrg            BitBlt(pScreenPriv->hdcScreen,
49235c4bbdfSmrg                   x, y, w, h, pScreenPriv->hdcShadow, x, y, SRCCOPY);
49335c4bbdfSmrg
49435c4bbdfSmrg            /* Get a pointer to the next box */
49535c4bbdfSmrg            ++pBox;
49635c4bbdfSmrg        }
49705b261ecSmrg    }
49835c4bbdfSmrg    else if (!pScreenInfo->fMultiWindow) {
49935c4bbdfSmrg
50035c4bbdfSmrg        /* Compute a GDI region from the damaged region */
50135c4bbdfSmrg        hrgnCombined =
50235c4bbdfSmrg            CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
50335c4bbdfSmrg                          pBoxExtents->y2);
50435c4bbdfSmrg
50535c4bbdfSmrg        /* Install the GDI region as a clipping region */
50635c4bbdfSmrg        SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
50735c4bbdfSmrg        DeleteObject(hrgnCombined);
50835c4bbdfSmrg        hrgnCombined = NULL;
50935c4bbdfSmrg
51035c4bbdfSmrg        /*
51135c4bbdfSmrg         * Blit the shadow buffer to the screen,
51235c4bbdfSmrg         * constrained to the clipping region.
51335c4bbdfSmrg         */
51435c4bbdfSmrg        BitBlt(pScreenPriv->hdcScreen,
51535c4bbdfSmrg               pBoxExtents->x1, pBoxExtents->y1,
51635c4bbdfSmrg               pBoxExtents->x2 - pBoxExtents->x1,
51735c4bbdfSmrg               pBoxExtents->y2 - pBoxExtents->y1,
51835c4bbdfSmrg               pScreenPriv->hdcShadow,
51935c4bbdfSmrg               pBoxExtents->x1, pBoxExtents->y1, SRCCOPY);
52035c4bbdfSmrg
52135c4bbdfSmrg        /* Reset the clip region */
52235c4bbdfSmrg        SelectClipRgn(pScreenPriv->hdcScreen, NULL);
52305b261ecSmrg    }
52405b261ecSmrg
52535c4bbdfSmrg    /* Redraw all multiwindow windows */
52635c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
52735c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID,
52835c4bbdfSmrg                          winRedrawDamagedWindowShadowGDI,
52935c4bbdfSmrg                          (LPARAM) pBoxExtents);
53005b261ecSmrg}
53105b261ecSmrg
5329ace9065Smrgstatic Bool
53335c4bbdfSmrgwinInitScreenShadowGDI(ScreenPtr pScreen)
5349ace9065Smrg{
53535c4bbdfSmrg    winScreenPriv(pScreen);
53635c4bbdfSmrg
53735c4bbdfSmrg    /* Get device contexts for the screen and shadow bitmap */
53835c4bbdfSmrg    pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen);
53935c4bbdfSmrg    pScreenPriv->hdcShadow = CreateCompatibleDC(pScreenPriv->hdcScreen);
54035c4bbdfSmrg
54135c4bbdfSmrg    /* Allocate bitmap info header */
54235c4bbdfSmrg    pScreenPriv->pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
54335c4bbdfSmrg    if (pScreenPriv->pbmih == NULL) {
54435c4bbdfSmrg        ErrorF("winInitScreenShadowGDI - malloc () failed\n");
54535c4bbdfSmrg        return FALSE;
5469ace9065Smrg    }
5479ace9065Smrg
54835c4bbdfSmrg    /* Query the screen format */
54935c4bbdfSmrg    if (!winQueryScreenDIBFormat(pScreen, pScreenPriv->pbmih)) {
55035c4bbdfSmrg        ErrorF("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n");
55135c4bbdfSmrg        return FALSE;
5529ace9065Smrg    }
5539ace9065Smrg
55435c4bbdfSmrg    /* Determine our color masks */
55535c4bbdfSmrg    if (!winQueryRGBBitsAndMasks(pScreen)) {
55635c4bbdfSmrg        ErrorF("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n");
55735c4bbdfSmrg        return FALSE;
5589ace9065Smrg    }
5599ace9065Smrg
56035c4bbdfSmrg    return winAllocateFBShadowGDI(pScreen);
5619ace9065Smrg}
5629ace9065Smrg
56305b261ecSmrg/* See Porting Layer Definition - p. 33 */
56405b261ecSmrg/*
56505b261ecSmrg * We wrap whatever CloseScreen procedure was specified by fb;
56605b261ecSmrg * a pointer to said procedure is stored in our privates.
56705b261ecSmrg */
56805b261ecSmrg
56905b261ecSmrgstatic Bool
57035c4bbdfSmrgwinCloseScreenShadowGDI(ScreenPtr pScreen)
57105b261ecSmrg{
57235c4bbdfSmrg    winScreenPriv(pScreen);
57335c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
5741b5d61b8Smrg    Bool fReturn = TRUE;
57505b261ecSmrg
57605b261ecSmrg#if CYGDEBUG
57735c4bbdfSmrg    winDebug("winCloseScreenShadowGDI - Freeing screen resources\n");
57805b261ecSmrg#endif
57905b261ecSmrg
58035c4bbdfSmrg    /* Flag that the screen is closed */
58135c4bbdfSmrg    pScreenPriv->fClosed = TRUE;
58235c4bbdfSmrg    pScreenPriv->fActive = FALSE;
58305b261ecSmrg
58435c4bbdfSmrg    /* Call the wrapped CloseScreen procedure */
58535c4bbdfSmrg    WIN_UNWRAP(CloseScreen);
58635c4bbdfSmrg    if (pScreen->CloseScreen)
58735c4bbdfSmrg        fReturn = (*pScreen->CloseScreen) (pScreen);
58805b261ecSmrg
58935c4bbdfSmrg    /* Delete the window property */
59035c4bbdfSmrg    RemoveProp(pScreenPriv->hwndScreen, WIN_SCR_PROP);
59105b261ecSmrg
59235c4bbdfSmrg    /* Free the shadow DC; which allows the bitmap to be freed */
59335c4bbdfSmrg    DeleteDC(pScreenPriv->hdcShadow);
5949ace9065Smrg
59535c4bbdfSmrg    winFreeFBShadowGDI(pScreen);
59605b261ecSmrg
59735c4bbdfSmrg    /* Free the screen DC */
59835c4bbdfSmrg    ReleaseDC(pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
59905b261ecSmrg
60035c4bbdfSmrg    /* Delete tray icon, if we have one */
60135c4bbdfSmrg    if (!pScreenInfo->fNoTrayIcon)
60235c4bbdfSmrg        winDeleteNotifyIcon(pScreenPriv);
60305b261ecSmrg
60435c4bbdfSmrg    /* Free the exit confirmation dialog box, if it exists */
60535c4bbdfSmrg    if (g_hDlgExit != NULL) {
60635c4bbdfSmrg        DestroyWindow(g_hDlgExit);
60735c4bbdfSmrg        g_hDlgExit = NULL;
60805b261ecSmrg    }
60905b261ecSmrg
61035c4bbdfSmrg    /* Kill our window */
61135c4bbdfSmrg    if (pScreenPriv->hwndScreen) {
61235c4bbdfSmrg        DestroyWindow(pScreenPriv->hwndScreen);
61335c4bbdfSmrg        pScreenPriv->hwndScreen = NULL;
61405b261ecSmrg    }
61505b261ecSmrg
61635c4bbdfSmrg    /* Destroy the thread startup mutex */
61735c4bbdfSmrg    pthread_mutex_destroy(&pScreenPriv->pmServerStarted);
61805b261ecSmrg
61935c4bbdfSmrg    /* Invalidate our screeninfo's pointer to the screen */
62035c4bbdfSmrg    pScreenInfo->pScreen = NULL;
62105b261ecSmrg
62235c4bbdfSmrg    /* Free the screen privates for this screen */
62335c4bbdfSmrg    free((void *) pScreenPriv);
62405b261ecSmrg
62535c4bbdfSmrg    return fReturn;
62605b261ecSmrg}
62705b261ecSmrg
62805b261ecSmrg/*
62905b261ecSmrg * Tell mi what sort of visuals we need.
63035c4bbdfSmrg *
63105b261ecSmrg * Generally we only need one visual, as our screen can only
63205b261ecSmrg * handle one format at a time, I believe.  You may want
63305b261ecSmrg * to verify that last sentence.
63405b261ecSmrg */
63505b261ecSmrg
63605b261ecSmrgstatic Bool
63735c4bbdfSmrgwinInitVisualsShadowGDI(ScreenPtr pScreen)
63805b261ecSmrg{
63935c4bbdfSmrg    winScreenPriv(pScreen);
64035c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
64135c4bbdfSmrg
64235c4bbdfSmrg    /* Display debugging information */
64335c4bbdfSmrg    ErrorF("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d "
64435c4bbdfSmrg           "bpp %d\n",
64535c4bbdfSmrg           (unsigned int) pScreenPriv->dwRedMask,
64635c4bbdfSmrg           (unsigned int) pScreenPriv->dwGreenMask,
64735c4bbdfSmrg           (unsigned int) pScreenPriv->dwBlueMask,
64835c4bbdfSmrg           (int) pScreenPriv->dwBitsPerRGB,
64935c4bbdfSmrg           (int) pScreenInfo->dwDepth, (int) pScreenInfo->dwBPP);
65035c4bbdfSmrg
65135c4bbdfSmrg    /* Create a single visual according to the Windows screen depth */
65235c4bbdfSmrg    switch (pScreenInfo->dwDepth) {
65305b261ecSmrg    case 24:
65405b261ecSmrg    case 16:
65505b261ecSmrg    case 15:
65635c4bbdfSmrg        /* Setup the real visual */
65735c4bbdfSmrg        if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
65835c4bbdfSmrg                                      TrueColorMask,
65935c4bbdfSmrg                                      pScreenPriv->dwBitsPerRGB,
66035c4bbdfSmrg                                      -1,
66135c4bbdfSmrg                                      pScreenPriv->dwRedMask,
66235c4bbdfSmrg                                      pScreenPriv->dwGreenMask,
66335c4bbdfSmrg                                      pScreenPriv->dwBlueMask)) {
66435c4bbdfSmrg            ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
66535c4bbdfSmrg                   "failed\n");
66635c4bbdfSmrg            return FALSE;
66735c4bbdfSmrg        }
66805b261ecSmrg
66905b261ecSmrg#ifdef XWIN_EMULATEPSEUDO
67035c4bbdfSmrg        if (!pScreenInfo->fEmulatePseudo)
67135c4bbdfSmrg            break;
67235c4bbdfSmrg
67335c4bbdfSmrg        /* Setup a pseudocolor visual */
67435c4bbdfSmrg        if (!miSetVisualTypesAndMasks(8, PseudoColorMask, 8, -1, 0, 0, 0)) {
67535c4bbdfSmrg            ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
67635c4bbdfSmrg                   "failed for PseudoColor\n");
67735c4bbdfSmrg            return FALSE;
67835c4bbdfSmrg        }
67905b261ecSmrg#endif
68035c4bbdfSmrg        break;
68105b261ecSmrg
68205b261ecSmrg    case 8:
68335c4bbdfSmrg        if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
68435c4bbdfSmrg                                      PseudoColorMask,
68535c4bbdfSmrg                                      pScreenPriv->dwBitsPerRGB,
68635c4bbdfSmrg                                      PseudoColor,
68735c4bbdfSmrg                                      pScreenPriv->dwRedMask,
68835c4bbdfSmrg                                      pScreenPriv->dwGreenMask,
68935c4bbdfSmrg                                      pScreenPriv->dwBlueMask)) {
69035c4bbdfSmrg            ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
69135c4bbdfSmrg                   "failed\n");
69235c4bbdfSmrg            return FALSE;
69335c4bbdfSmrg        }
69435c4bbdfSmrg        break;
69505b261ecSmrg
69605b261ecSmrg    default:
69735c4bbdfSmrg        ErrorF("winInitVisualsShadowGDI - Unknown screen depth\n");
69835c4bbdfSmrg        return FALSE;
69905b261ecSmrg    }
70005b261ecSmrg
70105b261ecSmrg#if CYGDEBUG
70235c4bbdfSmrg    winDebug("winInitVisualsShadowGDI - Returning\n");
70305b261ecSmrg#endif
70405b261ecSmrg
70535c4bbdfSmrg    return TRUE;
70605b261ecSmrg}
70705b261ecSmrg
70805b261ecSmrg/*
70905b261ecSmrg * Adjust the proposed video mode
71005b261ecSmrg */
71105b261ecSmrg
71205b261ecSmrgstatic Bool
71335c4bbdfSmrgwinAdjustVideoModeShadowGDI(ScreenPtr pScreen)
71405b261ecSmrg{
71535c4bbdfSmrg    winScreenPriv(pScreen);
71635c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
71735c4bbdfSmrg    HDC hdc;
71835c4bbdfSmrg    DWORD dwBPP;
71935c4bbdfSmrg
72035c4bbdfSmrg    hdc = GetDC(NULL);
72135c4bbdfSmrg
72235c4bbdfSmrg    /* We're in serious trouble if we can't get a DC */
72335c4bbdfSmrg    if (hdc == NULL) {
72435c4bbdfSmrg        ErrorF("winAdjustVideoModeShadowGDI - GetDC () failed\n");
72535c4bbdfSmrg        return FALSE;
72605b261ecSmrg    }
72705b261ecSmrg
72835c4bbdfSmrg    /* Query GDI for current display depth */
72935c4bbdfSmrg    dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
73005b261ecSmrg
73135c4bbdfSmrg    /* GDI cannot change the screen depth, so always use GDI's depth */
73235c4bbdfSmrg    pScreenInfo->dwBPP = dwBPP;
73305b261ecSmrg
73435c4bbdfSmrg    /* Release our DC */
73535c4bbdfSmrg    ReleaseDC(NULL, hdc);
73635c4bbdfSmrg    hdc = NULL;
73705b261ecSmrg
73835c4bbdfSmrg    return TRUE;
73905b261ecSmrg}
74005b261ecSmrg
74105b261ecSmrg/*
74205b261ecSmrg * Blt exposed regions to the screen
74305b261ecSmrg */
74405b261ecSmrg
74505b261ecSmrgstatic Bool
74635c4bbdfSmrgwinBltExposedRegionsShadowGDI(ScreenPtr pScreen)
74705b261ecSmrg{
74835c4bbdfSmrg    winScreenPriv(pScreen);
74935c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
75035c4bbdfSmrg    winPrivCmapPtr pCmapPriv = NULL;
75135c4bbdfSmrg    HDC hdcUpdate;
75235c4bbdfSmrg    PAINTSTRUCT ps;
75335c4bbdfSmrg
75435c4bbdfSmrg    /* BeginPaint gives us an hdc that clips to the invalidated region */
75535c4bbdfSmrg    hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps);
756ed6184dfSmrg    /* Avoid the BitBlt if the PAINTSTRUCT region is bogus */
757ed6184dfSmrg    if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 &&
758ed6184dfSmrg        ps.rcPaint.left == 0 && ps.rcPaint.top == 0) {
759ed6184dfSmrg        EndPaint(pScreenPriv->hwndScreen, &ps);
760ed6184dfSmrg        return 0;
761ed6184dfSmrg    }
76235c4bbdfSmrg
76335c4bbdfSmrg    /* Realize the palette, if we have one */
76435c4bbdfSmrg    if (pScreenPriv->pcmapInstalled != NULL) {
76535c4bbdfSmrg        pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled);
76635c4bbdfSmrg
76735c4bbdfSmrg        SelectPalette(hdcUpdate, pCmapPriv->hPalette, FALSE);
76835c4bbdfSmrg        RealizePalette(hdcUpdate);
76905b261ecSmrg    }
77005b261ecSmrg
771ed6184dfSmrg    /* Try to copy from the shadow buffer to the invalidated region */
772ed6184dfSmrg    if (!BitBlt(hdcUpdate,
773ed6184dfSmrg                ps.rcPaint.left, ps.rcPaint.top,
774ed6184dfSmrg                ps.rcPaint.right - ps.rcPaint.left,
775ed6184dfSmrg                ps.rcPaint.bottom - ps.rcPaint.top,
776ed6184dfSmrg                pScreenPriv->hdcShadow,
777ed6184dfSmrg                ps.rcPaint.left,
778ed6184dfSmrg                ps.rcPaint.top,
779ed6184dfSmrg                SRCCOPY)) {
780ed6184dfSmrg        LPVOID lpMsgBuf;
781ed6184dfSmrg
782ed6184dfSmrg        /* Display an error message */
783ed6184dfSmrg        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
784ed6184dfSmrg                      FORMAT_MESSAGE_FROM_SYSTEM |
785ed6184dfSmrg                      FORMAT_MESSAGE_IGNORE_INSERTS,
786ed6184dfSmrg                      NULL,
787ed6184dfSmrg                      GetLastError(),
788ed6184dfSmrg                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
789ed6184dfSmrg                      (LPTSTR) &lpMsgBuf, 0, NULL);
790ed6184dfSmrg
791ed6184dfSmrg        ErrorF("winBltExposedRegionsShadowGDI - BitBlt failed: %s\n",
792ed6184dfSmrg               (LPSTR) lpMsgBuf);
793ed6184dfSmrg        LocalFree(lpMsgBuf);
794ed6184dfSmrg    }
79505b261ecSmrg
79635c4bbdfSmrg    /* EndPaint frees the DC */
79735c4bbdfSmrg    EndPaint(pScreenPriv->hwndScreen, &ps);
79805b261ecSmrg
79935c4bbdfSmrg    /* Redraw all windows */
80035c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
80135c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI,
80235c4bbdfSmrg                          (LPARAM) pScreenPriv->hwndScreen);
80305b261ecSmrg
80435c4bbdfSmrg    return TRUE;
80505b261ecSmrg}
80605b261ecSmrg
807ed6184dfSmrg/*
808ed6184dfSmrg * Blt exposed region to the given HWND
809ed6184dfSmrg */
810ed6184dfSmrg
811ed6184dfSmrgstatic Bool
812ed6184dfSmrgwinBltExposedWindowRegionShadowGDI(ScreenPtr pScreen, WindowPtr pWin)
813ed6184dfSmrg{
814ed6184dfSmrg    winScreenPriv(pScreen);
815ed6184dfSmrg    winPrivWinPtr pWinPriv = winGetWindowPriv(pWin);
816ed6184dfSmrg
817ed6184dfSmrg    HWND hWnd = pWinPriv->hWnd;
818ed6184dfSmrg    HDC hdcUpdate;
819ed6184dfSmrg    PAINTSTRUCT ps;
820ed6184dfSmrg
821ed6184dfSmrg    hdcUpdate = BeginPaint(hWnd, &ps);
822ed6184dfSmrg    /* Avoid the BitBlt if the PAINTSTRUCT region is bogus */
823ed6184dfSmrg    if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 &&
824ed6184dfSmrg        ps.rcPaint.left == 0 && ps.rcPaint.top == 0) {
825ed6184dfSmrg        EndPaint(hWnd, &ps);
826ed6184dfSmrg        return 0;
827ed6184dfSmrg    }
828ed6184dfSmrg
829ed6184dfSmrg#ifdef COMPOSITE
830ed6184dfSmrg    if (pWin->redirectDraw != RedirectDrawNone) {
831ed6184dfSmrg        HBITMAP hBitmap;
832ed6184dfSmrg        HDC hdcPixmap;
833ed6184dfSmrg        PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
834ed6184dfSmrg        winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap);
835ed6184dfSmrg
836ed6184dfSmrg        /* window pixmap format is the same as the screen pixmap */
837ed6184dfSmrg        assert(pPixmap->drawable.bitsPerPixel > 8);
838ed6184dfSmrg
839ed6184dfSmrg        /* Get the window bitmap from the pixmap */
840ed6184dfSmrg        hBitmap = pPixmapPriv->hBitmap;
841ed6184dfSmrg
842ed6184dfSmrg        /* XXX: There may be a need for a slow-path here: If hBitmap is NULL
843ed6184dfSmrg           (because we couldn't back the pixmap with a Windows DIB), we should
844ed6184dfSmrg           fall-back to creating a Windows DIB from the pixmap, then deleting it
845ed6184dfSmrg           after the BitBlt (as this this code did before the fast-path was
846ed6184dfSmrg           added). */
847ed6184dfSmrg        if (!hBitmap) {
848ed6184dfSmrg            ErrorF("winBltExposedWindowRegionShadowGDI - slow path unimplemented\n");
849ed6184dfSmrg        }
850ed6184dfSmrg
851ed6184dfSmrg        /* Select the window bitmap into a screen-compatible DC */
852ed6184dfSmrg        hdcPixmap = CreateCompatibleDC(pScreenPriv->hdcScreen);
853ed6184dfSmrg        SelectObject(hdcPixmap, hBitmap);
854ed6184dfSmrg
855ed6184dfSmrg        /* Blt from the window bitmap to the invalidated region */
856ed6184dfSmrg        if (!BitBlt(hdcUpdate,
857ed6184dfSmrg                    ps.rcPaint.left, ps.rcPaint.top,
858ed6184dfSmrg                    ps.rcPaint.right - ps.rcPaint.left,
859ed6184dfSmrg                    ps.rcPaint.bottom - ps.rcPaint.top,
860ed6184dfSmrg                    hdcPixmap,
861ed6184dfSmrg                    ps.rcPaint.left + pWin->borderWidth,
862ed6184dfSmrg                    ps.rcPaint.top + pWin->borderWidth,
863ed6184dfSmrg                    SRCCOPY))
864ed6184dfSmrg            ErrorF("winBltExposedWindowRegionShadowGDI - BitBlt failed: 0x%08x\n",
865ed6184dfSmrg                   GetLastError());
866ed6184dfSmrg
867ed6184dfSmrg        /* Release DC */
868ed6184dfSmrg        DeleteDC(hdcPixmap);
869ed6184dfSmrg    }
870ed6184dfSmrg    else
871ed6184dfSmrg#endif
872ed6184dfSmrg    {
873ed6184dfSmrg    /* Try to copy from the shadow buffer to the invalidated region */
874ed6184dfSmrg    if (!BitBlt(hdcUpdate,
875ed6184dfSmrg                ps.rcPaint.left, ps.rcPaint.top,
876ed6184dfSmrg                ps.rcPaint.right - ps.rcPaint.left,
877ed6184dfSmrg                ps.rcPaint.bottom - ps.rcPaint.top,
878ed6184dfSmrg                pScreenPriv->hdcShadow,
879ed6184dfSmrg                ps.rcPaint.left + pWin->drawable.x,
880ed6184dfSmrg                ps.rcPaint.top + pWin->drawable.y,
881ed6184dfSmrg                SRCCOPY)) {
882ed6184dfSmrg        LPVOID lpMsgBuf;
883ed6184dfSmrg
884ed6184dfSmrg        /* Display an error message */
885ed6184dfSmrg        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
886ed6184dfSmrg                      FORMAT_MESSAGE_FROM_SYSTEM |
887ed6184dfSmrg                      FORMAT_MESSAGE_IGNORE_INSERTS,
888ed6184dfSmrg                      NULL,
889ed6184dfSmrg                      GetLastError(),
890ed6184dfSmrg                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
891ed6184dfSmrg                      (LPTSTR) &lpMsgBuf, 0, NULL);
892ed6184dfSmrg
893ed6184dfSmrg        ErrorF("winBltExposedWindowRegionShadowGDI - BitBlt failed: %s\n",
894ed6184dfSmrg               (LPSTR) lpMsgBuf);
895ed6184dfSmrg        LocalFree(lpMsgBuf);
896ed6184dfSmrg    }
897ed6184dfSmrg    }
898ed6184dfSmrg
899ed6184dfSmrg    /* If part of the invalidated region is outside the window (which can happen
900ed6184dfSmrg       if the native window is being re-sized), fill that area with black */
901ed6184dfSmrg    if (ps.rcPaint.right > ps.rcPaint.left + pWin->drawable.width) {
902ed6184dfSmrg        BitBlt(hdcUpdate,
903ed6184dfSmrg               ps.rcPaint.left + pWin->drawable.width,
904ed6184dfSmrg               ps.rcPaint.top,
905ed6184dfSmrg               ps.rcPaint.right - (ps.rcPaint.left + pWin->drawable.width),
906ed6184dfSmrg               ps.rcPaint.bottom - ps.rcPaint.top,
907ed6184dfSmrg               NULL,
908ed6184dfSmrg               0, 0,
909ed6184dfSmrg               BLACKNESS);
910ed6184dfSmrg    }
911ed6184dfSmrg
912ed6184dfSmrg    if (ps.rcPaint.bottom > ps.rcPaint.top + pWin->drawable.height) {
913ed6184dfSmrg        BitBlt(hdcUpdate,
914ed6184dfSmrg               ps.rcPaint.left,
915ed6184dfSmrg               ps.rcPaint.top + pWin->drawable.height,
916ed6184dfSmrg               ps.rcPaint.right - ps.rcPaint.left,
917ed6184dfSmrg               ps.rcPaint.bottom - (ps.rcPaint.top + pWin->drawable.height),
918ed6184dfSmrg               NULL,
919ed6184dfSmrg               0, 0,
920ed6184dfSmrg               BLACKNESS);
921ed6184dfSmrg    }
922ed6184dfSmrg
923ed6184dfSmrg    /* EndPaint frees the DC */
924ed6184dfSmrg    EndPaint(hWnd, &ps);
925ed6184dfSmrg
926ed6184dfSmrg    return TRUE;
927ed6184dfSmrg}
928ed6184dfSmrg
92905b261ecSmrg/*
93005b261ecSmrg * Do any engine-specific appliation-activation processing
93105b261ecSmrg */
93205b261ecSmrg
93305b261ecSmrgstatic Bool
93435c4bbdfSmrgwinActivateAppShadowGDI(ScreenPtr pScreen)
93505b261ecSmrg{
93635c4bbdfSmrg    winScreenPriv(pScreen);
93735c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
93835c4bbdfSmrg
93935c4bbdfSmrg    /*
94035c4bbdfSmrg     * 2004/04/12 - Harold - We perform the restoring or minimizing
94135c4bbdfSmrg     * manually for ShadowGDI in fullscreen modes so that this engine
94235c4bbdfSmrg     * will perform just like ShadowDD and ShadowDDNL in fullscreen mode;
94335c4bbdfSmrg     * if we do not do this then our fullscreen window will appear in the
94435c4bbdfSmrg     * z-order when it is deactivated and it can be uncovered by resizing
94535c4bbdfSmrg     * or minimizing another window that is on top of it, which is not how
94635c4bbdfSmrg     * the DirectDraw engines work.  Therefore we keep this code here to
94735c4bbdfSmrg     * make sure that all engines work the same in fullscreen mode.
94835c4bbdfSmrg     */
94935c4bbdfSmrg
95035c4bbdfSmrg    /*
95135c4bbdfSmrg     * Are we active?
95235c4bbdfSmrg     * Are we fullscreen?
95335c4bbdfSmrg     */
95435c4bbdfSmrg    if (pScreenPriv->fActive && pScreenInfo->fFullScreen) {
95535c4bbdfSmrg        /*
95635c4bbdfSmrg         * Activating, attempt to bring our window
95735c4bbdfSmrg         * to the top of the display
95835c4bbdfSmrg         */
95935c4bbdfSmrg        ShowWindow(pScreenPriv->hwndScreen, SW_RESTORE);
96005b261ecSmrg    }
96135c4bbdfSmrg    else if (!pScreenPriv->fActive && pScreenInfo->fFullScreen) {
96235c4bbdfSmrg        /*
96335c4bbdfSmrg         * Deactivating, stuff our window onto the
96435c4bbdfSmrg         * task bar.
96535c4bbdfSmrg         */
96635c4bbdfSmrg        ShowWindow(pScreenPriv->hwndScreen, SW_MINIMIZE);
96705b261ecSmrg    }
96805b261ecSmrg
96935c4bbdfSmrg    return TRUE;
97005b261ecSmrg}
97105b261ecSmrg
97205b261ecSmrg/*
97305b261ecSmrg * Reblit the shadow framebuffer to the screen.
97405b261ecSmrg */
97505b261ecSmrg
97605b261ecSmrgstatic Bool
97735c4bbdfSmrgwinRedrawScreenShadowGDI(ScreenPtr pScreen)
97805b261ecSmrg{
97935c4bbdfSmrg    winScreenPriv(pScreen);
98035c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
98105b261ecSmrg
98235c4bbdfSmrg    /* Redraw the whole window, to take account for the new colors */
98335c4bbdfSmrg    BitBlt(pScreenPriv->hdcScreen,
98435c4bbdfSmrg           0, 0,
98535c4bbdfSmrg           pScreenInfo->dwWidth, pScreenInfo->dwHeight,
98635c4bbdfSmrg           pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
98705b261ecSmrg
98835c4bbdfSmrg    /* Redraw all windows */
98935c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
99035c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
99105b261ecSmrg
99235c4bbdfSmrg    return TRUE;
99305b261ecSmrg}
99405b261ecSmrg
99505b261ecSmrg/*
99605b261ecSmrg * Realize the currently installed colormap
99705b261ecSmrg */
99805b261ecSmrg
99905b261ecSmrgstatic Bool
100035c4bbdfSmrgwinRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen)
100105b261ecSmrg{
100235c4bbdfSmrg    winScreenPriv(pScreen);
100335c4bbdfSmrg    winPrivCmapPtr pCmapPriv = NULL;
100405b261ecSmrg
100505b261ecSmrg#if CYGDEBUG
100635c4bbdfSmrg    winDebug("winRealizeInstalledPaletteShadowGDI\n");
100705b261ecSmrg#endif
100805b261ecSmrg
100935c4bbdfSmrg    /* Don't do anything if there is not a colormap */
101035c4bbdfSmrg    if (pScreenPriv->pcmapInstalled == NULL) {
101105b261ecSmrg#if CYGDEBUG
101235c4bbdfSmrg        winDebug("winRealizeInstalledPaletteShadowGDI - No colormap "
101335c4bbdfSmrg                 "installed\n");
101405b261ecSmrg#endif
101535c4bbdfSmrg        return TRUE;
101605b261ecSmrg    }
101705b261ecSmrg
101835c4bbdfSmrg    pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled);
101935c4bbdfSmrg
102035c4bbdfSmrg    /* Realize our palette for the screen */
102135c4bbdfSmrg    if (RealizePalette(pScreenPriv->hdcScreen) == GDI_ERROR) {
102235c4bbdfSmrg        ErrorF("winRealizeInstalledPaletteShadowGDI - RealizePalette () "
102335c4bbdfSmrg               "failed\n");
102435c4bbdfSmrg        return FALSE;
102505b261ecSmrg    }
102635c4bbdfSmrg
102735c4bbdfSmrg    /* Set the DIB color table */
102835c4bbdfSmrg    if (SetDIBColorTable(pScreenPriv->hdcShadow,
102935c4bbdfSmrg                         0,
103035c4bbdfSmrg                         WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) {
103135c4bbdfSmrg        ErrorF("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () "
103235c4bbdfSmrg               "failed\n");
103335c4bbdfSmrg        return FALSE;
103405b261ecSmrg    }
103505b261ecSmrg
103635c4bbdfSmrg    return TRUE;
103735c4bbdfSmrg}
103805b261ecSmrg
103905b261ecSmrg/*
104005b261ecSmrg * Install the specified colormap
104105b261ecSmrg */
104205b261ecSmrg
104305b261ecSmrgstatic Bool
104435c4bbdfSmrgwinInstallColormapShadowGDI(ColormapPtr pColormap)
104505b261ecSmrg{
104635c4bbdfSmrg    ScreenPtr pScreen = pColormap->pScreen;
104735c4bbdfSmrg
104835c4bbdfSmrg    winScreenPriv(pScreen);
104935c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
105035c4bbdfSmrg
105135c4bbdfSmrg    winCmapPriv(pColormap);
105235c4bbdfSmrg
105335c4bbdfSmrg    /*
105435c4bbdfSmrg     * Tell Windows to install the new colormap
105535c4bbdfSmrg     */
105635c4bbdfSmrg    if (SelectPalette(pScreenPriv->hdcScreen,
105735c4bbdfSmrg                      pCmapPriv->hPalette, FALSE) == NULL) {
105835c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - SelectPalette () failed\n");
105935c4bbdfSmrg        return FALSE;
106005b261ecSmrg    }
106135c4bbdfSmrg
106235c4bbdfSmrg    /* Realize the palette */
106335c4bbdfSmrg    if (GDI_ERROR == RealizePalette(pScreenPriv->hdcScreen)) {
106435c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - RealizePalette () failed\n");
106535c4bbdfSmrg        return FALSE;
106605b261ecSmrg    }
106705b261ecSmrg
106835c4bbdfSmrg    /* Set the DIB color table */
106935c4bbdfSmrg    if (SetDIBColorTable(pScreenPriv->hdcShadow,
107035c4bbdfSmrg                         0,
107135c4bbdfSmrg                         WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) {
107235c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
107335c4bbdfSmrg        return FALSE;
107405b261ecSmrg    }
107505b261ecSmrg
107635c4bbdfSmrg    /* Redraw the whole window, to take account for the new colors */
107735c4bbdfSmrg    BitBlt(pScreenPriv->hdcScreen,
107835c4bbdfSmrg           0, 0,
107935c4bbdfSmrg           pScreenInfo->dwWidth, pScreenInfo->dwHeight,
108035c4bbdfSmrg           pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
108105b261ecSmrg
108235c4bbdfSmrg    /* Save a pointer to the newly installed colormap */
108335c4bbdfSmrg    pScreenPriv->pcmapInstalled = pColormap;
108405b261ecSmrg
108535c4bbdfSmrg    /* Redraw all windows */
108635c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
108735c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
108805b261ecSmrg
108935c4bbdfSmrg    return TRUE;
109005b261ecSmrg}
109105b261ecSmrg
109205b261ecSmrg/*
109305b261ecSmrg * Store the specified colors in the specified colormap
109405b261ecSmrg */
109505b261ecSmrg
109605b261ecSmrgstatic Bool
109735c4bbdfSmrgwinStoreColorsShadowGDI(ColormapPtr pColormap, int ndef, xColorItem * pdefs)
109805b261ecSmrg{
109935c4bbdfSmrg    ScreenPtr pScreen = pColormap->pScreen;
110035c4bbdfSmrg
110135c4bbdfSmrg    winScreenPriv(pScreen);
110235c4bbdfSmrg    winCmapPriv(pColormap);
110335c4bbdfSmrg    ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
110435c4bbdfSmrg
110535c4bbdfSmrg    /* Put the X colormap entries into the Windows logical palette */
110635c4bbdfSmrg    if (SetPaletteEntries(pCmapPriv->hPalette,
110735c4bbdfSmrg                          pdefs[0].pixel,
110835c4bbdfSmrg                          ndef, pCmapPriv->peColors + pdefs[0].pixel) == 0) {
110935c4bbdfSmrg        ErrorF("winStoreColorsShadowGDI - SetPaletteEntries () failed\n");
111035c4bbdfSmrg        return FALSE;
111105b261ecSmrg    }
111205b261ecSmrg
111335c4bbdfSmrg    /* Don't install the Windows palette if the colormap is not installed */
111435c4bbdfSmrg    if (pColormap != curpmap) {
111535c4bbdfSmrg        return TRUE;
111605b261ecSmrg    }
111705b261ecSmrg
111835c4bbdfSmrg    /* Try to install the newly modified colormap */
111935c4bbdfSmrg    if (!winInstallColormapShadowGDI(pColormap)) {
112035c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - winInstallColormapShadowGDI "
112135c4bbdfSmrg               "failed\n");
112235c4bbdfSmrg        return FALSE;
112305b261ecSmrg    }
112405b261ecSmrg
112505b261ecSmrg#if 0
112635c4bbdfSmrg    /* Tell Windows that the palette has changed */
112735c4bbdfSmrg    RealizePalette(pScreenPriv->hdcScreen);
112835c4bbdfSmrg
112935c4bbdfSmrg    /* Set the DIB color table */
113035c4bbdfSmrg    if (SetDIBColorTable(pScreenPriv->hdcShadow,
113135c4bbdfSmrg                         pdefs[0].pixel,
113235c4bbdfSmrg                         ndef, pCmapPriv->rgbColors + pdefs[0].pixel) == 0) {
113335c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
113435c4bbdfSmrg        return FALSE;
113505b261ecSmrg    }
113605b261ecSmrg
113735c4bbdfSmrg    /* Save a pointer to the newly installed colormap */
113835c4bbdfSmrg    pScreenPriv->pcmapInstalled = pColormap;
113905b261ecSmrg#endif
114005b261ecSmrg
114135c4bbdfSmrg    return TRUE;
114205b261ecSmrg}
114305b261ecSmrg
114405b261ecSmrg/*
114505b261ecSmrg * Colormap initialization procedure
114605b261ecSmrg */
114705b261ecSmrg
114805b261ecSmrgstatic Bool
114935c4bbdfSmrgwinCreateColormapShadowGDI(ColormapPtr pColormap)
115005b261ecSmrg{
115135c4bbdfSmrg    LPLOGPALETTE lpPaletteNew = NULL;
115235c4bbdfSmrg    DWORD dwEntriesMax;
115335c4bbdfSmrg    VisualPtr pVisual;
115435c4bbdfSmrg    HPALETTE hpalNew = NULL;
115535c4bbdfSmrg
115635c4bbdfSmrg    winCmapPriv(pColormap);
115735c4bbdfSmrg
115835c4bbdfSmrg    /* Get a pointer to the visual that the colormap belongs to */
115935c4bbdfSmrg    pVisual = pColormap->pVisual;
116035c4bbdfSmrg
116135c4bbdfSmrg    /* Get the maximum number of palette entries for this visual */
116235c4bbdfSmrg    dwEntriesMax = pVisual->ColormapEntries;
116335c4bbdfSmrg
116435c4bbdfSmrg    /* Allocate a Windows logical color palette with max entries */
116535c4bbdfSmrg    lpPaletteNew = malloc(sizeof(LOGPALETTE)
116635c4bbdfSmrg                          + (dwEntriesMax - 1) * sizeof(PALETTEENTRY));
116735c4bbdfSmrg    if (lpPaletteNew == NULL) {
116835c4bbdfSmrg        ErrorF("winCreateColormapShadowGDI - Couldn't allocate palette "
116935c4bbdfSmrg               "with %d entries\n", (int) dwEntriesMax);
117035c4bbdfSmrg        return FALSE;
117105b261ecSmrg    }
117205b261ecSmrg
117335c4bbdfSmrg    /* Zero out the colormap */
117435c4bbdfSmrg    ZeroMemory(lpPaletteNew, sizeof(LOGPALETTE)
117535c4bbdfSmrg               + (dwEntriesMax - 1) * sizeof(PALETTEENTRY));
117635c4bbdfSmrg
117735c4bbdfSmrg    /* Set the logical palette structure */
117835c4bbdfSmrg    lpPaletteNew->palVersion = 0x0300;
117935c4bbdfSmrg    lpPaletteNew->palNumEntries = dwEntriesMax;
118035c4bbdfSmrg
118135c4bbdfSmrg    /* Tell Windows to create the palette */
118235c4bbdfSmrg    hpalNew = CreatePalette(lpPaletteNew);
118335c4bbdfSmrg    if (hpalNew == NULL) {
118435c4bbdfSmrg        ErrorF("winCreateColormapShadowGDI - CreatePalette () failed\n");
118535c4bbdfSmrg        free(lpPaletteNew);
118635c4bbdfSmrg        return FALSE;
118705b261ecSmrg    }
118805b261ecSmrg
118935c4bbdfSmrg    /* Save the Windows logical palette handle in the X colormaps' privates */
119035c4bbdfSmrg    pCmapPriv->hPalette = hpalNew;
119105b261ecSmrg
119235c4bbdfSmrg    /* Free the palette initialization memory */
119335c4bbdfSmrg    free(lpPaletteNew);
119405b261ecSmrg
119535c4bbdfSmrg    return TRUE;
119605b261ecSmrg}
119705b261ecSmrg
119805b261ecSmrg/*
119905b261ecSmrg * Colormap destruction procedure
120005b261ecSmrg */
120105b261ecSmrg
120205b261ecSmrgstatic Bool
120335c4bbdfSmrgwinDestroyColormapShadowGDI(ColormapPtr pColormap)
120405b261ecSmrg{
120535c4bbdfSmrg    winScreenPriv(pColormap->pScreen);
120635c4bbdfSmrg    winCmapPriv(pColormap);
120735c4bbdfSmrg
120835c4bbdfSmrg    /*
120935c4bbdfSmrg     * Is colormap to be destroyed the default?
121035c4bbdfSmrg     *
121135c4bbdfSmrg     * Non-default colormaps should have had winUninstallColormap
121235c4bbdfSmrg     * called on them before we get here.  The default colormap
121335c4bbdfSmrg     * will not have had winUninstallColormap called on it.  Thus,
121435c4bbdfSmrg     * we need to handle the default colormap in a special way.
121535c4bbdfSmrg     */
121635c4bbdfSmrg    if (pColormap->flags & IsDefault) {
121705b261ecSmrg#if CYGDEBUG
121835c4bbdfSmrg        winDebug("winDestroyColormapShadowGDI - Destroying default "
121935c4bbdfSmrg                 "colormap\n");
122005b261ecSmrg#endif
122135c4bbdfSmrg
122235c4bbdfSmrg        /*
122335c4bbdfSmrg         * FIXME: Walk the list of all screens, popping the default
122435c4bbdfSmrg         * palette out of each screen device context.
122535c4bbdfSmrg         */
122635c4bbdfSmrg
122735c4bbdfSmrg        /* Pop the palette out of the device context */
122835c4bbdfSmrg        SelectPalette(pScreenPriv->hdcScreen,
122935c4bbdfSmrg                      GetStockObject(DEFAULT_PALETTE), FALSE);
123035c4bbdfSmrg
123135c4bbdfSmrg        /* Clear our private installed colormap pointer */
123235c4bbdfSmrg        pScreenPriv->pcmapInstalled = NULL;
123305b261ecSmrg    }
123435c4bbdfSmrg
123535c4bbdfSmrg    /* Try to delete the logical palette */
123635c4bbdfSmrg    if (DeleteObject(pCmapPriv->hPalette) == 0) {
123735c4bbdfSmrg        ErrorF("winDestroyColormap - DeleteObject () failed\n");
123835c4bbdfSmrg        return FALSE;
123905b261ecSmrg    }
124005b261ecSmrg
124135c4bbdfSmrg    /* Invalidate the colormap privates */
124235c4bbdfSmrg    pCmapPriv->hPalette = NULL;
124305b261ecSmrg
124435c4bbdfSmrg    return TRUE;
124535c4bbdfSmrg}
124605b261ecSmrg
124705b261ecSmrg/*
1248ed6184dfSmrg * Set engine specific functions
124905b261ecSmrg */
125005b261ecSmrg
125105b261ecSmrgBool
125235c4bbdfSmrgwinSetEngineFunctionsShadowGDI(ScreenPtr pScreen)
125305b261ecSmrg{
125435c4bbdfSmrg    winScreenPriv(pScreen);
125535c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
125635c4bbdfSmrg
125735c4bbdfSmrg    /* Set our pointers */
125835c4bbdfSmrg    pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI;
125935c4bbdfSmrg    pScreenPriv->pwinFreeFB = winFreeFBShadowGDI;
126035c4bbdfSmrg    pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI;
126135c4bbdfSmrg    pScreenPriv->pwinInitScreen = winInitScreenShadowGDI;
126235c4bbdfSmrg    pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI;
126335c4bbdfSmrg    pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI;
126435c4bbdfSmrg    pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI;
126535c4bbdfSmrg    if (pScreenInfo->fFullScreen)
126635c4bbdfSmrg        pScreenPriv->pwinCreateBoundingWindow =
126735c4bbdfSmrg            winCreateBoundingWindowFullScreen;
126835c4bbdfSmrg    else
126935c4bbdfSmrg        pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
127035c4bbdfSmrg    pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
127135c4bbdfSmrg    pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI;
1272ed6184dfSmrg    pScreenPriv->pwinBltExposedWindowRegion = winBltExposedWindowRegionShadowGDI;
127335c4bbdfSmrg    pScreenPriv->pwinActivateApp = winActivateAppShadowGDI;
127435c4bbdfSmrg    pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI;
127535c4bbdfSmrg    pScreenPriv->pwinRealizeInstalledPalette =
127635c4bbdfSmrg        winRealizeInstalledPaletteShadowGDI;
127735c4bbdfSmrg    pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI;
127835c4bbdfSmrg    pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI;
127935c4bbdfSmrg    pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI;
128035c4bbdfSmrg    pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI;
12811b5d61b8Smrg    pScreenPriv->pwinCreatePrimarySurface = NULL;
12821b5d61b8Smrg    pScreenPriv->pwinReleasePrimarySurface = NULL;
128305b261ecSmrg
128435c4bbdfSmrg    return TRUE;
128505b261ecSmrg}
1286