winshadgdi.c revision 35c4bbdf
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
4005b261ecSmrg#ifdef XWIN_MULTIWINDOW
4135c4bbdfSmrgstatic wBOOL CALLBACK winRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam);
4205b261ecSmrg
4335c4bbdfSmrgstatic wBOOL CALLBACK winRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam);
4405b261ecSmrg#endif
4505b261ecSmrg
4605b261ecSmrgstatic Bool
4735c4bbdfSmrg winAllocateFBShadowGDI(ScreenPtr pScreen);
4805b261ecSmrg
4905b261ecSmrgstatic void
5035c4bbdfSmrg winShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf);
5105b261ecSmrg
5205b261ecSmrgstatic Bool
5335c4bbdfSmrg winCloseScreenShadowGDI(ScreenPtr pScreen);
5405b261ecSmrg
5505b261ecSmrgstatic Bool
5635c4bbdfSmrg winInitVisualsShadowGDI(ScreenPtr pScreen);
5705b261ecSmrg
5805b261ecSmrgstatic Bool
5935c4bbdfSmrg winAdjustVideoModeShadowGDI(ScreenPtr pScreen);
6005b261ecSmrg
6105b261ecSmrgstatic Bool
6235c4bbdfSmrg winBltExposedRegionsShadowGDI(ScreenPtr pScreen);
6305b261ecSmrg
6405b261ecSmrgstatic Bool
6535c4bbdfSmrg winActivateAppShadowGDI(ScreenPtr pScreen);
6605b261ecSmrg
6705b261ecSmrgstatic Bool
6835c4bbdfSmrg winRedrawScreenShadowGDI(ScreenPtr pScreen);
6905b261ecSmrg
7005b261ecSmrgstatic Bool
7135c4bbdfSmrg winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen);
7205b261ecSmrg
7305b261ecSmrgstatic Bool
7435c4bbdfSmrg winInstallColormapShadowGDI(ColormapPtr pColormap);
7505b261ecSmrg
7605b261ecSmrgstatic Bool
7735c4bbdfSmrg winStoreColorsShadowGDI(ColormapPtr pmap, int ndef, xColorItem * pdefs);
7805b261ecSmrg
7905b261ecSmrgstatic Bool
8035c4bbdfSmrg winCreateColormapShadowGDI(ColormapPtr pColormap);
8105b261ecSmrg
8205b261ecSmrgstatic Bool
8335c4bbdfSmrg winDestroyColormapShadowGDI(ColormapPtr pColormap);
8405b261ecSmrg
8505b261ecSmrg/*
8605b261ecSmrg * Internal function to get the DIB format that is compatible with the screen
8705b261ecSmrg */
8805b261ecSmrg
8905b261ecSmrgstatic
9035c4bbdfSmrg    Bool
9135c4bbdfSmrgwinQueryScreenDIBFormat(ScreenPtr pScreen, BITMAPINFOHEADER * pbmih)
9205b261ecSmrg{
9335c4bbdfSmrg    winScreenPriv(pScreen);
9435c4bbdfSmrg    HBITMAP hbmp;
9535c4bbdfSmrg
9605b261ecSmrg#if CYGDEBUG
9735c4bbdfSmrg    LPDWORD pdw = NULL;
9805b261ecSmrg#endif
9935c4bbdfSmrg
10035c4bbdfSmrg    /* Create a memory bitmap compatible with the screen */
10135c4bbdfSmrg    hbmp = CreateCompatibleBitmap(pScreenPriv->hdcScreen, 1, 1);
10235c4bbdfSmrg    if (hbmp == NULL) {
10335c4bbdfSmrg        ErrorF("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n");
10435c4bbdfSmrg        return FALSE;
10505b261ecSmrg    }
10635c4bbdfSmrg
10735c4bbdfSmrg    /* Initialize our bitmap info header */
10835c4bbdfSmrg    ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
10935c4bbdfSmrg    pbmih->biSize = sizeof(BITMAPINFOHEADER);
11035c4bbdfSmrg
11135c4bbdfSmrg    /* Get the biBitCount */
11235c4bbdfSmrg    if (!GetDIBits(pScreenPriv->hdcScreen,
11335c4bbdfSmrg                   hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) {
11435c4bbdfSmrg        ErrorF("winQueryScreenDIBFormat - First call to GetDIBits failed\n");
11535c4bbdfSmrg        DeleteObject(hbmp);
11635c4bbdfSmrg        return FALSE;
11705b261ecSmrg    }
11805b261ecSmrg
11905b261ecSmrg#if CYGDEBUG
12035c4bbdfSmrg    /* Get a pointer to bitfields */
12135c4bbdfSmrg    pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER));
12205b261ecSmrg
12335c4bbdfSmrg    winDebug("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n",
12435c4bbdfSmrg             (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]);
12505b261ecSmrg#endif
12605b261ecSmrg
12735c4bbdfSmrg    /* Get optimal color table, or the optimal bitfields */
12835c4bbdfSmrg    if (!GetDIBits(pScreenPriv->hdcScreen,
12935c4bbdfSmrg                   hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) {
13035c4bbdfSmrg        ErrorF("winQueryScreenDIBFormat - Second call to GetDIBits "
13135c4bbdfSmrg               "failed\n");
13235c4bbdfSmrg        DeleteObject(hbmp);
13335c4bbdfSmrg        return FALSE;
13405b261ecSmrg    }
13505b261ecSmrg
13635c4bbdfSmrg    /* Free memory */
13735c4bbdfSmrg    DeleteObject(hbmp);
13805b261ecSmrg
13935c4bbdfSmrg    return TRUE;
14035c4bbdfSmrg}
14105b261ecSmrg
14205b261ecSmrg/*
14305b261ecSmrg * Internal function to determine the GDI bits per rgb and bit masks
14405b261ecSmrg */
14505b261ecSmrg
14605b261ecSmrgstatic
14735c4bbdfSmrg    Bool
14835c4bbdfSmrgwinQueryRGBBitsAndMasks(ScreenPtr pScreen)
14905b261ecSmrg{
15035c4bbdfSmrg    winScreenPriv(pScreen);
15135c4bbdfSmrg    BITMAPINFOHEADER *pbmih = NULL;
15235c4bbdfSmrg    Bool fReturn = TRUE;
15335c4bbdfSmrg    LPDWORD pdw = NULL;
15435c4bbdfSmrg    DWORD dwRedBits, dwGreenBits, dwBlueBits;
15535c4bbdfSmrg
15635c4bbdfSmrg    /* Color masks for 8 bpp are standardized */
15735c4bbdfSmrg    if (GetDeviceCaps(pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) {
15835c4bbdfSmrg        /*
15935c4bbdfSmrg         * RGB BPP for 8 bit palletes is always 8
16035c4bbdfSmrg         * and the color masks are always 0.
16135c4bbdfSmrg         */
16235c4bbdfSmrg        pScreenPriv->dwBitsPerRGB = 8;
16335c4bbdfSmrg        pScreenPriv->dwRedMask = 0x0L;
16435c4bbdfSmrg        pScreenPriv->dwGreenMask = 0x0L;
16535c4bbdfSmrg        pScreenPriv->dwBlueMask = 0x0L;
16635c4bbdfSmrg        return TRUE;
16705b261ecSmrg    }
16805b261ecSmrg
16935c4bbdfSmrg    /* Color masks for 24 bpp are standardized */
17035c4bbdfSmrg    if (GetDeviceCaps(pScreenPriv->hdcScreen, PLANES)
17135c4bbdfSmrg        * GetDeviceCaps(pScreenPriv->hdcScreen, BITSPIXEL) == 24) {
17235c4bbdfSmrg        ErrorF("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) "
17335c4bbdfSmrg               "returned 24 for the screen.  Using default 24bpp masks.\n");
17435c4bbdfSmrg
17535c4bbdfSmrg        /* 8 bits per primary color */
17635c4bbdfSmrg        pScreenPriv->dwBitsPerRGB = 8;
17735c4bbdfSmrg
17835c4bbdfSmrg        /* Set screen privates masks */
17935c4bbdfSmrg        pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED;
18035c4bbdfSmrg        pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN;
18135c4bbdfSmrg        pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE;
18235c4bbdfSmrg
18335c4bbdfSmrg        return TRUE;
18405b261ecSmrg    }
18505b261ecSmrg
18635c4bbdfSmrg    /* Allocate a bitmap header and color table */
18735c4bbdfSmrg    pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
18835c4bbdfSmrg    if (pbmih == NULL) {
18935c4bbdfSmrg        ErrorF("winQueryRGBBitsAndMasks - malloc failed\n");
19035c4bbdfSmrg        return FALSE;
19105b261ecSmrg    }
19205b261ecSmrg
19335c4bbdfSmrg    /* Get screen description */
19435c4bbdfSmrg    if (winQueryScreenDIBFormat(pScreen, pbmih)) {
19535c4bbdfSmrg        /* Get a pointer to bitfields */
19635c4bbdfSmrg        pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER));
19735c4bbdfSmrg
19805b261ecSmrg#if CYGDEBUG
19935c4bbdfSmrg        winDebug("%s - Masks: %08x %08x %08x\n", __FUNCTION__,
20035c4bbdfSmrg                 (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]);
20135c4bbdfSmrg        winDebug("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__,
20235c4bbdfSmrg                 (int)pbmih->biWidth, (int)pbmih->biHeight, pbmih->biBitCount,
20335c4bbdfSmrg                 pbmih->biPlanes);
20435c4bbdfSmrg        winDebug("%s - Compression: %u %s\n", __FUNCTION__,
20535c4bbdfSmrg                 (unsigned int)pbmih->biCompression,
20635c4bbdfSmrg                 (pbmih->biCompression ==
20735c4bbdfSmrg                  BI_RGB ? "(BI_RGB)" : (pbmih->biCompression ==
20835c4bbdfSmrg                                         BI_RLE8 ? "(BI_RLE8)" : (pbmih->
20935c4bbdfSmrg                                                                  biCompression
21035c4bbdfSmrg                                                                  ==
21135c4bbdfSmrg                                                                  BI_RLE4 ?
21235c4bbdfSmrg                                                                  "(BI_RLE4)"
21335c4bbdfSmrg                                                                  : (pbmih->
21435c4bbdfSmrg                                                                     biCompression
21535c4bbdfSmrg                                                                     ==
21635c4bbdfSmrg                                                                     BI_BITFIELDS
21735c4bbdfSmrg                                                                     ?
21835c4bbdfSmrg                                                                     "(BI_BITFIELDS)"
21935c4bbdfSmrg                                                                     : "")))));
22005b261ecSmrg#endif
22105b261ecSmrg
22235c4bbdfSmrg        /* Handle BI_RGB case, which is returned by Wine */
22335c4bbdfSmrg        if (pbmih->biCompression == BI_RGB) {
22435c4bbdfSmrg            dwRedBits = 5;
22535c4bbdfSmrg            dwGreenBits = 5;
22635c4bbdfSmrg            dwBlueBits = 5;
22735c4bbdfSmrg
22835c4bbdfSmrg            pScreenPriv->dwBitsPerRGB = 5;
22935c4bbdfSmrg
23035c4bbdfSmrg            /* Set screen privates masks */
23135c4bbdfSmrg            pScreenPriv->dwRedMask = 0x7c00;
23235c4bbdfSmrg            pScreenPriv->dwGreenMask = 0x03e0;
23335c4bbdfSmrg            pScreenPriv->dwBlueMask = 0x001f;
23435c4bbdfSmrg        }
23535c4bbdfSmrg        else {
23635c4bbdfSmrg            /* Count the number of bits in each mask */
23735c4bbdfSmrg            dwRedBits = winCountBits(pdw[0]);
23835c4bbdfSmrg            dwGreenBits = winCountBits(pdw[1]);
23935c4bbdfSmrg            dwBlueBits = winCountBits(pdw[2]);
24035c4bbdfSmrg
24135c4bbdfSmrg            /* Find maximum bits per red, green, blue */
24235c4bbdfSmrg            if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
24335c4bbdfSmrg                pScreenPriv->dwBitsPerRGB = dwRedBits;
24435c4bbdfSmrg            else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
24535c4bbdfSmrg                pScreenPriv->dwBitsPerRGB = dwGreenBits;
24635c4bbdfSmrg            else
24735c4bbdfSmrg                pScreenPriv->dwBitsPerRGB = dwBlueBits;
24835c4bbdfSmrg
24935c4bbdfSmrg            /* Set screen privates masks */
25035c4bbdfSmrg            pScreenPriv->dwRedMask = pdw[0];
25135c4bbdfSmrg            pScreenPriv->dwGreenMask = pdw[1];
25235c4bbdfSmrg            pScreenPriv->dwBlueMask = pdw[2];
25305b261ecSmrg        }
25405b261ecSmrg    }
25535c4bbdfSmrg    else {
25635c4bbdfSmrg        ErrorF("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n");
25735c4bbdfSmrg        fReturn = FALSE;
25805b261ecSmrg    }
25905b261ecSmrg
26035c4bbdfSmrg    /* Free memory */
26135c4bbdfSmrg    free(pbmih);
26205b261ecSmrg
26335c4bbdfSmrg    return fReturn;
26405b261ecSmrg}
26505b261ecSmrg
26605b261ecSmrg#ifdef XWIN_MULTIWINDOW
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#endif
31305b261ecSmrg
31405b261ecSmrg/*
31505b261ecSmrg * Allocate a DIB for the shadow framebuffer GDI server
31605b261ecSmrg */
31705b261ecSmrg
31805b261ecSmrgstatic Bool
31935c4bbdfSmrgwinAllocateFBShadowGDI(ScreenPtr pScreen)
32005b261ecSmrg{
32135c4bbdfSmrg    winScreenPriv(pScreen);
32235c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
32335c4bbdfSmrg    DIBSECTION dibsection;
32435c4bbdfSmrg    Bool fReturn = TRUE;
32535c4bbdfSmrg
32635c4bbdfSmrg    /* Describe shadow bitmap to be created */
32735c4bbdfSmrg    pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth;
32835c4bbdfSmrg    pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight;
32935c4bbdfSmrg
33035c4bbdfSmrg    ErrorF("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d "
33135c4bbdfSmrg           "depth: %d\n",
33235c4bbdfSmrg           (int) pScreenPriv->pbmih->biWidth,
33335c4bbdfSmrg           (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount);
33435c4bbdfSmrg
33535c4bbdfSmrg    /* Create a DI shadow bitmap with a bit pointer */
33635c4bbdfSmrg    pScreenPriv->hbmpShadow = CreateDIBSection(pScreenPriv->hdcScreen,
33735c4bbdfSmrg                                               (BITMAPINFO *) pScreenPriv->
33835c4bbdfSmrg                                               pbmih, DIB_RGB_COLORS,
33935c4bbdfSmrg                                               (VOID **) &pScreenInfo->pfb,
34035c4bbdfSmrg                                               NULL, 0);
34135c4bbdfSmrg    if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) {
34235c4bbdfSmrg        winW32Error(2, "winAllocateFBShadowGDI - CreateDIBSection failed:");
34335c4bbdfSmrg        return FALSE;
34405b261ecSmrg    }
34535c4bbdfSmrg    else {
34605b261ecSmrg#if CYGDEBUG
34735c4bbdfSmrg        winDebug("winAllocateFBShadowGDI - Shadow buffer allocated\n");
34805b261ecSmrg#endif
34905b261ecSmrg    }
35005b261ecSmrg
35135c4bbdfSmrg    /* Get information about the bitmap that was allocated */
35235c4bbdfSmrg    GetObject(pScreenPriv->hbmpShadow, sizeof(dibsection), &dibsection);
35305b261ecSmrg
35405b261ecSmrg#if CYGDEBUG || YES
35535c4bbdfSmrg    /* Print information about bitmap allocated */
35635c4bbdfSmrg    winDebug("winAllocateFBShadowGDI - Dibsection width: %d height: %d "
35735c4bbdfSmrg             "depth: %d size image: %d\n",
35835c4bbdfSmrg             (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight,
35935c4bbdfSmrg             dibsection.dsBmih.biBitCount, (int) dibsection.dsBmih.biSizeImage);
36005b261ecSmrg#endif
36105b261ecSmrg
36235c4bbdfSmrg    /* Select the shadow bitmap into the shadow DC */
36335c4bbdfSmrg    SelectObject(pScreenPriv->hdcShadow, pScreenPriv->hbmpShadow);
36405b261ecSmrg
36505b261ecSmrg#if CYGDEBUG
36635c4bbdfSmrg    winDebug("winAllocateFBShadowGDI - Attempting a shadow blit\n");
36705b261ecSmrg#endif
36805b261ecSmrg
36935c4bbdfSmrg    /* Do a test blit from the shadow to the screen, I think */
37035c4bbdfSmrg    fReturn = BitBlt(pScreenPriv->hdcScreen,
37135c4bbdfSmrg                     0, 0,
37235c4bbdfSmrg                     pScreenInfo->dwWidth, pScreenInfo->dwHeight,
37335c4bbdfSmrg                     pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
37435c4bbdfSmrg    if (fReturn) {
37505b261ecSmrg#if CYGDEBUG
37635c4bbdfSmrg        winDebug("winAllocateFBShadowGDI - Shadow blit success\n");
37705b261ecSmrg#endif
37805b261ecSmrg    }
37935c4bbdfSmrg    else {
38035c4bbdfSmrg        winW32Error(2, "winAllocateFBShadowGDI - Shadow blit failure\n");
38135c4bbdfSmrg#if 0
38235c4bbdfSmrg        return FALSE;
38335c4bbdfSmrg#else
38435c4bbdfSmrg        /* ago: ignore this error. The blit fails with wine, but does not
38535c4bbdfSmrg         * cause any problems later. */
38635c4bbdfSmrg
38735c4bbdfSmrg        fReturn = TRUE;
38835c4bbdfSmrg#endif
38905b261ecSmrg    }
39005b261ecSmrg
39135c4bbdfSmrg    /* Look for height weirdness */
39235c4bbdfSmrg    if (dibsection.dsBmih.biHeight < 0) {
39335c4bbdfSmrg        dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight;
39405b261ecSmrg    }
39505b261ecSmrg
39635c4bbdfSmrg    /* Set screeninfo stride */
39735c4bbdfSmrg    pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage
39835c4bbdfSmrg                              / dibsection.dsBmih.biHeight)
39935c4bbdfSmrg                             * 8) / pScreenInfo->dwBPP;
40005b261ecSmrg
40105b261ecSmrg#if CYGDEBUG || YES
40235c4bbdfSmrg    winDebug("winAllocateFBShadowGDI - Created shadow stride: %d\n",
40335c4bbdfSmrg             (int) pScreenInfo->dwStride);
40405b261ecSmrg#endif
40505b261ecSmrg
40605b261ecSmrg#ifdef XWIN_MULTIWINDOW
40735c4bbdfSmrg    /* Redraw all windows */
40835c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
40935c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
41005b261ecSmrg#endif
41105b261ecSmrg
41235c4bbdfSmrg    return fReturn;
41305b261ecSmrg}
41405b261ecSmrg
4159ace9065Smrgstatic void
41635c4bbdfSmrgwinFreeFBShadowGDI(ScreenPtr pScreen)
4179ace9065Smrg{
41835c4bbdfSmrg    winScreenPriv(pScreen);
41935c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
4209ace9065Smrg
42135c4bbdfSmrg    /* Free the shadow bitmap */
42235c4bbdfSmrg    DeleteObject(pScreenPriv->hbmpShadow);
4239ace9065Smrg
42435c4bbdfSmrg    /* Invalidate the ScreenInfo's fb pointer */
42535c4bbdfSmrg    pScreenInfo->pfb = NULL;
4269ace9065Smrg}
42705b261ecSmrg
42805b261ecSmrg/*
42905b261ecSmrg * Blit the damaged regions of the shadow fb to the screen
43005b261ecSmrg */
43105b261ecSmrg
43205b261ecSmrgstatic void
43335c4bbdfSmrgwinShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf)
43405b261ecSmrg{
43535c4bbdfSmrg    winScreenPriv(pScreen);
43635c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
43735c4bbdfSmrg    RegionPtr damage = shadowDamage(pBuf);
43835c4bbdfSmrg    DWORD dwBox = RegionNumRects(damage);
43935c4bbdfSmrg    BoxPtr pBox = RegionRects(damage);
44035c4bbdfSmrg    int x, y, w, h;
44135c4bbdfSmrg    HRGN hrgnCombined = NULL;
44235c4bbdfSmrg
44305b261ecSmrg#ifdef XWIN_UPDATESTATS
44435c4bbdfSmrg    static DWORD s_dwNonUnitRegions = 0;
44535c4bbdfSmrg    static DWORD s_dwTotalUpdates = 0;
44635c4bbdfSmrg    static DWORD s_dwTotalBoxes = 0;
44705b261ecSmrg#endif
44835c4bbdfSmrg    BoxPtr pBoxExtents = RegionExtents(damage);
44905b261ecSmrg
45035c4bbdfSmrg    /*
45135c4bbdfSmrg     * Return immediately if the app is not active
45235c4bbdfSmrg     * and we are fullscreen, or if we have a bad display depth
45335c4bbdfSmrg     */
45435c4bbdfSmrg    if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
45535c4bbdfSmrg        || pScreenPriv->fBadDepth)
45635c4bbdfSmrg        return;
45705b261ecSmrg
45805b261ecSmrg#ifdef XWIN_UPDATESTATS
45935c4bbdfSmrg    ++s_dwTotalUpdates;
46035c4bbdfSmrg    s_dwTotalBoxes += dwBox;
46105b261ecSmrg
46235c4bbdfSmrg    if (dwBox != 1) {
46335c4bbdfSmrg        ++s_dwNonUnitRegions;
46435c4bbdfSmrg        ErrorF("winShadowUpdatGDI - dwBox: %d\n", dwBox);
46505b261ecSmrg    }
46635c4bbdfSmrg
46735c4bbdfSmrg    if ((s_dwTotalUpdates % 100) == 0)
46835c4bbdfSmrg        ErrorF("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d "
46935c4bbdfSmrg               "nu: %d tu: %d\n",
47035c4bbdfSmrg               (s_dwNonUnitRegions * 100) / s_dwTotalUpdates,
47135c4bbdfSmrg               s_dwTotalBoxes / s_dwTotalUpdates,
47235c4bbdfSmrg               s_dwNonUnitRegions, s_dwTotalUpdates);
47335c4bbdfSmrg#endif                          /* XWIN_UPDATESTATS */
47435c4bbdfSmrg
47535c4bbdfSmrg    /*
47635c4bbdfSmrg     * Handle small regions with multiple blits,
47735c4bbdfSmrg     * handle large regions by creating a clipping region and
47835c4bbdfSmrg     * doing a single blit constrained to that clipping region.
47935c4bbdfSmrg     */
48035c4bbdfSmrg    if (!pScreenInfo->fMultiWindow &&
48135c4bbdfSmrg        (pScreenInfo->dwClipUpdatesNBoxes == 0 ||
48235c4bbdfSmrg         dwBox < pScreenInfo->dwClipUpdatesNBoxes)) {
48335c4bbdfSmrg        /* Loop through all boxes in the damaged region */
48435c4bbdfSmrg        while (dwBox--) {
48535c4bbdfSmrg            /*
48635c4bbdfSmrg             * Calculate x offset, y offset, width, and height for
48735c4bbdfSmrg             * current damage box
48835c4bbdfSmrg             */
48935c4bbdfSmrg            x = pBox->x1;
49035c4bbdfSmrg            y = pBox->y1;
49135c4bbdfSmrg            w = pBox->x2 - pBox->x1;
49235c4bbdfSmrg            h = pBox->y2 - pBox->y1;
49335c4bbdfSmrg
49435c4bbdfSmrg            BitBlt(pScreenPriv->hdcScreen,
49535c4bbdfSmrg                   x, y, w, h, pScreenPriv->hdcShadow, x, y, SRCCOPY);
49635c4bbdfSmrg
49735c4bbdfSmrg            /* Get a pointer to the next box */
49835c4bbdfSmrg            ++pBox;
49935c4bbdfSmrg        }
50005b261ecSmrg    }
50135c4bbdfSmrg    else if (!pScreenInfo->fMultiWindow) {
50235c4bbdfSmrg
50335c4bbdfSmrg        /* Compute a GDI region from the damaged region */
50435c4bbdfSmrg        hrgnCombined =
50535c4bbdfSmrg            CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
50635c4bbdfSmrg                          pBoxExtents->y2);
50735c4bbdfSmrg
50835c4bbdfSmrg        /* Install the GDI region as a clipping region */
50935c4bbdfSmrg        SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
51035c4bbdfSmrg        DeleteObject(hrgnCombined);
51135c4bbdfSmrg        hrgnCombined = NULL;
51235c4bbdfSmrg
51335c4bbdfSmrg        /*
51435c4bbdfSmrg         * Blit the shadow buffer to the screen,
51535c4bbdfSmrg         * constrained to the clipping region.
51635c4bbdfSmrg         */
51735c4bbdfSmrg        BitBlt(pScreenPriv->hdcScreen,
51835c4bbdfSmrg               pBoxExtents->x1, pBoxExtents->y1,
51935c4bbdfSmrg               pBoxExtents->x2 - pBoxExtents->x1,
52035c4bbdfSmrg               pBoxExtents->y2 - pBoxExtents->y1,
52135c4bbdfSmrg               pScreenPriv->hdcShadow,
52235c4bbdfSmrg               pBoxExtents->x1, pBoxExtents->y1, SRCCOPY);
52335c4bbdfSmrg
52435c4bbdfSmrg        /* Reset the clip region */
52535c4bbdfSmrg        SelectClipRgn(pScreenPriv->hdcScreen, NULL);
52605b261ecSmrg    }
52705b261ecSmrg
52805b261ecSmrg#ifdef XWIN_MULTIWINDOW
52935c4bbdfSmrg    /* Redraw all multiwindow windows */
53035c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
53135c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID,
53235c4bbdfSmrg                          winRedrawDamagedWindowShadowGDI,
53335c4bbdfSmrg                          (LPARAM) pBoxExtents);
53405b261ecSmrg#endif
53505b261ecSmrg}
53605b261ecSmrg
5379ace9065Smrgstatic Bool
53835c4bbdfSmrgwinInitScreenShadowGDI(ScreenPtr pScreen)
5399ace9065Smrg{
54035c4bbdfSmrg    winScreenPriv(pScreen);
54135c4bbdfSmrg
54235c4bbdfSmrg    /* Get device contexts for the screen and shadow bitmap */
54335c4bbdfSmrg    pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen);
54435c4bbdfSmrg    pScreenPriv->hdcShadow = CreateCompatibleDC(pScreenPriv->hdcScreen);
54535c4bbdfSmrg
54635c4bbdfSmrg    /* Allocate bitmap info header */
54735c4bbdfSmrg    pScreenPriv->pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
54835c4bbdfSmrg    if (pScreenPriv->pbmih == NULL) {
54935c4bbdfSmrg        ErrorF("winInitScreenShadowGDI - malloc () failed\n");
55035c4bbdfSmrg        return FALSE;
5519ace9065Smrg    }
5529ace9065Smrg
55335c4bbdfSmrg    /* Query the screen format */
55435c4bbdfSmrg    if (!winQueryScreenDIBFormat(pScreen, pScreenPriv->pbmih)) {
55535c4bbdfSmrg        ErrorF("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n");
55635c4bbdfSmrg        return FALSE;
5579ace9065Smrg    }
5589ace9065Smrg
55935c4bbdfSmrg    /* Determine our color masks */
56035c4bbdfSmrg    if (!winQueryRGBBitsAndMasks(pScreen)) {
56135c4bbdfSmrg        ErrorF("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n");
56235c4bbdfSmrg        return FALSE;
5639ace9065Smrg    }
5649ace9065Smrg
56535c4bbdfSmrg    return winAllocateFBShadowGDI(pScreen);
5669ace9065Smrg}
5679ace9065Smrg
56805b261ecSmrg/* See Porting Layer Definition - p. 33 */
56905b261ecSmrg/*
57005b261ecSmrg * We wrap whatever CloseScreen procedure was specified by fb;
57105b261ecSmrg * a pointer to said procedure is stored in our privates.
57205b261ecSmrg */
57305b261ecSmrg
57405b261ecSmrgstatic Bool
57535c4bbdfSmrgwinCloseScreenShadowGDI(ScreenPtr pScreen)
57605b261ecSmrg{
57735c4bbdfSmrg    winScreenPriv(pScreen);
57835c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
57935c4bbdfSmrg    Bool fReturn;
58005b261ecSmrg
58105b261ecSmrg#if CYGDEBUG
58235c4bbdfSmrg    winDebug("winCloseScreenShadowGDI - Freeing screen resources\n");
58305b261ecSmrg#endif
58405b261ecSmrg
58535c4bbdfSmrg    /* Flag that the screen is closed */
58635c4bbdfSmrg    pScreenPriv->fClosed = TRUE;
58735c4bbdfSmrg    pScreenPriv->fActive = FALSE;
58805b261ecSmrg
58935c4bbdfSmrg    /* Call the wrapped CloseScreen procedure */
59035c4bbdfSmrg    WIN_UNWRAP(CloseScreen);
59135c4bbdfSmrg    if (pScreen->CloseScreen)
59235c4bbdfSmrg        fReturn = (*pScreen->CloseScreen) (pScreen);
59305b261ecSmrg
59435c4bbdfSmrg    /* Delete the window property */
59535c4bbdfSmrg    RemoveProp(pScreenPriv->hwndScreen, WIN_SCR_PROP);
59605b261ecSmrg
59735c4bbdfSmrg    /* Free the shadow DC; which allows the bitmap to be freed */
59835c4bbdfSmrg    DeleteDC(pScreenPriv->hdcShadow);
5999ace9065Smrg
60035c4bbdfSmrg    winFreeFBShadowGDI(pScreen);
60105b261ecSmrg
60235c4bbdfSmrg    /* Free the screen DC */
60335c4bbdfSmrg    ReleaseDC(pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
60405b261ecSmrg
60535c4bbdfSmrg    /* Delete tray icon, if we have one */
60635c4bbdfSmrg    if (!pScreenInfo->fNoTrayIcon)
60735c4bbdfSmrg        winDeleteNotifyIcon(pScreenPriv);
60805b261ecSmrg
60935c4bbdfSmrg    /* Free the exit confirmation dialog box, if it exists */
61035c4bbdfSmrg    if (g_hDlgExit != NULL) {
61135c4bbdfSmrg        DestroyWindow(g_hDlgExit);
61235c4bbdfSmrg        g_hDlgExit = NULL;
61305b261ecSmrg    }
61405b261ecSmrg
61535c4bbdfSmrg    /* Kill our window */
61635c4bbdfSmrg    if (pScreenPriv->hwndScreen) {
61735c4bbdfSmrg        DestroyWindow(pScreenPriv->hwndScreen);
61835c4bbdfSmrg        pScreenPriv->hwndScreen = NULL;
61905b261ecSmrg    }
62005b261ecSmrg
62105b261ecSmrg#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
62235c4bbdfSmrg    /* Destroy the thread startup mutex */
62335c4bbdfSmrg    pthread_mutex_destroy(&pScreenPriv->pmServerStarted);
62405b261ecSmrg#endif
62505b261ecSmrg
62635c4bbdfSmrg    /* Invalidate our screeninfo's pointer to the screen */
62735c4bbdfSmrg    pScreenInfo->pScreen = NULL;
62805b261ecSmrg
62935c4bbdfSmrg    /* Free the screen privates for this screen */
63035c4bbdfSmrg    free((void *) pScreenPriv);
63105b261ecSmrg
63235c4bbdfSmrg    return fReturn;
63305b261ecSmrg}
63405b261ecSmrg
63505b261ecSmrg/*
63605b261ecSmrg * Tell mi what sort of visuals we need.
63735c4bbdfSmrg *
63805b261ecSmrg * Generally we only need one visual, as our screen can only
63905b261ecSmrg * handle one format at a time, I believe.  You may want
64005b261ecSmrg * to verify that last sentence.
64105b261ecSmrg */
64205b261ecSmrg
64305b261ecSmrgstatic Bool
64435c4bbdfSmrgwinInitVisualsShadowGDI(ScreenPtr pScreen)
64505b261ecSmrg{
64635c4bbdfSmrg    winScreenPriv(pScreen);
64735c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
64835c4bbdfSmrg
64935c4bbdfSmrg    /* Display debugging information */
65035c4bbdfSmrg    ErrorF("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d "
65135c4bbdfSmrg           "bpp %d\n",
65235c4bbdfSmrg           (unsigned int) pScreenPriv->dwRedMask,
65335c4bbdfSmrg           (unsigned int) pScreenPriv->dwGreenMask,
65435c4bbdfSmrg           (unsigned int) pScreenPriv->dwBlueMask,
65535c4bbdfSmrg           (int) pScreenPriv->dwBitsPerRGB,
65635c4bbdfSmrg           (int) pScreenInfo->dwDepth, (int) pScreenInfo->dwBPP);
65735c4bbdfSmrg
65835c4bbdfSmrg    /* Create a single visual according to the Windows screen depth */
65935c4bbdfSmrg    switch (pScreenInfo->dwDepth) {
66005b261ecSmrg    case 24:
66105b261ecSmrg    case 16:
66205b261ecSmrg    case 15:
66335c4bbdfSmrg        /* Setup the real visual */
66435c4bbdfSmrg        if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
66535c4bbdfSmrg                                      TrueColorMask,
66635c4bbdfSmrg                                      pScreenPriv->dwBitsPerRGB,
66735c4bbdfSmrg                                      -1,
66835c4bbdfSmrg                                      pScreenPriv->dwRedMask,
66935c4bbdfSmrg                                      pScreenPriv->dwGreenMask,
67035c4bbdfSmrg                                      pScreenPriv->dwBlueMask)) {
67135c4bbdfSmrg            ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
67235c4bbdfSmrg                   "failed\n");
67335c4bbdfSmrg            return FALSE;
67435c4bbdfSmrg        }
67505b261ecSmrg
67605b261ecSmrg#ifdef XWIN_EMULATEPSEUDO
67735c4bbdfSmrg        if (!pScreenInfo->fEmulatePseudo)
67835c4bbdfSmrg            break;
67935c4bbdfSmrg
68035c4bbdfSmrg        /* Setup a pseudocolor visual */
68135c4bbdfSmrg        if (!miSetVisualTypesAndMasks(8, PseudoColorMask, 8, -1, 0, 0, 0)) {
68235c4bbdfSmrg            ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
68335c4bbdfSmrg                   "failed for PseudoColor\n");
68435c4bbdfSmrg            return FALSE;
68535c4bbdfSmrg        }
68605b261ecSmrg#endif
68735c4bbdfSmrg        break;
68805b261ecSmrg
68905b261ecSmrg    case 8:
69035c4bbdfSmrg        if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
69135c4bbdfSmrg                                      PseudoColorMask,
69235c4bbdfSmrg                                      pScreenPriv->dwBitsPerRGB,
69335c4bbdfSmrg                                      PseudoColor,
69435c4bbdfSmrg                                      pScreenPriv->dwRedMask,
69535c4bbdfSmrg                                      pScreenPriv->dwGreenMask,
69635c4bbdfSmrg                                      pScreenPriv->dwBlueMask)) {
69735c4bbdfSmrg            ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
69835c4bbdfSmrg                   "failed\n");
69935c4bbdfSmrg            return FALSE;
70035c4bbdfSmrg        }
70135c4bbdfSmrg        break;
70205b261ecSmrg
70305b261ecSmrg    default:
70435c4bbdfSmrg        ErrorF("winInitVisualsShadowGDI - Unknown screen depth\n");
70535c4bbdfSmrg        return FALSE;
70605b261ecSmrg    }
70705b261ecSmrg
70805b261ecSmrg#if CYGDEBUG
70935c4bbdfSmrg    winDebug("winInitVisualsShadowGDI - Returning\n");
71005b261ecSmrg#endif
71105b261ecSmrg
71235c4bbdfSmrg    return TRUE;
71305b261ecSmrg}
71405b261ecSmrg
71505b261ecSmrg/*
71605b261ecSmrg * Adjust the proposed video mode
71705b261ecSmrg */
71805b261ecSmrg
71905b261ecSmrgstatic Bool
72035c4bbdfSmrgwinAdjustVideoModeShadowGDI(ScreenPtr pScreen)
72105b261ecSmrg{
72235c4bbdfSmrg    winScreenPriv(pScreen);
72335c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
72435c4bbdfSmrg    HDC hdc;
72535c4bbdfSmrg    DWORD dwBPP;
72635c4bbdfSmrg
72735c4bbdfSmrg    hdc = GetDC(NULL);
72835c4bbdfSmrg
72935c4bbdfSmrg    /* We're in serious trouble if we can't get a DC */
73035c4bbdfSmrg    if (hdc == NULL) {
73135c4bbdfSmrg        ErrorF("winAdjustVideoModeShadowGDI - GetDC () failed\n");
73235c4bbdfSmrg        return FALSE;
73305b261ecSmrg    }
73405b261ecSmrg
73535c4bbdfSmrg    /* Query GDI for current display depth */
73635c4bbdfSmrg    dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
73705b261ecSmrg
73835c4bbdfSmrg    /* GDI cannot change the screen depth, so always use GDI's depth */
73935c4bbdfSmrg    pScreenInfo->dwBPP = dwBPP;
74005b261ecSmrg
74135c4bbdfSmrg    /* Release our DC */
74235c4bbdfSmrg    ReleaseDC(NULL, hdc);
74335c4bbdfSmrg    hdc = NULL;
74405b261ecSmrg
74535c4bbdfSmrg    return TRUE;
74605b261ecSmrg}
74705b261ecSmrg
74805b261ecSmrg/*
74905b261ecSmrg * Blt exposed regions to the screen
75005b261ecSmrg */
75105b261ecSmrg
75205b261ecSmrgstatic Bool
75335c4bbdfSmrgwinBltExposedRegionsShadowGDI(ScreenPtr pScreen)
75405b261ecSmrg{
75535c4bbdfSmrg    winScreenPriv(pScreen);
75635c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
75735c4bbdfSmrg    winPrivCmapPtr pCmapPriv = NULL;
75835c4bbdfSmrg    HDC hdcUpdate;
75935c4bbdfSmrg    PAINTSTRUCT ps;
76035c4bbdfSmrg
76135c4bbdfSmrg    /* BeginPaint gives us an hdc that clips to the invalidated region */
76235c4bbdfSmrg    hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps);
76335c4bbdfSmrg
76435c4bbdfSmrg    /* Realize the palette, if we have one */
76535c4bbdfSmrg    if (pScreenPriv->pcmapInstalled != NULL) {
76635c4bbdfSmrg        pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled);
76735c4bbdfSmrg
76835c4bbdfSmrg        SelectPalette(hdcUpdate, pCmapPriv->hPalette, FALSE);
76935c4bbdfSmrg        RealizePalette(hdcUpdate);
77005b261ecSmrg    }
77105b261ecSmrg
77235c4bbdfSmrg    /* Our BitBlt will be clipped to the invalidated region */
77335c4bbdfSmrg    BitBlt(hdcUpdate,
77435c4bbdfSmrg           0, 0,
77535c4bbdfSmrg           pScreenInfo->dwWidth, pScreenInfo->dwHeight,
77635c4bbdfSmrg           pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
77705b261ecSmrg
77835c4bbdfSmrg    /* EndPaint frees the DC */
77935c4bbdfSmrg    EndPaint(pScreenPriv->hwndScreen, &ps);
78005b261ecSmrg
78105b261ecSmrg#ifdef XWIN_MULTIWINDOW
78235c4bbdfSmrg    /* Redraw all windows */
78335c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
78435c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI,
78535c4bbdfSmrg                          (LPARAM) pScreenPriv->hwndScreen);
78605b261ecSmrg#endif
78705b261ecSmrg
78835c4bbdfSmrg    return TRUE;
78905b261ecSmrg}
79005b261ecSmrg
79105b261ecSmrg/*
79205b261ecSmrg * Do any engine-specific appliation-activation processing
79305b261ecSmrg */
79405b261ecSmrg
79505b261ecSmrgstatic Bool
79635c4bbdfSmrgwinActivateAppShadowGDI(ScreenPtr pScreen)
79705b261ecSmrg{
79835c4bbdfSmrg    winScreenPriv(pScreen);
79935c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
80035c4bbdfSmrg
80135c4bbdfSmrg    /*
80235c4bbdfSmrg     * 2004/04/12 - Harold - We perform the restoring or minimizing
80335c4bbdfSmrg     * manually for ShadowGDI in fullscreen modes so that this engine
80435c4bbdfSmrg     * will perform just like ShadowDD and ShadowDDNL in fullscreen mode;
80535c4bbdfSmrg     * if we do not do this then our fullscreen window will appear in the
80635c4bbdfSmrg     * z-order when it is deactivated and it can be uncovered by resizing
80735c4bbdfSmrg     * or minimizing another window that is on top of it, which is not how
80835c4bbdfSmrg     * the DirectDraw engines work.  Therefore we keep this code here to
80935c4bbdfSmrg     * make sure that all engines work the same in fullscreen mode.
81035c4bbdfSmrg     */
81135c4bbdfSmrg
81235c4bbdfSmrg    /*
81335c4bbdfSmrg     * Are we active?
81435c4bbdfSmrg     * Are we fullscreen?
81535c4bbdfSmrg     */
81635c4bbdfSmrg    if (pScreenPriv->fActive && pScreenInfo->fFullScreen) {
81735c4bbdfSmrg        /*
81835c4bbdfSmrg         * Activating, attempt to bring our window
81935c4bbdfSmrg         * to the top of the display
82035c4bbdfSmrg         */
82135c4bbdfSmrg        ShowWindow(pScreenPriv->hwndScreen, SW_RESTORE);
82205b261ecSmrg    }
82335c4bbdfSmrg    else if (!pScreenPriv->fActive && pScreenInfo->fFullScreen) {
82435c4bbdfSmrg        /*
82535c4bbdfSmrg         * Deactivating, stuff our window onto the
82635c4bbdfSmrg         * task bar.
82735c4bbdfSmrg         */
82835c4bbdfSmrg        ShowWindow(pScreenPriv->hwndScreen, SW_MINIMIZE);
82905b261ecSmrg    }
83005b261ecSmrg
83135c4bbdfSmrg    return TRUE;
83205b261ecSmrg}
83305b261ecSmrg
83405b261ecSmrg/*
83505b261ecSmrg * Reblit the shadow framebuffer to the screen.
83605b261ecSmrg */
83705b261ecSmrg
83805b261ecSmrgstatic Bool
83935c4bbdfSmrgwinRedrawScreenShadowGDI(ScreenPtr pScreen)
84005b261ecSmrg{
84135c4bbdfSmrg    winScreenPriv(pScreen);
84235c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
84305b261ecSmrg
84435c4bbdfSmrg    /* Redraw the whole window, to take account for the new colors */
84535c4bbdfSmrg    BitBlt(pScreenPriv->hdcScreen,
84635c4bbdfSmrg           0, 0,
84735c4bbdfSmrg           pScreenInfo->dwWidth, pScreenInfo->dwHeight,
84835c4bbdfSmrg           pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
84905b261ecSmrg
85005b261ecSmrg#ifdef XWIN_MULTIWINDOW
85135c4bbdfSmrg    /* Redraw all windows */
85235c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
85335c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
85405b261ecSmrg#endif
85505b261ecSmrg
85635c4bbdfSmrg    return TRUE;
85705b261ecSmrg}
85805b261ecSmrg
85905b261ecSmrg/*
86005b261ecSmrg * Realize the currently installed colormap
86105b261ecSmrg */
86205b261ecSmrg
86305b261ecSmrgstatic Bool
86435c4bbdfSmrgwinRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen)
86505b261ecSmrg{
86635c4bbdfSmrg    winScreenPriv(pScreen);
86735c4bbdfSmrg    winPrivCmapPtr pCmapPriv = NULL;
86805b261ecSmrg
86905b261ecSmrg#if CYGDEBUG
87035c4bbdfSmrg    winDebug("winRealizeInstalledPaletteShadowGDI\n");
87105b261ecSmrg#endif
87205b261ecSmrg
87335c4bbdfSmrg    /* Don't do anything if there is not a colormap */
87435c4bbdfSmrg    if (pScreenPriv->pcmapInstalled == NULL) {
87505b261ecSmrg#if CYGDEBUG
87635c4bbdfSmrg        winDebug("winRealizeInstalledPaletteShadowGDI - No colormap "
87735c4bbdfSmrg                 "installed\n");
87805b261ecSmrg#endif
87935c4bbdfSmrg        return TRUE;
88005b261ecSmrg    }
88105b261ecSmrg
88235c4bbdfSmrg    pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled);
88335c4bbdfSmrg
88435c4bbdfSmrg    /* Realize our palette for the screen */
88535c4bbdfSmrg    if (RealizePalette(pScreenPriv->hdcScreen) == GDI_ERROR) {
88635c4bbdfSmrg        ErrorF("winRealizeInstalledPaletteShadowGDI - RealizePalette () "
88735c4bbdfSmrg               "failed\n");
88835c4bbdfSmrg        return FALSE;
88905b261ecSmrg    }
89035c4bbdfSmrg
89135c4bbdfSmrg    /* Set the DIB color table */
89235c4bbdfSmrg    if (SetDIBColorTable(pScreenPriv->hdcShadow,
89335c4bbdfSmrg                         0,
89435c4bbdfSmrg                         WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) {
89535c4bbdfSmrg        ErrorF("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () "
89635c4bbdfSmrg               "failed\n");
89735c4bbdfSmrg        return FALSE;
89805b261ecSmrg    }
89905b261ecSmrg
90035c4bbdfSmrg    return TRUE;
90135c4bbdfSmrg}
90205b261ecSmrg
90305b261ecSmrg/*
90405b261ecSmrg * Install the specified colormap
90505b261ecSmrg */
90605b261ecSmrg
90705b261ecSmrgstatic Bool
90835c4bbdfSmrgwinInstallColormapShadowGDI(ColormapPtr pColormap)
90905b261ecSmrg{
91035c4bbdfSmrg    ScreenPtr pScreen = pColormap->pScreen;
91135c4bbdfSmrg
91235c4bbdfSmrg    winScreenPriv(pScreen);
91335c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
91435c4bbdfSmrg
91535c4bbdfSmrg    winCmapPriv(pColormap);
91635c4bbdfSmrg
91735c4bbdfSmrg    /*
91835c4bbdfSmrg     * Tell Windows to install the new colormap
91935c4bbdfSmrg     */
92035c4bbdfSmrg    if (SelectPalette(pScreenPriv->hdcScreen,
92135c4bbdfSmrg                      pCmapPriv->hPalette, FALSE) == NULL) {
92235c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - SelectPalette () failed\n");
92335c4bbdfSmrg        return FALSE;
92405b261ecSmrg    }
92535c4bbdfSmrg
92635c4bbdfSmrg    /* Realize the palette */
92735c4bbdfSmrg    if (GDI_ERROR == RealizePalette(pScreenPriv->hdcScreen)) {
92835c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - RealizePalette () failed\n");
92935c4bbdfSmrg        return FALSE;
93005b261ecSmrg    }
93105b261ecSmrg
93235c4bbdfSmrg    /* Set the DIB color table */
93335c4bbdfSmrg    if (SetDIBColorTable(pScreenPriv->hdcShadow,
93435c4bbdfSmrg                         0,
93535c4bbdfSmrg                         WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) {
93635c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
93735c4bbdfSmrg        return FALSE;
93805b261ecSmrg    }
93905b261ecSmrg
94035c4bbdfSmrg    /* Redraw the whole window, to take account for the new colors */
94135c4bbdfSmrg    BitBlt(pScreenPriv->hdcScreen,
94235c4bbdfSmrg           0, 0,
94335c4bbdfSmrg           pScreenInfo->dwWidth, pScreenInfo->dwHeight,
94435c4bbdfSmrg           pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
94505b261ecSmrg
94635c4bbdfSmrg    /* Save a pointer to the newly installed colormap */
94735c4bbdfSmrg    pScreenPriv->pcmapInstalled = pColormap;
94805b261ecSmrg
94905b261ecSmrg#ifdef XWIN_MULTIWINDOW
95035c4bbdfSmrg    /* Redraw all windows */
95135c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
95235c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
95305b261ecSmrg#endif
95405b261ecSmrg
95535c4bbdfSmrg    return TRUE;
95605b261ecSmrg}
95705b261ecSmrg
95805b261ecSmrg/*
95905b261ecSmrg * Store the specified colors in the specified colormap
96005b261ecSmrg */
96105b261ecSmrg
96205b261ecSmrgstatic Bool
96335c4bbdfSmrgwinStoreColorsShadowGDI(ColormapPtr pColormap, int ndef, xColorItem * pdefs)
96405b261ecSmrg{
96535c4bbdfSmrg    ScreenPtr pScreen = pColormap->pScreen;
96635c4bbdfSmrg
96735c4bbdfSmrg    winScreenPriv(pScreen);
96835c4bbdfSmrg    winCmapPriv(pColormap);
96935c4bbdfSmrg    ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
97035c4bbdfSmrg
97135c4bbdfSmrg    /* Put the X colormap entries into the Windows logical palette */
97235c4bbdfSmrg    if (SetPaletteEntries(pCmapPriv->hPalette,
97335c4bbdfSmrg                          pdefs[0].pixel,
97435c4bbdfSmrg                          ndef, pCmapPriv->peColors + pdefs[0].pixel) == 0) {
97535c4bbdfSmrg        ErrorF("winStoreColorsShadowGDI - SetPaletteEntries () failed\n");
97635c4bbdfSmrg        return FALSE;
97705b261ecSmrg    }
97805b261ecSmrg
97935c4bbdfSmrg    /* Don't install the Windows palette if the colormap is not installed */
98035c4bbdfSmrg    if (pColormap != curpmap) {
98135c4bbdfSmrg        return TRUE;
98205b261ecSmrg    }
98305b261ecSmrg
98435c4bbdfSmrg    /* Try to install the newly modified colormap */
98535c4bbdfSmrg    if (!winInstallColormapShadowGDI(pColormap)) {
98635c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - winInstallColormapShadowGDI "
98735c4bbdfSmrg               "failed\n");
98835c4bbdfSmrg        return FALSE;
98905b261ecSmrg    }
99005b261ecSmrg
99105b261ecSmrg#if 0
99235c4bbdfSmrg    /* Tell Windows that the palette has changed */
99335c4bbdfSmrg    RealizePalette(pScreenPriv->hdcScreen);
99435c4bbdfSmrg
99535c4bbdfSmrg    /* Set the DIB color table */
99635c4bbdfSmrg    if (SetDIBColorTable(pScreenPriv->hdcShadow,
99735c4bbdfSmrg                         pdefs[0].pixel,
99835c4bbdfSmrg                         ndef, pCmapPriv->rgbColors + pdefs[0].pixel) == 0) {
99935c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
100035c4bbdfSmrg        return FALSE;
100105b261ecSmrg    }
100205b261ecSmrg
100335c4bbdfSmrg    /* Save a pointer to the newly installed colormap */
100435c4bbdfSmrg    pScreenPriv->pcmapInstalled = pColormap;
100505b261ecSmrg#endif
100605b261ecSmrg
100735c4bbdfSmrg    return TRUE;
100805b261ecSmrg}
100905b261ecSmrg
101005b261ecSmrg/*
101105b261ecSmrg * Colormap initialization procedure
101205b261ecSmrg */
101305b261ecSmrg
101405b261ecSmrgstatic Bool
101535c4bbdfSmrgwinCreateColormapShadowGDI(ColormapPtr pColormap)
101605b261ecSmrg{
101735c4bbdfSmrg    LPLOGPALETTE lpPaletteNew = NULL;
101835c4bbdfSmrg    DWORD dwEntriesMax;
101935c4bbdfSmrg    VisualPtr pVisual;
102035c4bbdfSmrg    HPALETTE hpalNew = NULL;
102135c4bbdfSmrg
102235c4bbdfSmrg    winCmapPriv(pColormap);
102335c4bbdfSmrg
102435c4bbdfSmrg    /* Get a pointer to the visual that the colormap belongs to */
102535c4bbdfSmrg    pVisual = pColormap->pVisual;
102635c4bbdfSmrg
102735c4bbdfSmrg    /* Get the maximum number of palette entries for this visual */
102835c4bbdfSmrg    dwEntriesMax = pVisual->ColormapEntries;
102935c4bbdfSmrg
103035c4bbdfSmrg    /* Allocate a Windows logical color palette with max entries */
103135c4bbdfSmrg    lpPaletteNew = malloc(sizeof(LOGPALETTE)
103235c4bbdfSmrg                          + (dwEntriesMax - 1) * sizeof(PALETTEENTRY));
103335c4bbdfSmrg    if (lpPaletteNew == NULL) {
103435c4bbdfSmrg        ErrorF("winCreateColormapShadowGDI - Couldn't allocate palette "
103535c4bbdfSmrg               "with %d entries\n", (int) dwEntriesMax);
103635c4bbdfSmrg        return FALSE;
103705b261ecSmrg    }
103805b261ecSmrg
103935c4bbdfSmrg    /* Zero out the colormap */
104035c4bbdfSmrg    ZeroMemory(lpPaletteNew, sizeof(LOGPALETTE)
104135c4bbdfSmrg               + (dwEntriesMax - 1) * sizeof(PALETTEENTRY));
104235c4bbdfSmrg
104335c4bbdfSmrg    /* Set the logical palette structure */
104435c4bbdfSmrg    lpPaletteNew->palVersion = 0x0300;
104535c4bbdfSmrg    lpPaletteNew->palNumEntries = dwEntriesMax;
104635c4bbdfSmrg
104735c4bbdfSmrg    /* Tell Windows to create the palette */
104835c4bbdfSmrg    hpalNew = CreatePalette(lpPaletteNew);
104935c4bbdfSmrg    if (hpalNew == NULL) {
105035c4bbdfSmrg        ErrorF("winCreateColormapShadowGDI - CreatePalette () failed\n");
105135c4bbdfSmrg        free(lpPaletteNew);
105235c4bbdfSmrg        return FALSE;
105305b261ecSmrg    }
105405b261ecSmrg
105535c4bbdfSmrg    /* Save the Windows logical palette handle in the X colormaps' privates */
105635c4bbdfSmrg    pCmapPriv->hPalette = hpalNew;
105705b261ecSmrg
105835c4bbdfSmrg    /* Free the palette initialization memory */
105935c4bbdfSmrg    free(lpPaletteNew);
106005b261ecSmrg
106135c4bbdfSmrg    return TRUE;
106205b261ecSmrg}
106305b261ecSmrg
106405b261ecSmrg/*
106505b261ecSmrg * Colormap destruction procedure
106605b261ecSmrg */
106705b261ecSmrg
106805b261ecSmrgstatic Bool
106935c4bbdfSmrgwinDestroyColormapShadowGDI(ColormapPtr pColormap)
107005b261ecSmrg{
107135c4bbdfSmrg    winScreenPriv(pColormap->pScreen);
107235c4bbdfSmrg    winCmapPriv(pColormap);
107335c4bbdfSmrg
107435c4bbdfSmrg    /*
107535c4bbdfSmrg     * Is colormap to be destroyed the default?
107635c4bbdfSmrg     *
107735c4bbdfSmrg     * Non-default colormaps should have had winUninstallColormap
107835c4bbdfSmrg     * called on them before we get here.  The default colormap
107935c4bbdfSmrg     * will not have had winUninstallColormap called on it.  Thus,
108035c4bbdfSmrg     * we need to handle the default colormap in a special way.
108135c4bbdfSmrg     */
108235c4bbdfSmrg    if (pColormap->flags & IsDefault) {
108305b261ecSmrg#if CYGDEBUG
108435c4bbdfSmrg        winDebug("winDestroyColormapShadowGDI - Destroying default "
108535c4bbdfSmrg                 "colormap\n");
108605b261ecSmrg#endif
108735c4bbdfSmrg
108835c4bbdfSmrg        /*
108935c4bbdfSmrg         * FIXME: Walk the list of all screens, popping the default
109035c4bbdfSmrg         * palette out of each screen device context.
109135c4bbdfSmrg         */
109235c4bbdfSmrg
109335c4bbdfSmrg        /* Pop the palette out of the device context */
109435c4bbdfSmrg        SelectPalette(pScreenPriv->hdcScreen,
109535c4bbdfSmrg                      GetStockObject(DEFAULT_PALETTE), FALSE);
109635c4bbdfSmrg
109735c4bbdfSmrg        /* Clear our private installed colormap pointer */
109835c4bbdfSmrg        pScreenPriv->pcmapInstalled = NULL;
109905b261ecSmrg    }
110035c4bbdfSmrg
110135c4bbdfSmrg    /* Try to delete the logical palette */
110235c4bbdfSmrg    if (DeleteObject(pCmapPriv->hPalette) == 0) {
110335c4bbdfSmrg        ErrorF("winDestroyColormap - DeleteObject () failed\n");
110435c4bbdfSmrg        return FALSE;
110505b261ecSmrg    }
110605b261ecSmrg
110735c4bbdfSmrg    /* Invalidate the colormap privates */
110835c4bbdfSmrg    pCmapPriv->hPalette = NULL;
110905b261ecSmrg
111035c4bbdfSmrg    return TRUE;
111135c4bbdfSmrg}
111205b261ecSmrg
111305b261ecSmrg/*
111405b261ecSmrg * Set engine specific funtions
111505b261ecSmrg */
111605b261ecSmrg
111705b261ecSmrgBool
111835c4bbdfSmrgwinSetEngineFunctionsShadowGDI(ScreenPtr pScreen)
111905b261ecSmrg{
112035c4bbdfSmrg    winScreenPriv(pScreen);
112135c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
112235c4bbdfSmrg
112335c4bbdfSmrg    /* Set our pointers */
112435c4bbdfSmrg    pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI;
112535c4bbdfSmrg    pScreenPriv->pwinFreeFB = winFreeFBShadowGDI;
112635c4bbdfSmrg    pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI;
112735c4bbdfSmrg    pScreenPriv->pwinInitScreen = winInitScreenShadowGDI;
112835c4bbdfSmrg    pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI;
112935c4bbdfSmrg    pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI;
113035c4bbdfSmrg    pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI;
113135c4bbdfSmrg    if (pScreenInfo->fFullScreen)
113235c4bbdfSmrg        pScreenPriv->pwinCreateBoundingWindow =
113335c4bbdfSmrg            winCreateBoundingWindowFullScreen;
113435c4bbdfSmrg    else
113535c4bbdfSmrg        pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
113635c4bbdfSmrg    pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
113735c4bbdfSmrg    pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI;
113835c4bbdfSmrg    pScreenPriv->pwinActivateApp = winActivateAppShadowGDI;
113935c4bbdfSmrg    pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI;
114035c4bbdfSmrg    pScreenPriv->pwinRealizeInstalledPalette =
114135c4bbdfSmrg        winRealizeInstalledPaletteShadowGDI;
114235c4bbdfSmrg    pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI;
114335c4bbdfSmrg    pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI;
114435c4bbdfSmrg    pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI;
114535c4bbdfSmrg    pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI;
114635c4bbdfSmrg    pScreenPriv->pwinHotKeyAltTab =
114735c4bbdfSmrg        (winHotKeyAltTabProcPtr) (void (*)(void)) NoopDDA;
114835c4bbdfSmrg    pScreenPriv->pwinCreatePrimarySurface =
114935c4bbdfSmrg        (winCreatePrimarySurfaceProcPtr) (void (*)(void)) NoopDDA;
115035c4bbdfSmrg    pScreenPriv->pwinReleasePrimarySurface =
115135c4bbdfSmrg        (winReleasePrimarySurfaceProcPtr) (void (*)(void)) NoopDDA;
115205b261ecSmrg#ifdef XWIN_MULTIWINDOW
115335c4bbdfSmrg    pScreenPriv->pwinFinishCreateWindowsWindow =
115435c4bbdfSmrg        (winFinishCreateWindowsWindowProcPtr) (void (*)(void)) NoopDDA;
115505b261ecSmrg#endif
115605b261ecSmrg
115735c4bbdfSmrg    return TRUE;
115805b261ecSmrg}
1159