winshadgdi.c revision 1b5d61b8
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
6205b261ecSmrgstatic Bool
6335c4bbdfSmrg winActivateAppShadowGDI(ScreenPtr pScreen);
6405b261ecSmrg
6505b261ecSmrgstatic Bool
6635c4bbdfSmrg winRedrawScreenShadowGDI(ScreenPtr pScreen);
6705b261ecSmrg
6805b261ecSmrgstatic Bool
6935c4bbdfSmrg winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen);
7005b261ecSmrg
7105b261ecSmrgstatic Bool
7235c4bbdfSmrg winInstallColormapShadowGDI(ColormapPtr pColormap);
7305b261ecSmrg
7405b261ecSmrgstatic Bool
7535c4bbdfSmrg winStoreColorsShadowGDI(ColormapPtr pmap, int ndef, xColorItem * pdefs);
7605b261ecSmrg
7705b261ecSmrgstatic Bool
7835c4bbdfSmrg winCreateColormapShadowGDI(ColormapPtr pColormap);
7905b261ecSmrg
8005b261ecSmrgstatic Bool
8135c4bbdfSmrg winDestroyColormapShadowGDI(ColormapPtr pColormap);
8205b261ecSmrg
8305b261ecSmrg/*
8405b261ecSmrg * Internal function to get the DIB format that is compatible with the screen
8505b261ecSmrg */
8605b261ecSmrg
8705b261ecSmrgstatic
8835c4bbdfSmrg    Bool
8935c4bbdfSmrgwinQueryScreenDIBFormat(ScreenPtr pScreen, BITMAPINFOHEADER * pbmih)
9005b261ecSmrg{
9135c4bbdfSmrg    winScreenPriv(pScreen);
9235c4bbdfSmrg    HBITMAP hbmp;
9335c4bbdfSmrg
9405b261ecSmrg#if CYGDEBUG
9535c4bbdfSmrg    LPDWORD pdw = NULL;
9605b261ecSmrg#endif
9735c4bbdfSmrg
9835c4bbdfSmrg    /* Create a memory bitmap compatible with the screen */
9935c4bbdfSmrg    hbmp = CreateCompatibleBitmap(pScreenPriv->hdcScreen, 1, 1);
10035c4bbdfSmrg    if (hbmp == NULL) {
10135c4bbdfSmrg        ErrorF("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n");
10235c4bbdfSmrg        return FALSE;
10305b261ecSmrg    }
10435c4bbdfSmrg
10535c4bbdfSmrg    /* Initialize our bitmap info header */
10635c4bbdfSmrg    ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
10735c4bbdfSmrg    pbmih->biSize = sizeof(BITMAPINFOHEADER);
10835c4bbdfSmrg
10935c4bbdfSmrg    /* Get the biBitCount */
11035c4bbdfSmrg    if (!GetDIBits(pScreenPriv->hdcScreen,
11135c4bbdfSmrg                   hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) {
11235c4bbdfSmrg        ErrorF("winQueryScreenDIBFormat - First call to GetDIBits failed\n");
11335c4bbdfSmrg        DeleteObject(hbmp);
11435c4bbdfSmrg        return FALSE;
11505b261ecSmrg    }
11605b261ecSmrg
11705b261ecSmrg#if CYGDEBUG
11835c4bbdfSmrg    /* Get a pointer to bitfields */
11935c4bbdfSmrg    pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER));
12005b261ecSmrg
12135c4bbdfSmrg    winDebug("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n",
12235c4bbdfSmrg             (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]);
12305b261ecSmrg#endif
12405b261ecSmrg
12535c4bbdfSmrg    /* Get optimal color table, or the optimal bitfields */
12635c4bbdfSmrg    if (!GetDIBits(pScreenPriv->hdcScreen,
12735c4bbdfSmrg                   hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) {
12835c4bbdfSmrg        ErrorF("winQueryScreenDIBFormat - Second call to GetDIBits "
12935c4bbdfSmrg               "failed\n");
13035c4bbdfSmrg        DeleteObject(hbmp);
13135c4bbdfSmrg        return FALSE;
13205b261ecSmrg    }
13305b261ecSmrg
13435c4bbdfSmrg    /* Free memory */
13535c4bbdfSmrg    DeleteObject(hbmp);
13605b261ecSmrg
13735c4bbdfSmrg    return TRUE;
13835c4bbdfSmrg}
13905b261ecSmrg
14005b261ecSmrg/*
14105b261ecSmrg * Internal function to determine the GDI bits per rgb and bit masks
14205b261ecSmrg */
14305b261ecSmrg
14405b261ecSmrgstatic
14535c4bbdfSmrg    Bool
14635c4bbdfSmrgwinQueryRGBBitsAndMasks(ScreenPtr pScreen)
14705b261ecSmrg{
14835c4bbdfSmrg    winScreenPriv(pScreen);
14935c4bbdfSmrg    BITMAPINFOHEADER *pbmih = NULL;
15035c4bbdfSmrg    Bool fReturn = TRUE;
15135c4bbdfSmrg    LPDWORD pdw = NULL;
15235c4bbdfSmrg    DWORD dwRedBits, dwGreenBits, dwBlueBits;
15335c4bbdfSmrg
15435c4bbdfSmrg    /* Color masks for 8 bpp are standardized */
15535c4bbdfSmrg    if (GetDeviceCaps(pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) {
15635c4bbdfSmrg        /*
15735c4bbdfSmrg         * RGB BPP for 8 bit palletes is always 8
15835c4bbdfSmrg         * and the color masks are always 0.
15935c4bbdfSmrg         */
16035c4bbdfSmrg        pScreenPriv->dwBitsPerRGB = 8;
16135c4bbdfSmrg        pScreenPriv->dwRedMask = 0x0L;
16235c4bbdfSmrg        pScreenPriv->dwGreenMask = 0x0L;
16335c4bbdfSmrg        pScreenPriv->dwBlueMask = 0x0L;
16435c4bbdfSmrg        return TRUE;
16505b261ecSmrg    }
16605b261ecSmrg
16735c4bbdfSmrg    /* Color masks for 24 bpp are standardized */
16835c4bbdfSmrg    if (GetDeviceCaps(pScreenPriv->hdcScreen, PLANES)
16935c4bbdfSmrg        * GetDeviceCaps(pScreenPriv->hdcScreen, BITSPIXEL) == 24) {
17035c4bbdfSmrg        ErrorF("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) "
17135c4bbdfSmrg               "returned 24 for the screen.  Using default 24bpp masks.\n");
17235c4bbdfSmrg
17335c4bbdfSmrg        /* 8 bits per primary color */
17435c4bbdfSmrg        pScreenPriv->dwBitsPerRGB = 8;
17535c4bbdfSmrg
17635c4bbdfSmrg        /* Set screen privates masks */
17735c4bbdfSmrg        pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED;
17835c4bbdfSmrg        pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN;
17935c4bbdfSmrg        pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE;
18035c4bbdfSmrg
18135c4bbdfSmrg        return TRUE;
18205b261ecSmrg    }
18305b261ecSmrg
18435c4bbdfSmrg    /* Allocate a bitmap header and color table */
18535c4bbdfSmrg    pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
18635c4bbdfSmrg    if (pbmih == NULL) {
18735c4bbdfSmrg        ErrorF("winQueryRGBBitsAndMasks - malloc failed\n");
18835c4bbdfSmrg        return FALSE;
18905b261ecSmrg    }
19005b261ecSmrg
19135c4bbdfSmrg    /* Get screen description */
19235c4bbdfSmrg    if (winQueryScreenDIBFormat(pScreen, pbmih)) {
19335c4bbdfSmrg        /* Get a pointer to bitfields */
19435c4bbdfSmrg        pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER));
19535c4bbdfSmrg
19605b261ecSmrg#if CYGDEBUG
19735c4bbdfSmrg        winDebug("%s - Masks: %08x %08x %08x\n", __FUNCTION__,
19835c4bbdfSmrg                 (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]);
19935c4bbdfSmrg        winDebug("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__,
20035c4bbdfSmrg                 (int)pbmih->biWidth, (int)pbmih->biHeight, pbmih->biBitCount,
20135c4bbdfSmrg                 pbmih->biPlanes);
20235c4bbdfSmrg        winDebug("%s - Compression: %u %s\n", __FUNCTION__,
20335c4bbdfSmrg                 (unsigned int)pbmih->biCompression,
20435c4bbdfSmrg                 (pbmih->biCompression ==
20535c4bbdfSmrg                  BI_RGB ? "(BI_RGB)" : (pbmih->biCompression ==
20635c4bbdfSmrg                                         BI_RLE8 ? "(BI_RLE8)" : (pbmih->
20735c4bbdfSmrg                                                                  biCompression
20835c4bbdfSmrg                                                                  ==
20935c4bbdfSmrg                                                                  BI_RLE4 ?
21035c4bbdfSmrg                                                                  "(BI_RLE4)"
21135c4bbdfSmrg                                                                  : (pbmih->
21235c4bbdfSmrg                                                                     biCompression
21335c4bbdfSmrg                                                                     ==
21435c4bbdfSmrg                                                                     BI_BITFIELDS
21535c4bbdfSmrg                                                                     ?
21635c4bbdfSmrg                                                                     "(BI_BITFIELDS)"
21735c4bbdfSmrg                                                                     : "")))));
21805b261ecSmrg#endif
21905b261ecSmrg
22035c4bbdfSmrg        /* Handle BI_RGB case, which is returned by Wine */
22135c4bbdfSmrg        if (pbmih->biCompression == BI_RGB) {
22235c4bbdfSmrg            dwRedBits = 5;
22335c4bbdfSmrg            dwGreenBits = 5;
22435c4bbdfSmrg            dwBlueBits = 5;
22535c4bbdfSmrg
22635c4bbdfSmrg            pScreenPriv->dwBitsPerRGB = 5;
22735c4bbdfSmrg
22835c4bbdfSmrg            /* Set screen privates masks */
22935c4bbdfSmrg            pScreenPriv->dwRedMask = 0x7c00;
23035c4bbdfSmrg            pScreenPriv->dwGreenMask = 0x03e0;
23135c4bbdfSmrg            pScreenPriv->dwBlueMask = 0x001f;
23235c4bbdfSmrg        }
23335c4bbdfSmrg        else {
23435c4bbdfSmrg            /* Count the number of bits in each mask */
23535c4bbdfSmrg            dwRedBits = winCountBits(pdw[0]);
23635c4bbdfSmrg            dwGreenBits = winCountBits(pdw[1]);
23735c4bbdfSmrg            dwBlueBits = winCountBits(pdw[2]);
23835c4bbdfSmrg
23935c4bbdfSmrg            /* Find maximum bits per red, green, blue */
24035c4bbdfSmrg            if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
24135c4bbdfSmrg                pScreenPriv->dwBitsPerRGB = dwRedBits;
24235c4bbdfSmrg            else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
24335c4bbdfSmrg                pScreenPriv->dwBitsPerRGB = dwGreenBits;
24435c4bbdfSmrg            else
24535c4bbdfSmrg                pScreenPriv->dwBitsPerRGB = dwBlueBits;
24635c4bbdfSmrg
24735c4bbdfSmrg            /* Set screen privates masks */
24835c4bbdfSmrg            pScreenPriv->dwRedMask = pdw[0];
24935c4bbdfSmrg            pScreenPriv->dwGreenMask = pdw[1];
25035c4bbdfSmrg            pScreenPriv->dwBlueMask = pdw[2];
25105b261ecSmrg        }
25205b261ecSmrg    }
25335c4bbdfSmrg    else {
25435c4bbdfSmrg        ErrorF("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n");
25535c4bbdfSmrg        fReturn = FALSE;
25605b261ecSmrg    }
25705b261ecSmrg
25835c4bbdfSmrg    /* Free memory */
25935c4bbdfSmrg    free(pbmih);
26005b261ecSmrg
26135c4bbdfSmrg    return fReturn;
26205b261ecSmrg}
26305b261ecSmrg
26405b261ecSmrg/*
26505b261ecSmrg * Redraw all ---?
26605b261ecSmrg */
26705b261ecSmrg
26805b261ecSmrgstatic wBOOL CALLBACK
26935c4bbdfSmrgwinRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam)
27005b261ecSmrg{
27135c4bbdfSmrg    if (hwnd == (HWND) lParam)
27235c4bbdfSmrg        return TRUE;
27335c4bbdfSmrg    InvalidateRect(hwnd, NULL, FALSE);
27435c4bbdfSmrg    UpdateWindow(hwnd);
27535c4bbdfSmrg    return TRUE;
27605b261ecSmrg}
27705b261ecSmrg
27805b261ecSmrgstatic wBOOL CALLBACK
27935c4bbdfSmrgwinRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam)
28005b261ecSmrg{
28135c4bbdfSmrg    BoxPtr pDamage = (BoxPtr) lParam;
28235c4bbdfSmrg    RECT rcClient, rcDamage, rcRedraw;
28335c4bbdfSmrg    POINT topLeft, bottomRight;
28435c4bbdfSmrg
28535c4bbdfSmrg    if (IsIconic(hwnd))
28635c4bbdfSmrg        return TRUE;            /* Don't care minimized windows */
28735c4bbdfSmrg
28835c4bbdfSmrg    /* Convert the damaged area from Screen coords to Client coords */
28935c4bbdfSmrg    topLeft.x = pDamage->x1;
29035c4bbdfSmrg    topLeft.y = pDamage->y1;
29135c4bbdfSmrg    bottomRight.x = pDamage->x2;
29235c4bbdfSmrg    bottomRight.y = pDamage->y2;
29335c4bbdfSmrg    topLeft.x += GetSystemMetrics(SM_XVIRTUALSCREEN);
29435c4bbdfSmrg    bottomRight.x += GetSystemMetrics(SM_XVIRTUALSCREEN);
29535c4bbdfSmrg    topLeft.y += GetSystemMetrics(SM_YVIRTUALSCREEN);
29635c4bbdfSmrg    bottomRight.y += GetSystemMetrics(SM_YVIRTUALSCREEN);
29735c4bbdfSmrg    ScreenToClient(hwnd, &topLeft);
29835c4bbdfSmrg    ScreenToClient(hwnd, &bottomRight);
29935c4bbdfSmrg    SetRect(&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
30035c4bbdfSmrg
30135c4bbdfSmrg    GetClientRect(hwnd, &rcClient);
30235c4bbdfSmrg
30335c4bbdfSmrg    if (IntersectRect(&rcRedraw, &rcClient, &rcDamage)) {
30435c4bbdfSmrg        InvalidateRect(hwnd, &rcRedraw, FALSE);
30535c4bbdfSmrg        UpdateWindow(hwnd);
30605b261ecSmrg    }
30735c4bbdfSmrg    return TRUE;
30805b261ecSmrg}
30905b261ecSmrg
31005b261ecSmrg/*
31105b261ecSmrg * Allocate a DIB for the shadow framebuffer GDI server
31205b261ecSmrg */
31305b261ecSmrg
31405b261ecSmrgstatic Bool
31535c4bbdfSmrgwinAllocateFBShadowGDI(ScreenPtr pScreen)
31605b261ecSmrg{
31735c4bbdfSmrg    winScreenPriv(pScreen);
31835c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
31935c4bbdfSmrg    DIBSECTION dibsection;
32035c4bbdfSmrg    Bool fReturn = TRUE;
32135c4bbdfSmrg
32235c4bbdfSmrg    /* Describe shadow bitmap to be created */
32335c4bbdfSmrg    pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth;
32435c4bbdfSmrg    pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight;
32535c4bbdfSmrg
32635c4bbdfSmrg    ErrorF("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d "
32735c4bbdfSmrg           "depth: %d\n",
32835c4bbdfSmrg           (int) pScreenPriv->pbmih->biWidth,
32935c4bbdfSmrg           (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount);
33035c4bbdfSmrg
33135c4bbdfSmrg    /* Create a DI shadow bitmap with a bit pointer */
33235c4bbdfSmrg    pScreenPriv->hbmpShadow = CreateDIBSection(pScreenPriv->hdcScreen,
33335c4bbdfSmrg                                               (BITMAPINFO *) pScreenPriv->
33435c4bbdfSmrg                                               pbmih, DIB_RGB_COLORS,
33535c4bbdfSmrg                                               (VOID **) &pScreenInfo->pfb,
33635c4bbdfSmrg                                               NULL, 0);
33735c4bbdfSmrg    if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) {
33835c4bbdfSmrg        winW32Error(2, "winAllocateFBShadowGDI - CreateDIBSection failed:");
33935c4bbdfSmrg        return FALSE;
34005b261ecSmrg    }
34135c4bbdfSmrg    else {
34205b261ecSmrg#if CYGDEBUG
34335c4bbdfSmrg        winDebug("winAllocateFBShadowGDI - Shadow buffer allocated\n");
34405b261ecSmrg#endif
34505b261ecSmrg    }
34605b261ecSmrg
34735c4bbdfSmrg    /* Get information about the bitmap that was allocated */
34835c4bbdfSmrg    GetObject(pScreenPriv->hbmpShadow, sizeof(dibsection), &dibsection);
34905b261ecSmrg
35005b261ecSmrg#if CYGDEBUG || YES
35135c4bbdfSmrg    /* Print information about bitmap allocated */
35235c4bbdfSmrg    winDebug("winAllocateFBShadowGDI - Dibsection width: %d height: %d "
35335c4bbdfSmrg             "depth: %d size image: %d\n",
35435c4bbdfSmrg             (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight,
35535c4bbdfSmrg             dibsection.dsBmih.biBitCount, (int) dibsection.dsBmih.biSizeImage);
35605b261ecSmrg#endif
35705b261ecSmrg
35835c4bbdfSmrg    /* Select the shadow bitmap into the shadow DC */
35935c4bbdfSmrg    SelectObject(pScreenPriv->hdcShadow, pScreenPriv->hbmpShadow);
36005b261ecSmrg
36105b261ecSmrg#if CYGDEBUG
36235c4bbdfSmrg    winDebug("winAllocateFBShadowGDI - Attempting a shadow blit\n");
36305b261ecSmrg#endif
36405b261ecSmrg
36535c4bbdfSmrg    /* Do a test blit from the shadow to the screen, I think */
36635c4bbdfSmrg    fReturn = BitBlt(pScreenPriv->hdcScreen,
36735c4bbdfSmrg                     0, 0,
36835c4bbdfSmrg                     pScreenInfo->dwWidth, pScreenInfo->dwHeight,
36935c4bbdfSmrg                     pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
37035c4bbdfSmrg    if (fReturn) {
37105b261ecSmrg#if CYGDEBUG
37235c4bbdfSmrg        winDebug("winAllocateFBShadowGDI - Shadow blit success\n");
37305b261ecSmrg#endif
37405b261ecSmrg    }
37535c4bbdfSmrg    else {
37635c4bbdfSmrg        winW32Error(2, "winAllocateFBShadowGDI - Shadow blit failure\n");
37735c4bbdfSmrg#if 0
37835c4bbdfSmrg        return FALSE;
37935c4bbdfSmrg#else
38035c4bbdfSmrg        /* ago: ignore this error. The blit fails with wine, but does not
38135c4bbdfSmrg         * cause any problems later. */
38235c4bbdfSmrg
38335c4bbdfSmrg        fReturn = TRUE;
38435c4bbdfSmrg#endif
38505b261ecSmrg    }
38605b261ecSmrg
38735c4bbdfSmrg    /* Look for height weirdness */
38835c4bbdfSmrg    if (dibsection.dsBmih.biHeight < 0) {
38935c4bbdfSmrg        dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight;
39005b261ecSmrg    }
39105b261ecSmrg
39235c4bbdfSmrg    /* Set screeninfo stride */
39335c4bbdfSmrg    pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage
39435c4bbdfSmrg                              / dibsection.dsBmih.biHeight)
39535c4bbdfSmrg                             * 8) / pScreenInfo->dwBPP;
39605b261ecSmrg
39705b261ecSmrg#if CYGDEBUG || YES
39835c4bbdfSmrg    winDebug("winAllocateFBShadowGDI - Created shadow stride: %d\n",
39935c4bbdfSmrg             (int) pScreenInfo->dwStride);
40005b261ecSmrg#endif
40105b261ecSmrg
40235c4bbdfSmrg    /* Redraw all windows */
40335c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
40435c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
40505b261ecSmrg
40635c4bbdfSmrg    return fReturn;
40705b261ecSmrg}
40805b261ecSmrg
4099ace9065Smrgstatic void
41035c4bbdfSmrgwinFreeFBShadowGDI(ScreenPtr pScreen)
4119ace9065Smrg{
41235c4bbdfSmrg    winScreenPriv(pScreen);
41335c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
4149ace9065Smrg
41535c4bbdfSmrg    /* Free the shadow bitmap */
41635c4bbdfSmrg    DeleteObject(pScreenPriv->hbmpShadow);
4179ace9065Smrg
41835c4bbdfSmrg    /* Invalidate the ScreenInfo's fb pointer */
41935c4bbdfSmrg    pScreenInfo->pfb = NULL;
4209ace9065Smrg}
42105b261ecSmrg
42205b261ecSmrg/*
42305b261ecSmrg * Blit the damaged regions of the shadow fb to the screen
42405b261ecSmrg */
42505b261ecSmrg
42605b261ecSmrgstatic void
42735c4bbdfSmrgwinShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf)
42805b261ecSmrg{
42935c4bbdfSmrg    winScreenPriv(pScreen);
43035c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
4311b5d61b8Smrg    RegionPtr damage = DamageRegion(pBuf->pDamage);
43235c4bbdfSmrg    DWORD dwBox = RegionNumRects(damage);
43335c4bbdfSmrg    BoxPtr pBox = RegionRects(damage);
43435c4bbdfSmrg    int x, y, w, h;
43535c4bbdfSmrg    HRGN hrgnCombined = NULL;
43635c4bbdfSmrg
43705b261ecSmrg#ifdef XWIN_UPDATESTATS
43835c4bbdfSmrg    static DWORD s_dwNonUnitRegions = 0;
43935c4bbdfSmrg    static DWORD s_dwTotalUpdates = 0;
44035c4bbdfSmrg    static DWORD s_dwTotalBoxes = 0;
44105b261ecSmrg#endif
44235c4bbdfSmrg    BoxPtr pBoxExtents = RegionExtents(damage);
44305b261ecSmrg
44435c4bbdfSmrg    /*
44535c4bbdfSmrg     * Return immediately if the app is not active
44635c4bbdfSmrg     * and we are fullscreen, or if we have a bad display depth
44735c4bbdfSmrg     */
44835c4bbdfSmrg    if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
44935c4bbdfSmrg        || pScreenPriv->fBadDepth)
45035c4bbdfSmrg        return;
45105b261ecSmrg
45205b261ecSmrg#ifdef XWIN_UPDATESTATS
45335c4bbdfSmrg    ++s_dwTotalUpdates;
45435c4bbdfSmrg    s_dwTotalBoxes += dwBox;
45505b261ecSmrg
45635c4bbdfSmrg    if (dwBox != 1) {
45735c4bbdfSmrg        ++s_dwNonUnitRegions;
45835c4bbdfSmrg        ErrorF("winShadowUpdatGDI - dwBox: %d\n", dwBox);
45905b261ecSmrg    }
46035c4bbdfSmrg
46135c4bbdfSmrg    if ((s_dwTotalUpdates % 100) == 0)
46235c4bbdfSmrg        ErrorF("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d "
46335c4bbdfSmrg               "nu: %d tu: %d\n",
46435c4bbdfSmrg               (s_dwNonUnitRegions * 100) / s_dwTotalUpdates,
46535c4bbdfSmrg               s_dwTotalBoxes / s_dwTotalUpdates,
46635c4bbdfSmrg               s_dwNonUnitRegions, s_dwTotalUpdates);
46735c4bbdfSmrg#endif                          /* XWIN_UPDATESTATS */
46835c4bbdfSmrg
46935c4bbdfSmrg    /*
47035c4bbdfSmrg     * Handle small regions with multiple blits,
47135c4bbdfSmrg     * handle large regions by creating a clipping region and
47235c4bbdfSmrg     * doing a single blit constrained to that clipping region.
47335c4bbdfSmrg     */
47435c4bbdfSmrg    if (!pScreenInfo->fMultiWindow &&
47535c4bbdfSmrg        (pScreenInfo->dwClipUpdatesNBoxes == 0 ||
47635c4bbdfSmrg         dwBox < pScreenInfo->dwClipUpdatesNBoxes)) {
47735c4bbdfSmrg        /* Loop through all boxes in the damaged region */
47835c4bbdfSmrg        while (dwBox--) {
47935c4bbdfSmrg            /*
48035c4bbdfSmrg             * Calculate x offset, y offset, width, and height for
48135c4bbdfSmrg             * current damage box
48235c4bbdfSmrg             */
48335c4bbdfSmrg            x = pBox->x1;
48435c4bbdfSmrg            y = pBox->y1;
48535c4bbdfSmrg            w = pBox->x2 - pBox->x1;
48635c4bbdfSmrg            h = pBox->y2 - pBox->y1;
48735c4bbdfSmrg
48835c4bbdfSmrg            BitBlt(pScreenPriv->hdcScreen,
48935c4bbdfSmrg                   x, y, w, h, pScreenPriv->hdcShadow, x, y, SRCCOPY);
49035c4bbdfSmrg
49135c4bbdfSmrg            /* Get a pointer to the next box */
49235c4bbdfSmrg            ++pBox;
49335c4bbdfSmrg        }
49405b261ecSmrg    }
49535c4bbdfSmrg    else if (!pScreenInfo->fMultiWindow) {
49635c4bbdfSmrg
49735c4bbdfSmrg        /* Compute a GDI region from the damaged region */
49835c4bbdfSmrg        hrgnCombined =
49935c4bbdfSmrg            CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
50035c4bbdfSmrg                          pBoxExtents->y2);
50135c4bbdfSmrg
50235c4bbdfSmrg        /* Install the GDI region as a clipping region */
50335c4bbdfSmrg        SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
50435c4bbdfSmrg        DeleteObject(hrgnCombined);
50535c4bbdfSmrg        hrgnCombined = NULL;
50635c4bbdfSmrg
50735c4bbdfSmrg        /*
50835c4bbdfSmrg         * Blit the shadow buffer to the screen,
50935c4bbdfSmrg         * constrained to the clipping region.
51035c4bbdfSmrg         */
51135c4bbdfSmrg        BitBlt(pScreenPriv->hdcScreen,
51235c4bbdfSmrg               pBoxExtents->x1, pBoxExtents->y1,
51335c4bbdfSmrg               pBoxExtents->x2 - pBoxExtents->x1,
51435c4bbdfSmrg               pBoxExtents->y2 - pBoxExtents->y1,
51535c4bbdfSmrg               pScreenPriv->hdcShadow,
51635c4bbdfSmrg               pBoxExtents->x1, pBoxExtents->y1, SRCCOPY);
51735c4bbdfSmrg
51835c4bbdfSmrg        /* Reset the clip region */
51935c4bbdfSmrg        SelectClipRgn(pScreenPriv->hdcScreen, NULL);
52005b261ecSmrg    }
52105b261ecSmrg
52235c4bbdfSmrg    /* Redraw all multiwindow windows */
52335c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
52435c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID,
52535c4bbdfSmrg                          winRedrawDamagedWindowShadowGDI,
52635c4bbdfSmrg                          (LPARAM) pBoxExtents);
52705b261ecSmrg}
52805b261ecSmrg
5299ace9065Smrgstatic Bool
53035c4bbdfSmrgwinInitScreenShadowGDI(ScreenPtr pScreen)
5319ace9065Smrg{
53235c4bbdfSmrg    winScreenPriv(pScreen);
53335c4bbdfSmrg
53435c4bbdfSmrg    /* Get device contexts for the screen and shadow bitmap */
53535c4bbdfSmrg    pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen);
53635c4bbdfSmrg    pScreenPriv->hdcShadow = CreateCompatibleDC(pScreenPriv->hdcScreen);
53735c4bbdfSmrg
53835c4bbdfSmrg    /* Allocate bitmap info header */
53935c4bbdfSmrg    pScreenPriv->pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
54035c4bbdfSmrg    if (pScreenPriv->pbmih == NULL) {
54135c4bbdfSmrg        ErrorF("winInitScreenShadowGDI - malloc () failed\n");
54235c4bbdfSmrg        return FALSE;
5439ace9065Smrg    }
5449ace9065Smrg
54535c4bbdfSmrg    /* Query the screen format */
54635c4bbdfSmrg    if (!winQueryScreenDIBFormat(pScreen, pScreenPriv->pbmih)) {
54735c4bbdfSmrg        ErrorF("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n");
54835c4bbdfSmrg        return FALSE;
5499ace9065Smrg    }
5509ace9065Smrg
55135c4bbdfSmrg    /* Determine our color masks */
55235c4bbdfSmrg    if (!winQueryRGBBitsAndMasks(pScreen)) {
55335c4bbdfSmrg        ErrorF("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n");
55435c4bbdfSmrg        return FALSE;
5559ace9065Smrg    }
5569ace9065Smrg
55735c4bbdfSmrg    return winAllocateFBShadowGDI(pScreen);
5589ace9065Smrg}
5599ace9065Smrg
56005b261ecSmrg/* See Porting Layer Definition - p. 33 */
56105b261ecSmrg/*
56205b261ecSmrg * We wrap whatever CloseScreen procedure was specified by fb;
56305b261ecSmrg * a pointer to said procedure is stored in our privates.
56405b261ecSmrg */
56505b261ecSmrg
56605b261ecSmrgstatic Bool
56735c4bbdfSmrgwinCloseScreenShadowGDI(ScreenPtr pScreen)
56805b261ecSmrg{
56935c4bbdfSmrg    winScreenPriv(pScreen);
57035c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
5711b5d61b8Smrg    Bool fReturn = TRUE;
57205b261ecSmrg
57305b261ecSmrg#if CYGDEBUG
57435c4bbdfSmrg    winDebug("winCloseScreenShadowGDI - Freeing screen resources\n");
57505b261ecSmrg#endif
57605b261ecSmrg
57735c4bbdfSmrg    /* Flag that the screen is closed */
57835c4bbdfSmrg    pScreenPriv->fClosed = TRUE;
57935c4bbdfSmrg    pScreenPriv->fActive = FALSE;
58005b261ecSmrg
58135c4bbdfSmrg    /* Call the wrapped CloseScreen procedure */
58235c4bbdfSmrg    WIN_UNWRAP(CloseScreen);
58335c4bbdfSmrg    if (pScreen->CloseScreen)
58435c4bbdfSmrg        fReturn = (*pScreen->CloseScreen) (pScreen);
58505b261ecSmrg
58635c4bbdfSmrg    /* Delete the window property */
58735c4bbdfSmrg    RemoveProp(pScreenPriv->hwndScreen, WIN_SCR_PROP);
58805b261ecSmrg
58935c4bbdfSmrg    /* Free the shadow DC; which allows the bitmap to be freed */
59035c4bbdfSmrg    DeleteDC(pScreenPriv->hdcShadow);
5919ace9065Smrg
59235c4bbdfSmrg    winFreeFBShadowGDI(pScreen);
59305b261ecSmrg
59435c4bbdfSmrg    /* Free the screen DC */
59535c4bbdfSmrg    ReleaseDC(pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
59605b261ecSmrg
59735c4bbdfSmrg    /* Delete tray icon, if we have one */
59835c4bbdfSmrg    if (!pScreenInfo->fNoTrayIcon)
59935c4bbdfSmrg        winDeleteNotifyIcon(pScreenPriv);
60005b261ecSmrg
60135c4bbdfSmrg    /* Free the exit confirmation dialog box, if it exists */
60235c4bbdfSmrg    if (g_hDlgExit != NULL) {
60335c4bbdfSmrg        DestroyWindow(g_hDlgExit);
60435c4bbdfSmrg        g_hDlgExit = NULL;
60505b261ecSmrg    }
60605b261ecSmrg
60735c4bbdfSmrg    /* Kill our window */
60835c4bbdfSmrg    if (pScreenPriv->hwndScreen) {
60935c4bbdfSmrg        DestroyWindow(pScreenPriv->hwndScreen);
61035c4bbdfSmrg        pScreenPriv->hwndScreen = NULL;
61105b261ecSmrg    }
61205b261ecSmrg
61335c4bbdfSmrg    /* Destroy the thread startup mutex */
61435c4bbdfSmrg    pthread_mutex_destroy(&pScreenPriv->pmServerStarted);
61505b261ecSmrg
61635c4bbdfSmrg    /* Invalidate our screeninfo's pointer to the screen */
61735c4bbdfSmrg    pScreenInfo->pScreen = NULL;
61805b261ecSmrg
61935c4bbdfSmrg    /* Free the screen privates for this screen */
62035c4bbdfSmrg    free((void *) pScreenPriv);
62105b261ecSmrg
62235c4bbdfSmrg    return fReturn;
62305b261ecSmrg}
62405b261ecSmrg
62505b261ecSmrg/*
62605b261ecSmrg * Tell mi what sort of visuals we need.
62735c4bbdfSmrg *
62805b261ecSmrg * Generally we only need one visual, as our screen can only
62905b261ecSmrg * handle one format at a time, I believe.  You may want
63005b261ecSmrg * to verify that last sentence.
63105b261ecSmrg */
63205b261ecSmrg
63305b261ecSmrgstatic Bool
63435c4bbdfSmrgwinInitVisualsShadowGDI(ScreenPtr pScreen)
63505b261ecSmrg{
63635c4bbdfSmrg    winScreenPriv(pScreen);
63735c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
63835c4bbdfSmrg
63935c4bbdfSmrg    /* Display debugging information */
64035c4bbdfSmrg    ErrorF("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d "
64135c4bbdfSmrg           "bpp %d\n",
64235c4bbdfSmrg           (unsigned int) pScreenPriv->dwRedMask,
64335c4bbdfSmrg           (unsigned int) pScreenPriv->dwGreenMask,
64435c4bbdfSmrg           (unsigned int) pScreenPriv->dwBlueMask,
64535c4bbdfSmrg           (int) pScreenPriv->dwBitsPerRGB,
64635c4bbdfSmrg           (int) pScreenInfo->dwDepth, (int) pScreenInfo->dwBPP);
64735c4bbdfSmrg
64835c4bbdfSmrg    /* Create a single visual according to the Windows screen depth */
64935c4bbdfSmrg    switch (pScreenInfo->dwDepth) {
65005b261ecSmrg    case 24:
65105b261ecSmrg    case 16:
65205b261ecSmrg    case 15:
65335c4bbdfSmrg        /* Setup the real visual */
65435c4bbdfSmrg        if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
65535c4bbdfSmrg                                      TrueColorMask,
65635c4bbdfSmrg                                      pScreenPriv->dwBitsPerRGB,
65735c4bbdfSmrg                                      -1,
65835c4bbdfSmrg                                      pScreenPriv->dwRedMask,
65935c4bbdfSmrg                                      pScreenPriv->dwGreenMask,
66035c4bbdfSmrg                                      pScreenPriv->dwBlueMask)) {
66135c4bbdfSmrg            ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
66235c4bbdfSmrg                   "failed\n");
66335c4bbdfSmrg            return FALSE;
66435c4bbdfSmrg        }
66505b261ecSmrg
66605b261ecSmrg#ifdef XWIN_EMULATEPSEUDO
66735c4bbdfSmrg        if (!pScreenInfo->fEmulatePseudo)
66835c4bbdfSmrg            break;
66935c4bbdfSmrg
67035c4bbdfSmrg        /* Setup a pseudocolor visual */
67135c4bbdfSmrg        if (!miSetVisualTypesAndMasks(8, PseudoColorMask, 8, -1, 0, 0, 0)) {
67235c4bbdfSmrg            ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
67335c4bbdfSmrg                   "failed for PseudoColor\n");
67435c4bbdfSmrg            return FALSE;
67535c4bbdfSmrg        }
67605b261ecSmrg#endif
67735c4bbdfSmrg        break;
67805b261ecSmrg
67905b261ecSmrg    case 8:
68035c4bbdfSmrg        if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
68135c4bbdfSmrg                                      PseudoColorMask,
68235c4bbdfSmrg                                      pScreenPriv->dwBitsPerRGB,
68335c4bbdfSmrg                                      PseudoColor,
68435c4bbdfSmrg                                      pScreenPriv->dwRedMask,
68535c4bbdfSmrg                                      pScreenPriv->dwGreenMask,
68635c4bbdfSmrg                                      pScreenPriv->dwBlueMask)) {
68735c4bbdfSmrg            ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
68835c4bbdfSmrg                   "failed\n");
68935c4bbdfSmrg            return FALSE;
69035c4bbdfSmrg        }
69135c4bbdfSmrg        break;
69205b261ecSmrg
69305b261ecSmrg    default:
69435c4bbdfSmrg        ErrorF("winInitVisualsShadowGDI - Unknown screen depth\n");
69535c4bbdfSmrg        return FALSE;
69605b261ecSmrg    }
69705b261ecSmrg
69805b261ecSmrg#if CYGDEBUG
69935c4bbdfSmrg    winDebug("winInitVisualsShadowGDI - Returning\n");
70005b261ecSmrg#endif
70105b261ecSmrg
70235c4bbdfSmrg    return TRUE;
70305b261ecSmrg}
70405b261ecSmrg
70505b261ecSmrg/*
70605b261ecSmrg * Adjust the proposed video mode
70705b261ecSmrg */
70805b261ecSmrg
70905b261ecSmrgstatic Bool
71035c4bbdfSmrgwinAdjustVideoModeShadowGDI(ScreenPtr pScreen)
71105b261ecSmrg{
71235c4bbdfSmrg    winScreenPriv(pScreen);
71335c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
71435c4bbdfSmrg    HDC hdc;
71535c4bbdfSmrg    DWORD dwBPP;
71635c4bbdfSmrg
71735c4bbdfSmrg    hdc = GetDC(NULL);
71835c4bbdfSmrg
71935c4bbdfSmrg    /* We're in serious trouble if we can't get a DC */
72035c4bbdfSmrg    if (hdc == NULL) {
72135c4bbdfSmrg        ErrorF("winAdjustVideoModeShadowGDI - GetDC () failed\n");
72235c4bbdfSmrg        return FALSE;
72305b261ecSmrg    }
72405b261ecSmrg
72535c4bbdfSmrg    /* Query GDI for current display depth */
72635c4bbdfSmrg    dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
72705b261ecSmrg
72835c4bbdfSmrg    /* GDI cannot change the screen depth, so always use GDI's depth */
72935c4bbdfSmrg    pScreenInfo->dwBPP = dwBPP;
73005b261ecSmrg
73135c4bbdfSmrg    /* Release our DC */
73235c4bbdfSmrg    ReleaseDC(NULL, hdc);
73335c4bbdfSmrg    hdc = NULL;
73405b261ecSmrg
73535c4bbdfSmrg    return TRUE;
73605b261ecSmrg}
73705b261ecSmrg
73805b261ecSmrg/*
73905b261ecSmrg * Blt exposed regions to the screen
74005b261ecSmrg */
74105b261ecSmrg
74205b261ecSmrgstatic Bool
74335c4bbdfSmrgwinBltExposedRegionsShadowGDI(ScreenPtr pScreen)
74405b261ecSmrg{
74535c4bbdfSmrg    winScreenPriv(pScreen);
74635c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
74735c4bbdfSmrg    winPrivCmapPtr pCmapPriv = NULL;
74835c4bbdfSmrg    HDC hdcUpdate;
74935c4bbdfSmrg    PAINTSTRUCT ps;
75035c4bbdfSmrg
75135c4bbdfSmrg    /* BeginPaint gives us an hdc that clips to the invalidated region */
75235c4bbdfSmrg    hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps);
75335c4bbdfSmrg
75435c4bbdfSmrg    /* Realize the palette, if we have one */
75535c4bbdfSmrg    if (pScreenPriv->pcmapInstalled != NULL) {
75635c4bbdfSmrg        pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled);
75735c4bbdfSmrg
75835c4bbdfSmrg        SelectPalette(hdcUpdate, pCmapPriv->hPalette, FALSE);
75935c4bbdfSmrg        RealizePalette(hdcUpdate);
76005b261ecSmrg    }
76105b261ecSmrg
76235c4bbdfSmrg    /* Our BitBlt will be clipped to the invalidated region */
76335c4bbdfSmrg    BitBlt(hdcUpdate,
76435c4bbdfSmrg           0, 0,
76535c4bbdfSmrg           pScreenInfo->dwWidth, pScreenInfo->dwHeight,
76635c4bbdfSmrg           pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
76705b261ecSmrg
76835c4bbdfSmrg    /* EndPaint frees the DC */
76935c4bbdfSmrg    EndPaint(pScreenPriv->hwndScreen, &ps);
77005b261ecSmrg
77135c4bbdfSmrg    /* Redraw all windows */
77235c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
77335c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI,
77435c4bbdfSmrg                          (LPARAM) pScreenPriv->hwndScreen);
77505b261ecSmrg
77635c4bbdfSmrg    return TRUE;
77705b261ecSmrg}
77805b261ecSmrg
77905b261ecSmrg/*
78005b261ecSmrg * Do any engine-specific appliation-activation processing
78105b261ecSmrg */
78205b261ecSmrg
78305b261ecSmrgstatic Bool
78435c4bbdfSmrgwinActivateAppShadowGDI(ScreenPtr pScreen)
78505b261ecSmrg{
78635c4bbdfSmrg    winScreenPriv(pScreen);
78735c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
78835c4bbdfSmrg
78935c4bbdfSmrg    /*
79035c4bbdfSmrg     * 2004/04/12 - Harold - We perform the restoring or minimizing
79135c4bbdfSmrg     * manually for ShadowGDI in fullscreen modes so that this engine
79235c4bbdfSmrg     * will perform just like ShadowDD and ShadowDDNL in fullscreen mode;
79335c4bbdfSmrg     * if we do not do this then our fullscreen window will appear in the
79435c4bbdfSmrg     * z-order when it is deactivated and it can be uncovered by resizing
79535c4bbdfSmrg     * or minimizing another window that is on top of it, which is not how
79635c4bbdfSmrg     * the DirectDraw engines work.  Therefore we keep this code here to
79735c4bbdfSmrg     * make sure that all engines work the same in fullscreen mode.
79835c4bbdfSmrg     */
79935c4bbdfSmrg
80035c4bbdfSmrg    /*
80135c4bbdfSmrg     * Are we active?
80235c4bbdfSmrg     * Are we fullscreen?
80335c4bbdfSmrg     */
80435c4bbdfSmrg    if (pScreenPriv->fActive && pScreenInfo->fFullScreen) {
80535c4bbdfSmrg        /*
80635c4bbdfSmrg         * Activating, attempt to bring our window
80735c4bbdfSmrg         * to the top of the display
80835c4bbdfSmrg         */
80935c4bbdfSmrg        ShowWindow(pScreenPriv->hwndScreen, SW_RESTORE);
81005b261ecSmrg    }
81135c4bbdfSmrg    else if (!pScreenPriv->fActive && pScreenInfo->fFullScreen) {
81235c4bbdfSmrg        /*
81335c4bbdfSmrg         * Deactivating, stuff our window onto the
81435c4bbdfSmrg         * task bar.
81535c4bbdfSmrg         */
81635c4bbdfSmrg        ShowWindow(pScreenPriv->hwndScreen, SW_MINIMIZE);
81705b261ecSmrg    }
81805b261ecSmrg
81935c4bbdfSmrg    return TRUE;
82005b261ecSmrg}
82105b261ecSmrg
82205b261ecSmrg/*
82305b261ecSmrg * Reblit the shadow framebuffer to the screen.
82405b261ecSmrg */
82505b261ecSmrg
82605b261ecSmrgstatic Bool
82735c4bbdfSmrgwinRedrawScreenShadowGDI(ScreenPtr pScreen)
82805b261ecSmrg{
82935c4bbdfSmrg    winScreenPriv(pScreen);
83035c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
83105b261ecSmrg
83235c4bbdfSmrg    /* Redraw the whole window, to take account for the new colors */
83335c4bbdfSmrg    BitBlt(pScreenPriv->hdcScreen,
83435c4bbdfSmrg           0, 0,
83535c4bbdfSmrg           pScreenInfo->dwWidth, pScreenInfo->dwHeight,
83635c4bbdfSmrg           pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
83705b261ecSmrg
83835c4bbdfSmrg    /* Redraw all windows */
83935c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
84035c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
84105b261ecSmrg
84235c4bbdfSmrg    return TRUE;
84305b261ecSmrg}
84405b261ecSmrg
84505b261ecSmrg/*
84605b261ecSmrg * Realize the currently installed colormap
84705b261ecSmrg */
84805b261ecSmrg
84905b261ecSmrgstatic Bool
85035c4bbdfSmrgwinRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen)
85105b261ecSmrg{
85235c4bbdfSmrg    winScreenPriv(pScreen);
85335c4bbdfSmrg    winPrivCmapPtr pCmapPriv = NULL;
85405b261ecSmrg
85505b261ecSmrg#if CYGDEBUG
85635c4bbdfSmrg    winDebug("winRealizeInstalledPaletteShadowGDI\n");
85705b261ecSmrg#endif
85805b261ecSmrg
85935c4bbdfSmrg    /* Don't do anything if there is not a colormap */
86035c4bbdfSmrg    if (pScreenPriv->pcmapInstalled == NULL) {
86105b261ecSmrg#if CYGDEBUG
86235c4bbdfSmrg        winDebug("winRealizeInstalledPaletteShadowGDI - No colormap "
86335c4bbdfSmrg                 "installed\n");
86405b261ecSmrg#endif
86535c4bbdfSmrg        return TRUE;
86605b261ecSmrg    }
86705b261ecSmrg
86835c4bbdfSmrg    pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled);
86935c4bbdfSmrg
87035c4bbdfSmrg    /* Realize our palette for the screen */
87135c4bbdfSmrg    if (RealizePalette(pScreenPriv->hdcScreen) == GDI_ERROR) {
87235c4bbdfSmrg        ErrorF("winRealizeInstalledPaletteShadowGDI - RealizePalette () "
87335c4bbdfSmrg               "failed\n");
87435c4bbdfSmrg        return FALSE;
87505b261ecSmrg    }
87635c4bbdfSmrg
87735c4bbdfSmrg    /* Set the DIB color table */
87835c4bbdfSmrg    if (SetDIBColorTable(pScreenPriv->hdcShadow,
87935c4bbdfSmrg                         0,
88035c4bbdfSmrg                         WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) {
88135c4bbdfSmrg        ErrorF("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () "
88235c4bbdfSmrg               "failed\n");
88335c4bbdfSmrg        return FALSE;
88405b261ecSmrg    }
88505b261ecSmrg
88635c4bbdfSmrg    return TRUE;
88735c4bbdfSmrg}
88805b261ecSmrg
88905b261ecSmrg/*
89005b261ecSmrg * Install the specified colormap
89105b261ecSmrg */
89205b261ecSmrg
89305b261ecSmrgstatic Bool
89435c4bbdfSmrgwinInstallColormapShadowGDI(ColormapPtr pColormap)
89505b261ecSmrg{
89635c4bbdfSmrg    ScreenPtr pScreen = pColormap->pScreen;
89735c4bbdfSmrg
89835c4bbdfSmrg    winScreenPriv(pScreen);
89935c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
90035c4bbdfSmrg
90135c4bbdfSmrg    winCmapPriv(pColormap);
90235c4bbdfSmrg
90335c4bbdfSmrg    /*
90435c4bbdfSmrg     * Tell Windows to install the new colormap
90535c4bbdfSmrg     */
90635c4bbdfSmrg    if (SelectPalette(pScreenPriv->hdcScreen,
90735c4bbdfSmrg                      pCmapPriv->hPalette, FALSE) == NULL) {
90835c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - SelectPalette () failed\n");
90935c4bbdfSmrg        return FALSE;
91005b261ecSmrg    }
91135c4bbdfSmrg
91235c4bbdfSmrg    /* Realize the palette */
91335c4bbdfSmrg    if (GDI_ERROR == RealizePalette(pScreenPriv->hdcScreen)) {
91435c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - RealizePalette () failed\n");
91535c4bbdfSmrg        return FALSE;
91605b261ecSmrg    }
91705b261ecSmrg
91835c4bbdfSmrg    /* Set the DIB color table */
91935c4bbdfSmrg    if (SetDIBColorTable(pScreenPriv->hdcShadow,
92035c4bbdfSmrg                         0,
92135c4bbdfSmrg                         WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) {
92235c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
92335c4bbdfSmrg        return FALSE;
92405b261ecSmrg    }
92505b261ecSmrg
92635c4bbdfSmrg    /* Redraw the whole window, to take account for the new colors */
92735c4bbdfSmrg    BitBlt(pScreenPriv->hdcScreen,
92835c4bbdfSmrg           0, 0,
92935c4bbdfSmrg           pScreenInfo->dwWidth, pScreenInfo->dwHeight,
93035c4bbdfSmrg           pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
93105b261ecSmrg
93235c4bbdfSmrg    /* Save a pointer to the newly installed colormap */
93335c4bbdfSmrg    pScreenPriv->pcmapInstalled = pColormap;
93405b261ecSmrg
93535c4bbdfSmrg    /* Redraw all windows */
93635c4bbdfSmrg    if (pScreenInfo->fMultiWindow)
93735c4bbdfSmrg        EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
93805b261ecSmrg
93935c4bbdfSmrg    return TRUE;
94005b261ecSmrg}
94105b261ecSmrg
94205b261ecSmrg/*
94305b261ecSmrg * Store the specified colors in the specified colormap
94405b261ecSmrg */
94505b261ecSmrg
94605b261ecSmrgstatic Bool
94735c4bbdfSmrgwinStoreColorsShadowGDI(ColormapPtr pColormap, int ndef, xColorItem * pdefs)
94805b261ecSmrg{
94935c4bbdfSmrg    ScreenPtr pScreen = pColormap->pScreen;
95035c4bbdfSmrg
95135c4bbdfSmrg    winScreenPriv(pScreen);
95235c4bbdfSmrg    winCmapPriv(pColormap);
95335c4bbdfSmrg    ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
95435c4bbdfSmrg
95535c4bbdfSmrg    /* Put the X colormap entries into the Windows logical palette */
95635c4bbdfSmrg    if (SetPaletteEntries(pCmapPriv->hPalette,
95735c4bbdfSmrg                          pdefs[0].pixel,
95835c4bbdfSmrg                          ndef, pCmapPriv->peColors + pdefs[0].pixel) == 0) {
95935c4bbdfSmrg        ErrorF("winStoreColorsShadowGDI - SetPaletteEntries () failed\n");
96035c4bbdfSmrg        return FALSE;
96105b261ecSmrg    }
96205b261ecSmrg
96335c4bbdfSmrg    /* Don't install the Windows palette if the colormap is not installed */
96435c4bbdfSmrg    if (pColormap != curpmap) {
96535c4bbdfSmrg        return TRUE;
96605b261ecSmrg    }
96705b261ecSmrg
96835c4bbdfSmrg    /* Try to install the newly modified colormap */
96935c4bbdfSmrg    if (!winInstallColormapShadowGDI(pColormap)) {
97035c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - winInstallColormapShadowGDI "
97135c4bbdfSmrg               "failed\n");
97235c4bbdfSmrg        return FALSE;
97305b261ecSmrg    }
97405b261ecSmrg
97505b261ecSmrg#if 0
97635c4bbdfSmrg    /* Tell Windows that the palette has changed */
97735c4bbdfSmrg    RealizePalette(pScreenPriv->hdcScreen);
97835c4bbdfSmrg
97935c4bbdfSmrg    /* Set the DIB color table */
98035c4bbdfSmrg    if (SetDIBColorTable(pScreenPriv->hdcShadow,
98135c4bbdfSmrg                         pdefs[0].pixel,
98235c4bbdfSmrg                         ndef, pCmapPriv->rgbColors + pdefs[0].pixel) == 0) {
98335c4bbdfSmrg        ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
98435c4bbdfSmrg        return FALSE;
98505b261ecSmrg    }
98605b261ecSmrg
98735c4bbdfSmrg    /* Save a pointer to the newly installed colormap */
98835c4bbdfSmrg    pScreenPriv->pcmapInstalled = pColormap;
98905b261ecSmrg#endif
99005b261ecSmrg
99135c4bbdfSmrg    return TRUE;
99205b261ecSmrg}
99305b261ecSmrg
99405b261ecSmrg/*
99505b261ecSmrg * Colormap initialization procedure
99605b261ecSmrg */
99705b261ecSmrg
99805b261ecSmrgstatic Bool
99935c4bbdfSmrgwinCreateColormapShadowGDI(ColormapPtr pColormap)
100005b261ecSmrg{
100135c4bbdfSmrg    LPLOGPALETTE lpPaletteNew = NULL;
100235c4bbdfSmrg    DWORD dwEntriesMax;
100335c4bbdfSmrg    VisualPtr pVisual;
100435c4bbdfSmrg    HPALETTE hpalNew = NULL;
100535c4bbdfSmrg
100635c4bbdfSmrg    winCmapPriv(pColormap);
100735c4bbdfSmrg
100835c4bbdfSmrg    /* Get a pointer to the visual that the colormap belongs to */
100935c4bbdfSmrg    pVisual = pColormap->pVisual;
101035c4bbdfSmrg
101135c4bbdfSmrg    /* Get the maximum number of palette entries for this visual */
101235c4bbdfSmrg    dwEntriesMax = pVisual->ColormapEntries;
101335c4bbdfSmrg
101435c4bbdfSmrg    /* Allocate a Windows logical color palette with max entries */
101535c4bbdfSmrg    lpPaletteNew = malloc(sizeof(LOGPALETTE)
101635c4bbdfSmrg                          + (dwEntriesMax - 1) * sizeof(PALETTEENTRY));
101735c4bbdfSmrg    if (lpPaletteNew == NULL) {
101835c4bbdfSmrg        ErrorF("winCreateColormapShadowGDI - Couldn't allocate palette "
101935c4bbdfSmrg               "with %d entries\n", (int) dwEntriesMax);
102035c4bbdfSmrg        return FALSE;
102105b261ecSmrg    }
102205b261ecSmrg
102335c4bbdfSmrg    /* Zero out the colormap */
102435c4bbdfSmrg    ZeroMemory(lpPaletteNew, sizeof(LOGPALETTE)
102535c4bbdfSmrg               + (dwEntriesMax - 1) * sizeof(PALETTEENTRY));
102635c4bbdfSmrg
102735c4bbdfSmrg    /* Set the logical palette structure */
102835c4bbdfSmrg    lpPaletteNew->palVersion = 0x0300;
102935c4bbdfSmrg    lpPaletteNew->palNumEntries = dwEntriesMax;
103035c4bbdfSmrg
103135c4bbdfSmrg    /* Tell Windows to create the palette */
103235c4bbdfSmrg    hpalNew = CreatePalette(lpPaletteNew);
103335c4bbdfSmrg    if (hpalNew == NULL) {
103435c4bbdfSmrg        ErrorF("winCreateColormapShadowGDI - CreatePalette () failed\n");
103535c4bbdfSmrg        free(lpPaletteNew);
103635c4bbdfSmrg        return FALSE;
103705b261ecSmrg    }
103805b261ecSmrg
103935c4bbdfSmrg    /* Save the Windows logical palette handle in the X colormaps' privates */
104035c4bbdfSmrg    pCmapPriv->hPalette = hpalNew;
104105b261ecSmrg
104235c4bbdfSmrg    /* Free the palette initialization memory */
104335c4bbdfSmrg    free(lpPaletteNew);
104405b261ecSmrg
104535c4bbdfSmrg    return TRUE;
104605b261ecSmrg}
104705b261ecSmrg
104805b261ecSmrg/*
104905b261ecSmrg * Colormap destruction procedure
105005b261ecSmrg */
105105b261ecSmrg
105205b261ecSmrgstatic Bool
105335c4bbdfSmrgwinDestroyColormapShadowGDI(ColormapPtr pColormap)
105405b261ecSmrg{
105535c4bbdfSmrg    winScreenPriv(pColormap->pScreen);
105635c4bbdfSmrg    winCmapPriv(pColormap);
105735c4bbdfSmrg
105835c4bbdfSmrg    /*
105935c4bbdfSmrg     * Is colormap to be destroyed the default?
106035c4bbdfSmrg     *
106135c4bbdfSmrg     * Non-default colormaps should have had winUninstallColormap
106235c4bbdfSmrg     * called on them before we get here.  The default colormap
106335c4bbdfSmrg     * will not have had winUninstallColormap called on it.  Thus,
106435c4bbdfSmrg     * we need to handle the default colormap in a special way.
106535c4bbdfSmrg     */
106635c4bbdfSmrg    if (pColormap->flags & IsDefault) {
106705b261ecSmrg#if CYGDEBUG
106835c4bbdfSmrg        winDebug("winDestroyColormapShadowGDI - Destroying default "
106935c4bbdfSmrg                 "colormap\n");
107005b261ecSmrg#endif
107135c4bbdfSmrg
107235c4bbdfSmrg        /*
107335c4bbdfSmrg         * FIXME: Walk the list of all screens, popping the default
107435c4bbdfSmrg         * palette out of each screen device context.
107535c4bbdfSmrg         */
107635c4bbdfSmrg
107735c4bbdfSmrg        /* Pop the palette out of the device context */
107835c4bbdfSmrg        SelectPalette(pScreenPriv->hdcScreen,
107935c4bbdfSmrg                      GetStockObject(DEFAULT_PALETTE), FALSE);
108035c4bbdfSmrg
108135c4bbdfSmrg        /* Clear our private installed colormap pointer */
108235c4bbdfSmrg        pScreenPriv->pcmapInstalled = NULL;
108305b261ecSmrg    }
108435c4bbdfSmrg
108535c4bbdfSmrg    /* Try to delete the logical palette */
108635c4bbdfSmrg    if (DeleteObject(pCmapPriv->hPalette) == 0) {
108735c4bbdfSmrg        ErrorF("winDestroyColormap - DeleteObject () failed\n");
108835c4bbdfSmrg        return FALSE;
108905b261ecSmrg    }
109005b261ecSmrg
109135c4bbdfSmrg    /* Invalidate the colormap privates */
109235c4bbdfSmrg    pCmapPriv->hPalette = NULL;
109305b261ecSmrg
109435c4bbdfSmrg    return TRUE;
109535c4bbdfSmrg}
109605b261ecSmrg
109705b261ecSmrg/*
109805b261ecSmrg * Set engine specific funtions
109905b261ecSmrg */
110005b261ecSmrg
110105b261ecSmrgBool
110235c4bbdfSmrgwinSetEngineFunctionsShadowGDI(ScreenPtr pScreen)
110305b261ecSmrg{
110435c4bbdfSmrg    winScreenPriv(pScreen);
110535c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
110635c4bbdfSmrg
110735c4bbdfSmrg    /* Set our pointers */
110835c4bbdfSmrg    pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI;
110935c4bbdfSmrg    pScreenPriv->pwinFreeFB = winFreeFBShadowGDI;
111035c4bbdfSmrg    pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI;
111135c4bbdfSmrg    pScreenPriv->pwinInitScreen = winInitScreenShadowGDI;
111235c4bbdfSmrg    pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI;
111335c4bbdfSmrg    pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI;
111435c4bbdfSmrg    pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI;
111535c4bbdfSmrg    if (pScreenInfo->fFullScreen)
111635c4bbdfSmrg        pScreenPriv->pwinCreateBoundingWindow =
111735c4bbdfSmrg            winCreateBoundingWindowFullScreen;
111835c4bbdfSmrg    else
111935c4bbdfSmrg        pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
112035c4bbdfSmrg    pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
112135c4bbdfSmrg    pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI;
112235c4bbdfSmrg    pScreenPriv->pwinActivateApp = winActivateAppShadowGDI;
112335c4bbdfSmrg    pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI;
112435c4bbdfSmrg    pScreenPriv->pwinRealizeInstalledPalette =
112535c4bbdfSmrg        winRealizeInstalledPaletteShadowGDI;
112635c4bbdfSmrg    pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI;
112735c4bbdfSmrg    pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI;
112835c4bbdfSmrg    pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI;
112935c4bbdfSmrg    pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI;
11301b5d61b8Smrg    pScreenPriv->pwinCreatePrimarySurface = NULL;
11311b5d61b8Smrg    pScreenPriv->pwinReleasePrimarySurface = NULL;
113205b261ecSmrg
113335c4bbdfSmrg    return TRUE;
113405b261ecSmrg}
1135