winshadgdi.c revision 9ace9065
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/*
3805b261ecSmrg * Local function prototypes
3905b261ecSmrg */
4005b261ecSmrg
4105b261ecSmrg#ifdef XWIN_MULTIWINDOW
4205b261ecSmrgstatic wBOOL CALLBACK
4305b261ecSmrgwinRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam);
4405b261ecSmrg
4505b261ecSmrgstatic wBOOL CALLBACK
4605b261ecSmrgwinRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam);
4705b261ecSmrg#endif
4805b261ecSmrg
4905b261ecSmrgstatic Bool
5005b261ecSmrgwinAllocateFBShadowGDI (ScreenPtr pScreen);
5105b261ecSmrg
5205b261ecSmrgstatic void
5305b261ecSmrgwinShadowUpdateGDI (ScreenPtr pScreen,
5405b261ecSmrg		    shadowBufPtr pBuf);
5505b261ecSmrg
5605b261ecSmrgstatic Bool
5705b261ecSmrgwinCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen);
5805b261ecSmrg
5905b261ecSmrgstatic Bool
6005b261ecSmrgwinInitVisualsShadowGDI (ScreenPtr pScreen);
6105b261ecSmrg
6205b261ecSmrgstatic Bool
6305b261ecSmrgwinAdjustVideoModeShadowGDI (ScreenPtr pScreen);
6405b261ecSmrg
6505b261ecSmrgstatic Bool
6605b261ecSmrgwinBltExposedRegionsShadowGDI (ScreenPtr pScreen);
6705b261ecSmrg
6805b261ecSmrgstatic Bool
6905b261ecSmrgwinActivateAppShadowGDI (ScreenPtr pScreen);
7005b261ecSmrg
7105b261ecSmrgstatic Bool
7205b261ecSmrgwinRedrawScreenShadowGDI (ScreenPtr pScreen);
7305b261ecSmrg
7405b261ecSmrgstatic Bool
7505b261ecSmrgwinRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen);
7605b261ecSmrg
7705b261ecSmrgstatic Bool
7805b261ecSmrgwinInstallColormapShadowGDI (ColormapPtr pColormap);
7905b261ecSmrg
8005b261ecSmrgstatic Bool
8105b261ecSmrgwinStoreColorsShadowGDI (ColormapPtr pmap,
8205b261ecSmrg			 int ndef,
8305b261ecSmrg			 xColorItem *pdefs);
8405b261ecSmrg
8505b261ecSmrgstatic Bool
8605b261ecSmrgwinCreateColormapShadowGDI (ColormapPtr pColormap);
8705b261ecSmrg
8805b261ecSmrgstatic Bool
8905b261ecSmrgwinDestroyColormapShadowGDI (ColormapPtr pColormap);
9005b261ecSmrg
9105b261ecSmrg
9205b261ecSmrg/*
9305b261ecSmrg * Internal function to get the DIB format that is compatible with the screen
9405b261ecSmrg */
9505b261ecSmrg
9605b261ecSmrgstatic
9705b261ecSmrgBool
9805b261ecSmrgwinQueryScreenDIBFormat (ScreenPtr pScreen, BITMAPINFOHEADER *pbmih)
9905b261ecSmrg{
10005b261ecSmrg  winScreenPriv(pScreen);
10105b261ecSmrg  HBITMAP		hbmp;
10205b261ecSmrg#if CYGDEBUG
10305b261ecSmrg  LPDWORD		pdw = NULL;
10405b261ecSmrg#endif
10505b261ecSmrg
10605b261ecSmrg  /* Create a memory bitmap compatible with the screen */
10705b261ecSmrg  hbmp = CreateCompatibleBitmap (pScreenPriv->hdcScreen, 1, 1);
10805b261ecSmrg  if (hbmp == NULL)
10905b261ecSmrg    {
11005b261ecSmrg      ErrorF ("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n");
11105b261ecSmrg      return FALSE;
11205b261ecSmrg    }
11305b261ecSmrg
11405b261ecSmrg  /* Initialize our bitmap info header */
11505b261ecSmrg  ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD));
11605b261ecSmrg  pbmih->biSize = sizeof (BITMAPINFOHEADER);
11705b261ecSmrg
11805b261ecSmrg  /* Get the biBitCount */
11905b261ecSmrg  if (!GetDIBits (pScreenPriv->hdcScreen,
12005b261ecSmrg		  hbmp,
12105b261ecSmrg		  0, 1,
12205b261ecSmrg		  NULL,
12305b261ecSmrg		  (BITMAPINFO*) pbmih,
12405b261ecSmrg		  DIB_RGB_COLORS))
12505b261ecSmrg    {
12605b261ecSmrg      ErrorF ("winQueryScreenDIBFormat - First call to GetDIBits failed\n");
12705b261ecSmrg      DeleteObject (hbmp);
12805b261ecSmrg      return FALSE;
12905b261ecSmrg    }
13005b261ecSmrg
13105b261ecSmrg#if CYGDEBUG
13205b261ecSmrg  /* Get a pointer to bitfields */
13305b261ecSmrg  pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER));
13405b261ecSmrg
13505b261ecSmrg  winDebug ("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n",
13605b261ecSmrg	  pdw[0], pdw[1], pdw[2]);
13705b261ecSmrg#endif
13805b261ecSmrg
13905b261ecSmrg  /* Get optimal color table, or the optimal bitfields */
14005b261ecSmrg  if (!GetDIBits (pScreenPriv->hdcScreen,
14105b261ecSmrg		  hbmp,
14205b261ecSmrg		  0, 1,
14305b261ecSmrg		  NULL,
14405b261ecSmrg		  (BITMAPINFO*)pbmih,
14505b261ecSmrg		  DIB_RGB_COLORS))
14605b261ecSmrg    {
14705b261ecSmrg      ErrorF ("winQueryScreenDIBFormat - Second call to GetDIBits "
14805b261ecSmrg	      "failed\n");
14905b261ecSmrg      DeleteObject (hbmp);
15005b261ecSmrg      return FALSE;
15105b261ecSmrg    }
15205b261ecSmrg
15305b261ecSmrg  /* Free memory */
15405b261ecSmrg  DeleteObject (hbmp);
15505b261ecSmrg
15605b261ecSmrg  return TRUE;
15705b261ecSmrg}
15805b261ecSmrg
15905b261ecSmrg
16005b261ecSmrg/*
16105b261ecSmrg * Internal function to determine the GDI bits per rgb and bit masks
16205b261ecSmrg */
16305b261ecSmrg
16405b261ecSmrgstatic
16505b261ecSmrgBool
16605b261ecSmrgwinQueryRGBBitsAndMasks (ScreenPtr pScreen)
16705b261ecSmrg{
16805b261ecSmrg  winScreenPriv(pScreen);
16905b261ecSmrg  BITMAPINFOHEADER	*pbmih = NULL;
17005b261ecSmrg  Bool			fReturn = TRUE;
17105b261ecSmrg  LPDWORD		pdw = NULL;
17205b261ecSmrg  DWORD			dwRedBits, dwGreenBits, dwBlueBits;
17305b261ecSmrg
17405b261ecSmrg  /* Color masks for 8 bpp are standardized */
17505b261ecSmrg  if (GetDeviceCaps (pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE)
17605b261ecSmrg    {
17705b261ecSmrg      /*
17805b261ecSmrg       * RGB BPP for 8 bit palletes is always 8
17905b261ecSmrg       * and the color masks are always 0.
18005b261ecSmrg       */
18105b261ecSmrg      pScreenPriv->dwBitsPerRGB = 8;
18205b261ecSmrg      pScreenPriv->dwRedMask = 0x0L;
18305b261ecSmrg      pScreenPriv->dwGreenMask = 0x0L;
18405b261ecSmrg      pScreenPriv->dwBlueMask = 0x0L;
18505b261ecSmrg      return TRUE;
18605b261ecSmrg    }
18705b261ecSmrg
18805b261ecSmrg  /* Color masks for 24 bpp are standardized */
18905b261ecSmrg  if (GetDeviceCaps (pScreenPriv->hdcScreen, PLANES)
19005b261ecSmrg      * GetDeviceCaps (pScreenPriv->hdcScreen, BITSPIXEL) == 24)
19105b261ecSmrg    {
19205b261ecSmrg      ErrorF ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) "
19305b261ecSmrg	      "returned 24 for the screen.  Using default 24bpp masks.\n");
19405b261ecSmrg
19505b261ecSmrg      /* 8 bits per primary color */
19605b261ecSmrg      pScreenPriv->dwBitsPerRGB = 8;
19705b261ecSmrg
19805b261ecSmrg      /* Set screen privates masks */
19905b261ecSmrg      pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED;
20005b261ecSmrg      pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN;
20105b261ecSmrg      pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE;
20205b261ecSmrg
20305b261ecSmrg      return TRUE;
20405b261ecSmrg    }
20505b261ecSmrg
20605b261ecSmrg  /* Allocate a bitmap header and color table */
20705b261ecSmrg  pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
20805b261ecSmrg				      + 256  * sizeof (RGBQUAD));
20905b261ecSmrg  if (pbmih == NULL)
21005b261ecSmrg    {
21105b261ecSmrg      ErrorF ("winQueryRGBBitsAndMasks - malloc failed\n");
21205b261ecSmrg      return FALSE;
21305b261ecSmrg    }
21405b261ecSmrg
21505b261ecSmrg  /* Get screen description */
21605b261ecSmrg  if (winQueryScreenDIBFormat (pScreen, pbmih))
21705b261ecSmrg    {
21805b261ecSmrg      /* Get a pointer to bitfields */
21905b261ecSmrg      pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER));
22005b261ecSmrg
22105b261ecSmrg#if CYGDEBUG
22205b261ecSmrg      winDebug ("%s - Masks: %08x %08x %08x\n", __FUNCTION__,
22305b261ecSmrg	      pdw[0], pdw[1], pdw[2]);
22405b261ecSmrg      winDebug ("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__,
22505b261ecSmrg              pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount, pbmih->biPlanes);
22605b261ecSmrg      winDebug ("%s - Compression: %d %s\n", __FUNCTION__,
22705b261ecSmrg              pbmih->biCompression,
22805b261ecSmrg              (pbmih->biCompression == BI_RGB?"(BI_RGB)":
22905b261ecSmrg               (pbmih->biCompression == BI_RLE8?"(BI_RLE8)":
23005b261ecSmrg                (pbmih->biCompression == BI_RLE4?"(BI_RLE4)":
23105b261ecSmrg                 (pbmih->biCompression == BI_BITFIELDS?"(BI_BITFIELDS)":""
23205b261ecSmrg                 )))));
23305b261ecSmrg#endif
23405b261ecSmrg
23505b261ecSmrg      /* Handle BI_RGB case, which is returned by Wine */
23605b261ecSmrg      if (pbmih->biCompression == BI_RGB)
23705b261ecSmrg        {
23805b261ecSmrg	  dwRedBits = 5;
23905b261ecSmrg	  dwGreenBits = 5;
24005b261ecSmrg	  dwBlueBits = 5;
24105b261ecSmrg
24205b261ecSmrg	  pScreenPriv->dwBitsPerRGB = 5;
24305b261ecSmrg
24405b261ecSmrg	  /* Set screen privates masks */
24505b261ecSmrg	  pScreenPriv->dwRedMask = 0x7c00;
24605b261ecSmrg	  pScreenPriv->dwGreenMask = 0x03e0;
24705b261ecSmrg	  pScreenPriv->dwBlueMask = 0x001f;
24805b261ecSmrg        }
24905b261ecSmrg      else
25005b261ecSmrg        {
25105b261ecSmrg          /* Count the number of bits in each mask */
25205b261ecSmrg          dwRedBits = winCountBits (pdw[0]);
25305b261ecSmrg          dwGreenBits = winCountBits (pdw[1]);
25405b261ecSmrg          dwBlueBits = winCountBits (pdw[2]);
25505b261ecSmrg
25605b261ecSmrg	  /* Find maximum bits per red, green, blue */
25705b261ecSmrg	  if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
25805b261ecSmrg	    pScreenPriv->dwBitsPerRGB = dwRedBits;
25905b261ecSmrg	  else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
26005b261ecSmrg	    pScreenPriv->dwBitsPerRGB = dwGreenBits;
26105b261ecSmrg	  else
26205b261ecSmrg	    pScreenPriv->dwBitsPerRGB = dwBlueBits;
26305b261ecSmrg
26405b261ecSmrg	  /* Set screen privates masks */
26505b261ecSmrg	  pScreenPriv->dwRedMask = pdw[0];
26605b261ecSmrg	  pScreenPriv->dwGreenMask = pdw[1];
26705b261ecSmrg	  pScreenPriv->dwBlueMask = pdw[2];
26805b261ecSmrg	}
26905b261ecSmrg    }
27005b261ecSmrg  else
27105b261ecSmrg    {
27205b261ecSmrg      ErrorF ("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n");
27305b261ecSmrg      free (pbmih);
27405b261ecSmrg      fReturn = FALSE;
27505b261ecSmrg    }
27605b261ecSmrg
27705b261ecSmrg  /* Free memory */
27805b261ecSmrg  free (pbmih);
27905b261ecSmrg
28005b261ecSmrg  return fReturn;
28105b261ecSmrg}
28205b261ecSmrg
28305b261ecSmrg
28405b261ecSmrg#ifdef XWIN_MULTIWINDOW
28505b261ecSmrg/*
28605b261ecSmrg * Redraw all ---?
28705b261ecSmrg */
28805b261ecSmrg
28905b261ecSmrgstatic wBOOL CALLBACK
29005b261ecSmrgwinRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam)
29105b261ecSmrg{
29205b261ecSmrg  if (hwnd == (HWND)lParam)
29305b261ecSmrg    return TRUE;
29405b261ecSmrg  InvalidateRect (hwnd, NULL, FALSE);
29505b261ecSmrg  UpdateWindow (hwnd);
29605b261ecSmrg  return TRUE;
29705b261ecSmrg}
29805b261ecSmrg
29905b261ecSmrgstatic wBOOL CALLBACK
30005b261ecSmrgwinRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam)
30105b261ecSmrg{
30205b261ecSmrg  BoxPtr pDamage = (BoxPtr)lParam;
30305b261ecSmrg  RECT rcClient, rcDamage, rcRedraw;
30405b261ecSmrg  POINT topLeft, bottomRight;
30505b261ecSmrg
30605b261ecSmrg  if (IsIconic (hwnd))
30705b261ecSmrg    return TRUE; /* Don't care minimized windows */
30805b261ecSmrg
30905b261ecSmrg  /* Convert the damaged area from Screen coords to Client coords */
31005b261ecSmrg  topLeft.x = pDamage->x1; topLeft.y = pDamage->y1;
31105b261ecSmrg  bottomRight.x = pDamage->x2; bottomRight.y = pDamage->y2;
31205b261ecSmrg  topLeft.x += GetSystemMetrics (SM_XVIRTUALSCREEN);
31305b261ecSmrg  bottomRight.x += GetSystemMetrics (SM_XVIRTUALSCREEN);
31405b261ecSmrg  topLeft.y += GetSystemMetrics (SM_YVIRTUALSCREEN);
31505b261ecSmrg  bottomRight.y += GetSystemMetrics (SM_YVIRTUALSCREEN);
31605b261ecSmrg  ScreenToClient (hwnd, &topLeft);
31705b261ecSmrg  ScreenToClient (hwnd, &bottomRight);
31805b261ecSmrg  SetRect (&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
31905b261ecSmrg
32005b261ecSmrg  GetClientRect (hwnd, &rcClient);
32105b261ecSmrg
32205b261ecSmrg  if (IntersectRect (&rcRedraw, &rcClient, &rcDamage))
32305b261ecSmrg    {
32405b261ecSmrg      InvalidateRect (hwnd, &rcRedraw, FALSE);
32505b261ecSmrg      UpdateWindow (hwnd);
32605b261ecSmrg    }
32705b261ecSmrg  return TRUE;
32805b261ecSmrg}
32905b261ecSmrg#endif
33005b261ecSmrg
33105b261ecSmrg
33205b261ecSmrg/*
33305b261ecSmrg * Allocate a DIB for the shadow framebuffer GDI server
33405b261ecSmrg */
33505b261ecSmrg
33605b261ecSmrgstatic Bool
33705b261ecSmrgwinAllocateFBShadowGDI (ScreenPtr pScreen)
33805b261ecSmrg{
33905b261ecSmrg  winScreenPriv(pScreen);
34005b261ecSmrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
34105b261ecSmrg  DIBSECTION		dibsection;
34205b261ecSmrg  Bool			fReturn = TRUE;
34305b261ecSmrg
34405b261ecSmrg  /* Describe shadow bitmap to be created */
3459ace9065Smrg  pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth;
3469ace9065Smrg  pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight;
3479ace9065Smrg
34805b261ecSmrg  ErrorF ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d "
34905b261ecSmrg	  "depth: %d\n",
3509ace9065Smrg	  (int) pScreenPriv->pbmih->biWidth, (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount);
35105b261ecSmrg
35205b261ecSmrg  /* Create a DI shadow bitmap with a bit pointer */
35305b261ecSmrg  pScreenPriv->hbmpShadow = CreateDIBSection (pScreenPriv->hdcScreen,
3549ace9065Smrg					      (BITMAPINFO *) pScreenPriv->pbmih,
35505b261ecSmrg					      DIB_RGB_COLORS,
35605b261ecSmrg					      (VOID**) &pScreenInfo->pfb,
35705b261ecSmrg					      NULL,
35805b261ecSmrg					      0);
35905b261ecSmrg  if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL)
36005b261ecSmrg    {
36105b261ecSmrg      winW32Error (2, "winAllocateFBShadowGDI - CreateDIBSection failed:");
36205b261ecSmrg      return FALSE;
36305b261ecSmrg    }
36405b261ecSmrg  else
36505b261ecSmrg    {
36605b261ecSmrg#if CYGDEBUG
36705b261ecSmrg      winDebug ("winAllocateFBShadowGDI - Shadow buffer allocated\n");
36805b261ecSmrg#endif
36905b261ecSmrg    }
37005b261ecSmrg
37105b261ecSmrg  /* Get information about the bitmap that was allocated */
37205b261ecSmrg  GetObject (pScreenPriv->hbmpShadow,
37305b261ecSmrg	     sizeof (dibsection),
37405b261ecSmrg	     &dibsection);
37505b261ecSmrg
37605b261ecSmrg#if CYGDEBUG || YES
37705b261ecSmrg  /* Print information about bitmap allocated */
37805b261ecSmrg  winDebug ("winAllocateFBShadowGDI - Dibsection width: %d height: %d "
37905b261ecSmrg	  "depth: %d size image: %d\n",
38005b261ecSmrg	  (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight,
38105b261ecSmrg	  dibsection.dsBmih.biBitCount,
38205b261ecSmrg	  (int) dibsection.dsBmih.biSizeImage);
38305b261ecSmrg#endif
38405b261ecSmrg
38505b261ecSmrg  /* Select the shadow bitmap into the shadow DC */
38605b261ecSmrg  SelectObject (pScreenPriv->hdcShadow,
38705b261ecSmrg		pScreenPriv->hbmpShadow);
38805b261ecSmrg
38905b261ecSmrg#if CYGDEBUG
39005b261ecSmrg  winDebug ("winAllocateFBShadowGDI - Attempting a shadow blit\n");
39105b261ecSmrg#endif
39205b261ecSmrg
39305b261ecSmrg  /* Do a test blit from the shadow to the screen, I think */
39405b261ecSmrg  fReturn = BitBlt (pScreenPriv->hdcScreen,
39505b261ecSmrg		    0, 0,
39605b261ecSmrg		    pScreenInfo->dwWidth, pScreenInfo->dwHeight,
39705b261ecSmrg		    pScreenPriv->hdcShadow,
39805b261ecSmrg		    0, 0,
39905b261ecSmrg		    SRCCOPY);
40005b261ecSmrg  if (fReturn)
40105b261ecSmrg    {
40205b261ecSmrg#if CYGDEBUG
40305b261ecSmrg      winDebug ("winAllocateFBShadowGDI - Shadow blit success\n");
40405b261ecSmrg#endif
40505b261ecSmrg    }
40605b261ecSmrg  else
40705b261ecSmrg    {
40805b261ecSmrg      winW32Error (2, "winAllocateFBShadowGDI - Shadow blit failure\n");
40905b261ecSmrg#if 0
41005b261ecSmrg      return FALSE;
41105b261ecSmrg#else
41205b261ecSmrg      /* ago: ignore this error. The blit fails with wine, but does not
41305b261ecSmrg       * cause any problems later. */
41405b261ecSmrg
41505b261ecSmrg      fReturn = TRUE;
41605b261ecSmrg#endif
41705b261ecSmrg    }
41805b261ecSmrg
41905b261ecSmrg  /* Look for height weirdness */
42005b261ecSmrg  if (dibsection.dsBmih.biHeight < 0)
42105b261ecSmrg    {
42205b261ecSmrg      dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight;
42305b261ecSmrg    }
42405b261ecSmrg
42505b261ecSmrg  /* Set screeninfo stride */
42605b261ecSmrg  pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage
42705b261ecSmrg			    / dibsection.dsBmih.biHeight)
42805b261ecSmrg			   * 8) / pScreenInfo->dwBPP;
42905b261ecSmrg
43005b261ecSmrg#if CYGDEBUG || YES
43105b261ecSmrg  winDebug ("winAllocateFBShadowGDI - Created shadow stride: %d\n",
43205b261ecSmrg	  (int) pScreenInfo->dwStride);
43305b261ecSmrg#endif
43405b261ecSmrg
43505b261ecSmrg#ifdef XWIN_MULTIWINDOW
43605b261ecSmrg  /* Redraw all windows */
43705b261ecSmrg  if (pScreenInfo->fMultiWindow)
43805b261ecSmrg    EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
43905b261ecSmrg#endif
44005b261ecSmrg
44105b261ecSmrg  return fReturn;
44205b261ecSmrg}
44305b261ecSmrg
4449ace9065Smrgstatic void
4459ace9065SmrgwinFreeFBShadowGDI (ScreenPtr pScreen)
4469ace9065Smrg{
4479ace9065Smrg  winScreenPriv(pScreen);
4489ace9065Smrg  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
4499ace9065Smrg
4509ace9065Smrg  /* Free the shadow bitmap */
4519ace9065Smrg  DeleteObject (pScreenPriv->hbmpShadow);
4529ace9065Smrg
4539ace9065Smrg  /* Invalidate the ScreenInfo's fb pointer */
4549ace9065Smrg  pScreenInfo->pfb = NULL;
4559ace9065Smrg}
45605b261ecSmrg
45705b261ecSmrg/*
45805b261ecSmrg * Blit the damaged regions of the shadow fb to the screen
45905b261ecSmrg */
46005b261ecSmrg
46105b261ecSmrgstatic void
46205b261ecSmrgwinShadowUpdateGDI (ScreenPtr pScreen,
46305b261ecSmrg		    shadowBufPtr pBuf)
46405b261ecSmrg{
46505b261ecSmrg  winScreenPriv(pScreen);
46605b261ecSmrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
4676747b715Smrg  RegionPtr		damage = shadowDamage(pBuf);
4686747b715Smrg  DWORD			dwBox = RegionNumRects (damage);
4696747b715Smrg  BoxPtr		pBox = RegionRects (damage);
47005b261ecSmrg  int			x, y, w, h;
47105b261ecSmrg  HRGN			hrgnTemp = NULL, hrgnCombined = NULL;
47205b261ecSmrg#ifdef XWIN_UPDATESTATS
47305b261ecSmrg  static DWORD		s_dwNonUnitRegions = 0;
47405b261ecSmrg  static DWORD		s_dwTotalUpdates = 0;
47505b261ecSmrg  static DWORD		s_dwTotalBoxes = 0;
47605b261ecSmrg#endif
4776747b715Smrg  BoxPtr		pBoxExtents = RegionExtents(damage);
47805b261ecSmrg
47905b261ecSmrg  /*
48005b261ecSmrg   * Return immediately if the app is not active
48105b261ecSmrg   * and we are fullscreen, or if we have a bad display depth
48205b261ecSmrg   */
48305b261ecSmrg  if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
48405b261ecSmrg      || pScreenPriv->fBadDepth) return;
48505b261ecSmrg
48605b261ecSmrg#ifdef XWIN_UPDATESTATS
48705b261ecSmrg  ++s_dwTotalUpdates;
48805b261ecSmrg  s_dwTotalBoxes += dwBox;
48905b261ecSmrg
49005b261ecSmrg  if (dwBox != 1)
49105b261ecSmrg    {
49205b261ecSmrg      ++s_dwNonUnitRegions;
49305b261ecSmrg      ErrorF ("winShadowUpdatGDI - dwBox: %d\n", dwBox);
49405b261ecSmrg    }
49505b261ecSmrg
49605b261ecSmrg  if ((s_dwTotalUpdates % 100) == 0)
49705b261ecSmrg    ErrorF ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d "
49805b261ecSmrg	    "nu: %d tu: %d\n",
49905b261ecSmrg	    (s_dwNonUnitRegions * 100) / s_dwTotalUpdates,
50005b261ecSmrg	    s_dwTotalBoxes / s_dwTotalUpdates,
50105b261ecSmrg	    s_dwNonUnitRegions, s_dwTotalUpdates);
50205b261ecSmrg#endif /* XWIN_UPDATESTATS */
50305b261ecSmrg
50405b261ecSmrg  /*
50505b261ecSmrg   * Handle small regions with multiple blits,
50605b261ecSmrg   * handle large regions by creating a clipping region and
50705b261ecSmrg   * doing a single blit constrained to that clipping region.
50805b261ecSmrg   */
50905b261ecSmrg  if (!pScreenInfo->fMultiWindow &&
51005b261ecSmrg      (pScreenInfo->dwClipUpdatesNBoxes == 0 ||
51105b261ecSmrg      dwBox < pScreenInfo->dwClipUpdatesNBoxes))
51205b261ecSmrg    {
51305b261ecSmrg      /* Loop through all boxes in the damaged region */
51405b261ecSmrg      while (dwBox--)
51505b261ecSmrg	{
51605b261ecSmrg	  /*
51705b261ecSmrg	   * Calculate x offset, y offset, width, and height for
51805b261ecSmrg	   * current damage box
51905b261ecSmrg	   */
52005b261ecSmrg	  x = pBox->x1;
52105b261ecSmrg	  y = pBox->y1;
52205b261ecSmrg	  w = pBox->x2 - pBox->x1;
52305b261ecSmrg	  h = pBox->y2 - pBox->y1;
52405b261ecSmrg
52505b261ecSmrg	  BitBlt (pScreenPriv->hdcScreen,
52605b261ecSmrg		  x, y,
52705b261ecSmrg		  w, h,
52805b261ecSmrg		  pScreenPriv->hdcShadow,
52905b261ecSmrg		  x, y,
53005b261ecSmrg		  SRCCOPY);
53105b261ecSmrg
53205b261ecSmrg	  /* Get a pointer to the next box */
53305b261ecSmrg	  ++pBox;
53405b261ecSmrg	}
53505b261ecSmrg    }
53605b261ecSmrg  else if (!pScreenInfo->fMultiWindow)
53705b261ecSmrg    {
53805b261ecSmrg      /* Compute a GDI region from the damaged region */
53905b261ecSmrg      hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
54005b261ecSmrg      dwBox--;
54105b261ecSmrg      pBox++;
54205b261ecSmrg      while (dwBox--)
54305b261ecSmrg	{
54405b261ecSmrg	  hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
54505b261ecSmrg	  CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
54605b261ecSmrg	  DeleteObject (hrgnTemp);
54705b261ecSmrg	  pBox++;
54805b261ecSmrg	}
54905b261ecSmrg
55005b261ecSmrg      /* Install the GDI region as a clipping region */
55105b261ecSmrg      SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined);
55205b261ecSmrg      DeleteObject (hrgnCombined);
55305b261ecSmrg      hrgnCombined = NULL;
55405b261ecSmrg
55505b261ecSmrg      /*
55605b261ecSmrg       * Blit the shadow buffer to the screen,
55705b261ecSmrg       * constrained to the clipping region.
55805b261ecSmrg       */
55905b261ecSmrg      BitBlt (pScreenPriv->hdcScreen,
56005b261ecSmrg	      pBoxExtents->x1, pBoxExtents->y1,
56105b261ecSmrg	      pBoxExtents->x2 - pBoxExtents->x1,
56205b261ecSmrg	      pBoxExtents->y2 - pBoxExtents->y1,
56305b261ecSmrg	      pScreenPriv->hdcShadow,
56405b261ecSmrg	      pBoxExtents->x1, pBoxExtents->y1,
56505b261ecSmrg	      SRCCOPY);
56605b261ecSmrg
56705b261ecSmrg      /* Reset the clip region */
56805b261ecSmrg      SelectClipRgn (pScreenPriv->hdcScreen, NULL);
56905b261ecSmrg    }
57005b261ecSmrg
57105b261ecSmrg#ifdef XWIN_MULTIWINDOW
57205b261ecSmrg  /* Redraw all multiwindow windows */
57305b261ecSmrg  if (pScreenInfo->fMultiWindow)
57405b261ecSmrg    EnumThreadWindows (g_dwCurrentThreadID,
57505b261ecSmrg		       winRedrawDamagedWindowShadowGDI,
57605b261ecSmrg		       (LPARAM)pBoxExtents);
57705b261ecSmrg#endif
57805b261ecSmrg}
57905b261ecSmrg
58005b261ecSmrg
5819ace9065Smrgstatic Bool
5829ace9065SmrgwinInitScreenShadowGDI (ScreenPtr pScreen)
5839ace9065Smrg{
5849ace9065Smrg  winScreenPriv(pScreen);
5859ace9065Smrg
5869ace9065Smrg  /* Get device contexts for the screen and shadow bitmap */
5879ace9065Smrg  pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
5889ace9065Smrg  pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen);
5899ace9065Smrg
5909ace9065Smrg  /* Allocate bitmap info header */
5919ace9065Smrg  pScreenPriv->pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
5929ace9065Smrg                                                   + 256 * sizeof (RGBQUAD));
5939ace9065Smrg  if (pScreenPriv->pbmih == NULL)
5949ace9065Smrg    {
5959ace9065Smrg      ErrorF ("winInitScreenShadowGDI - malloc () failed\n");
5969ace9065Smrg      return FALSE;
5979ace9065Smrg    }
5989ace9065Smrg
5999ace9065Smrg  /* Query the screen format */
6009ace9065Smrg  if (!winQueryScreenDIBFormat (pScreen, pScreenPriv->pbmih))
6019ace9065Smrg    {
6029ace9065Smrg      ErrorF ("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n");
6039ace9065Smrg      return FALSE;
6049ace9065Smrg    }
6059ace9065Smrg
6069ace9065Smrg  /* Determine our color masks */
6079ace9065Smrg  if (!winQueryRGBBitsAndMasks (pScreen))
6089ace9065Smrg    {
6099ace9065Smrg      ErrorF ("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n");
6109ace9065Smrg      return FALSE;
6119ace9065Smrg    }
6129ace9065Smrg
6139ace9065Smrg  return winAllocateFBShadowGDI(pScreen);
6149ace9065Smrg}
6159ace9065Smrg
61605b261ecSmrg/* See Porting Layer Definition - p. 33 */
61705b261ecSmrg/*
61805b261ecSmrg * We wrap whatever CloseScreen procedure was specified by fb;
61905b261ecSmrg * a pointer to said procedure is stored in our privates.
62005b261ecSmrg */
62105b261ecSmrg
62205b261ecSmrgstatic Bool
62305b261ecSmrgwinCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen)
62405b261ecSmrg{
62505b261ecSmrg  winScreenPriv(pScreen);
62605b261ecSmrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
62705b261ecSmrg  Bool			fReturn;
62805b261ecSmrg
62905b261ecSmrg#if CYGDEBUG
63005b261ecSmrg  winDebug ("winCloseScreenShadowGDI - Freeing screen resources\n");
63105b261ecSmrg#endif
63205b261ecSmrg
63305b261ecSmrg  /* Flag that the screen is closed */
63405b261ecSmrg  pScreenPriv->fClosed = TRUE;
63505b261ecSmrg  pScreenPriv->fActive = FALSE;
63605b261ecSmrg
63705b261ecSmrg  /* Call the wrapped CloseScreen procedure */
63805b261ecSmrg  WIN_UNWRAP(CloseScreen);
63905b261ecSmrg  fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);
64005b261ecSmrg
64105b261ecSmrg  /* Delete the window property */
64205b261ecSmrg  RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
64305b261ecSmrg
64405b261ecSmrg  /* Free the shadow DC; which allows the bitmap to be freed */
64505b261ecSmrg  DeleteDC (pScreenPriv->hdcShadow);
6469ace9065Smrg
6479ace9065Smrg  winFreeFBShadowGDI(pScreen);
64805b261ecSmrg
64905b261ecSmrg  /* Free the screen DC */
65005b261ecSmrg  ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
65105b261ecSmrg
65205b261ecSmrg  /* Delete tray icon, if we have one */
65305b261ecSmrg  if (!pScreenInfo->fNoTrayIcon)
65405b261ecSmrg    winDeleteNotifyIcon (pScreenPriv);
65505b261ecSmrg
65605b261ecSmrg  /* Free the exit confirmation dialog box, if it exists */
65705b261ecSmrg  if (g_hDlgExit != NULL)
65805b261ecSmrg    {
65905b261ecSmrg      DestroyWindow (g_hDlgExit);
66005b261ecSmrg      g_hDlgExit = NULL;
66105b261ecSmrg    }
66205b261ecSmrg
66305b261ecSmrg  /* Kill our window */
66405b261ecSmrg  if (pScreenPriv->hwndScreen)
66505b261ecSmrg    {
66605b261ecSmrg      DestroyWindow (pScreenPriv->hwndScreen);
66705b261ecSmrg      pScreenPriv->hwndScreen = NULL;
66805b261ecSmrg    }
66905b261ecSmrg
67005b261ecSmrg#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
67105b261ecSmrg  /* Destroy the thread startup mutex */
67205b261ecSmrg  pthread_mutex_destroy (&pScreenPriv->pmServerStarted);
67305b261ecSmrg#endif
67405b261ecSmrg
67505b261ecSmrg  /* Invalidate our screeninfo's pointer to the screen */
67605b261ecSmrg  pScreenInfo->pScreen = NULL;
67705b261ecSmrg
67805b261ecSmrg  /* Free the screen privates for this screen */
67905b261ecSmrg  free ((pointer) pScreenPriv);
68005b261ecSmrg
68105b261ecSmrg  return fReturn;
68205b261ecSmrg}
68305b261ecSmrg
68405b261ecSmrg
68505b261ecSmrg/*
68605b261ecSmrg * Tell mi what sort of visuals we need.
68705b261ecSmrg *
68805b261ecSmrg * Generally we only need one visual, as our screen can only
68905b261ecSmrg * handle one format at a time, I believe.  You may want
69005b261ecSmrg * to verify that last sentence.
69105b261ecSmrg */
69205b261ecSmrg
69305b261ecSmrgstatic Bool
69405b261ecSmrgwinInitVisualsShadowGDI (ScreenPtr pScreen)
69505b261ecSmrg{
69605b261ecSmrg  winScreenPriv(pScreen);
69705b261ecSmrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
69805b261ecSmrg
69905b261ecSmrg  /* Display debugging information */
70005b261ecSmrg  ErrorF ("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d "
70105b261ecSmrg	  "bpp %d\n",
70205b261ecSmrg	  (unsigned int) pScreenPriv->dwRedMask,
70305b261ecSmrg	  (unsigned int) pScreenPriv->dwGreenMask,
70405b261ecSmrg	  (unsigned int) pScreenPriv->dwBlueMask,
70505b261ecSmrg	  (int) pScreenPriv->dwBitsPerRGB,
70605b261ecSmrg	  (int) pScreenInfo->dwDepth,
70705b261ecSmrg	  (int) pScreenInfo->dwBPP);
70805b261ecSmrg
70905b261ecSmrg  /* Create a single visual according to the Windows screen depth */
71005b261ecSmrg  switch (pScreenInfo->dwDepth)
71105b261ecSmrg    {
71205b261ecSmrg    case 24:
71305b261ecSmrg    case 16:
71405b261ecSmrg    case 15:
71505b261ecSmrg      /* Setup the real visual */
71605b261ecSmrg      if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
71705b261ecSmrg				     TrueColorMask,
71805b261ecSmrg				     pScreenPriv->dwBitsPerRGB,
71905b261ecSmrg				     -1,
72005b261ecSmrg				     pScreenPriv->dwRedMask,
72105b261ecSmrg				     pScreenPriv->dwGreenMask,
72205b261ecSmrg				     pScreenPriv->dwBlueMask))
72305b261ecSmrg	{
72405b261ecSmrg	  ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
72505b261ecSmrg		  "failed\n");
72605b261ecSmrg	  return FALSE;
72705b261ecSmrg	}
72805b261ecSmrg
72905b261ecSmrg#ifdef XWIN_EMULATEPSEUDO
73005b261ecSmrg      if (!pScreenInfo->fEmulatePseudo)
73105b261ecSmrg	break;
73205b261ecSmrg
73305b261ecSmrg      /* Setup a pseudocolor visual */
73405b261ecSmrg      if (!miSetVisualTypesAndMasks (8,
73505b261ecSmrg				     PseudoColorMask,
73605b261ecSmrg				     8,
73705b261ecSmrg				     -1,
73805b261ecSmrg				     0,
73905b261ecSmrg				     0,
74005b261ecSmrg				     0))
74105b261ecSmrg	{
74205b261ecSmrg	  ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
74305b261ecSmrg		  "failed for PseudoColor\n");
74405b261ecSmrg	  return FALSE;
74505b261ecSmrg	}
74605b261ecSmrg#endif
74705b261ecSmrg      break;
74805b261ecSmrg
74905b261ecSmrg    case 8:
75005b261ecSmrg      if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
75105b261ecSmrg				     PseudoColorMask,
75205b261ecSmrg				     pScreenPriv->dwBitsPerRGB,
75305b261ecSmrg				     PseudoColor,
75405b261ecSmrg				     pScreenPriv->dwRedMask,
75505b261ecSmrg				     pScreenPriv->dwGreenMask,
75605b261ecSmrg				     pScreenPriv->dwBlueMask))
75705b261ecSmrg	{
75805b261ecSmrg	  ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
75905b261ecSmrg		  "failed\n");
76005b261ecSmrg	  return FALSE;
76105b261ecSmrg	}
76205b261ecSmrg      break;
76305b261ecSmrg
76405b261ecSmrg    default:
76505b261ecSmrg      ErrorF ("winInitVisualsShadowGDI - Unknown screen depth\n");
76605b261ecSmrg      return FALSE;
76705b261ecSmrg    }
76805b261ecSmrg
76905b261ecSmrg#if CYGDEBUG
77005b261ecSmrg  winDebug ("winInitVisualsShadowGDI - Returning\n");
77105b261ecSmrg#endif
77205b261ecSmrg
77305b261ecSmrg  return TRUE;
77405b261ecSmrg}
77505b261ecSmrg
77605b261ecSmrg
77705b261ecSmrg/*
77805b261ecSmrg * Adjust the proposed video mode
77905b261ecSmrg */
78005b261ecSmrg
78105b261ecSmrgstatic Bool
78205b261ecSmrgwinAdjustVideoModeShadowGDI (ScreenPtr pScreen)
78305b261ecSmrg{
78405b261ecSmrg  winScreenPriv(pScreen);
78505b261ecSmrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
78605b261ecSmrg  HDC			hdc;
78705b261ecSmrg  DWORD			dwBPP;
78805b261ecSmrg
78905b261ecSmrg  hdc = GetDC (NULL);
79005b261ecSmrg
79105b261ecSmrg  /* We're in serious trouble if we can't get a DC */
79205b261ecSmrg  if (hdc == NULL)
79305b261ecSmrg    {
79405b261ecSmrg      ErrorF ("winAdjustVideoModeShadowGDI - GetDC () failed\n");
79505b261ecSmrg      return FALSE;
79605b261ecSmrg    }
79705b261ecSmrg
79805b261ecSmrg  /* Query GDI for current display depth */
79905b261ecSmrg  dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
80005b261ecSmrg
8019ace9065Smrg  /* GDI cannot change the screen depth, so always use GDI's depth */
8029ace9065Smrg  pScreenInfo->dwBPP = dwBPP;
80305b261ecSmrg
80405b261ecSmrg  /* Release our DC */
80505b261ecSmrg  ReleaseDC (NULL, hdc);
80605b261ecSmrg  hdc = NULL;
80705b261ecSmrg
80805b261ecSmrg  return TRUE;
80905b261ecSmrg}
81005b261ecSmrg
81105b261ecSmrg
81205b261ecSmrg/*
81305b261ecSmrg * Blt exposed regions to the screen
81405b261ecSmrg */
81505b261ecSmrg
81605b261ecSmrgstatic Bool
81705b261ecSmrgwinBltExposedRegionsShadowGDI (ScreenPtr pScreen)
81805b261ecSmrg{
81905b261ecSmrg  winScreenPriv(pScreen);
82005b261ecSmrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
82105b261ecSmrg  winPrivCmapPtr	pCmapPriv = NULL;
82205b261ecSmrg  HDC			hdcUpdate;
82305b261ecSmrg  PAINTSTRUCT		ps;
82405b261ecSmrg
82505b261ecSmrg  /* BeginPaint gives us an hdc that clips to the invalidated region */
82605b261ecSmrg  hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps);
82705b261ecSmrg
82805b261ecSmrg  /* Realize the palette, if we have one */
82905b261ecSmrg  if (pScreenPriv->pcmapInstalled != NULL)
83005b261ecSmrg    {
83105b261ecSmrg      pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled);
83205b261ecSmrg
83305b261ecSmrg      SelectPalette (hdcUpdate, pCmapPriv->hPalette, FALSE);
83405b261ecSmrg      RealizePalette (hdcUpdate);
83505b261ecSmrg    }
83605b261ecSmrg
83705b261ecSmrg  /* Our BitBlt will be clipped to the invalidated region */
83805b261ecSmrg  BitBlt (hdcUpdate,
83905b261ecSmrg	  0, 0,
84005b261ecSmrg	  pScreenInfo->dwWidth, pScreenInfo->dwHeight,
84105b261ecSmrg	  pScreenPriv->hdcShadow,
84205b261ecSmrg	  0, 0,
84305b261ecSmrg	  SRCCOPY);
84405b261ecSmrg
84505b261ecSmrg  /* EndPaint frees the DC */
84605b261ecSmrg  EndPaint (pScreenPriv->hwndScreen, &ps);
84705b261ecSmrg
84805b261ecSmrg#ifdef XWIN_MULTIWINDOW
84905b261ecSmrg  /* Redraw all windows */
85005b261ecSmrg  if (pScreenInfo->fMultiWindow)
85105b261ecSmrg    EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI,
85205b261ecSmrg            (LPARAM)pScreenPriv->hwndScreen);
85305b261ecSmrg#endif
85405b261ecSmrg
85505b261ecSmrg  return TRUE;
85605b261ecSmrg}
85705b261ecSmrg
85805b261ecSmrg
85905b261ecSmrg/*
86005b261ecSmrg * Do any engine-specific appliation-activation processing
86105b261ecSmrg */
86205b261ecSmrg
86305b261ecSmrgstatic Bool
86405b261ecSmrgwinActivateAppShadowGDI (ScreenPtr pScreen)
86505b261ecSmrg{
86605b261ecSmrg  winScreenPriv(pScreen);
86705b261ecSmrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
86805b261ecSmrg
86905b261ecSmrg  /*
87005b261ecSmrg   * 2004/04/12 - Harold - We perform the restoring or minimizing
87105b261ecSmrg   * manually for ShadowGDI in fullscreen modes so that this engine
87205b261ecSmrg   * will perform just like ShadowDD and ShadowDDNL in fullscreen mode;
87305b261ecSmrg   * if we do not do this then our fullscreen window will appear in the
87405b261ecSmrg   * z-order when it is deactivated and it can be uncovered by resizing
87505b261ecSmrg   * or minimizing another window that is on top of it, which is not how
87605b261ecSmrg   * the DirectDraw engines work.  Therefore we keep this code here to
87705b261ecSmrg   * make sure that all engines work the same in fullscreen mode.
87805b261ecSmrg   */
87905b261ecSmrg
88005b261ecSmrg  /*
88105b261ecSmrg   * Are we active?
88205b261ecSmrg   * Are we fullscreen?
88305b261ecSmrg   */
88405b261ecSmrg  if (pScreenPriv->fActive
88505b261ecSmrg      && pScreenInfo->fFullScreen)
88605b261ecSmrg    {
88705b261ecSmrg      /*
88805b261ecSmrg       * Activating, attempt to bring our window
88905b261ecSmrg       * to the top of the display
89005b261ecSmrg       */
89105b261ecSmrg      ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE);
89205b261ecSmrg    }
89305b261ecSmrg  else if (!pScreenPriv->fActive
89405b261ecSmrg	   && pScreenInfo->fFullScreen)
89505b261ecSmrg    {
89605b261ecSmrg      /*
89705b261ecSmrg       * Deactivating, stuff our window onto the
89805b261ecSmrg       * task bar.
89905b261ecSmrg       */
90005b261ecSmrg      ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE);
90105b261ecSmrg    }
90205b261ecSmrg
90305b261ecSmrg  return TRUE;
90405b261ecSmrg}
90505b261ecSmrg
90605b261ecSmrg
90705b261ecSmrg/*
90805b261ecSmrg * Reblit the shadow framebuffer to the screen.
90905b261ecSmrg */
91005b261ecSmrg
91105b261ecSmrgstatic Bool
91205b261ecSmrgwinRedrawScreenShadowGDI (ScreenPtr pScreen)
91305b261ecSmrg{
91405b261ecSmrg  winScreenPriv(pScreen);
91505b261ecSmrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
91605b261ecSmrg
91705b261ecSmrg  /* Redraw the whole window, to take account for the new colors */
91805b261ecSmrg  BitBlt (pScreenPriv->hdcScreen,
91905b261ecSmrg	  0, 0,
92005b261ecSmrg	  pScreenInfo->dwWidth, pScreenInfo->dwHeight,
92105b261ecSmrg	  pScreenPriv->hdcShadow,
92205b261ecSmrg	  0, 0,
92305b261ecSmrg	  SRCCOPY);
92405b261ecSmrg
92505b261ecSmrg#ifdef XWIN_MULTIWINDOW
92605b261ecSmrg  /* Redraw all windows */
92705b261ecSmrg  if (pScreenInfo->fMultiWindow)
92805b261ecSmrg    EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
92905b261ecSmrg#endif
93005b261ecSmrg
93105b261ecSmrg  return TRUE;
93205b261ecSmrg}
93305b261ecSmrg
93405b261ecSmrg
93505b261ecSmrg
93605b261ecSmrg/*
93705b261ecSmrg * Realize the currently installed colormap
93805b261ecSmrg */
93905b261ecSmrg
94005b261ecSmrgstatic Bool
94105b261ecSmrgwinRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen)
94205b261ecSmrg{
94305b261ecSmrg  winScreenPriv(pScreen);
94405b261ecSmrg  winPrivCmapPtr	pCmapPriv = NULL;
94505b261ecSmrg
94605b261ecSmrg#if CYGDEBUG
94705b261ecSmrg  winDebug ("winRealizeInstalledPaletteShadowGDI\n");
94805b261ecSmrg#endif
94905b261ecSmrg
95005b261ecSmrg  /* Don't do anything if there is not a colormap */
95105b261ecSmrg  if (pScreenPriv->pcmapInstalled == NULL)
95205b261ecSmrg    {
95305b261ecSmrg#if CYGDEBUG
95405b261ecSmrg      winDebug ("winRealizeInstalledPaletteShadowGDI - No colormap "
95505b261ecSmrg	      "installed\n");
95605b261ecSmrg#endif
95705b261ecSmrg      return TRUE;
95805b261ecSmrg    }
95905b261ecSmrg
96005b261ecSmrg  pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled);
96105b261ecSmrg
96205b261ecSmrg  /* Realize our palette for the screen */
96305b261ecSmrg  if (RealizePalette (pScreenPriv->hdcScreen) == GDI_ERROR)
96405b261ecSmrg    {
96505b261ecSmrg      ErrorF ("winRealizeInstalledPaletteShadowGDI - RealizePalette () "
96605b261ecSmrg	      "failed\n");
96705b261ecSmrg      return FALSE;
96805b261ecSmrg    }
96905b261ecSmrg
97005b261ecSmrg  /* Set the DIB color table */
97105b261ecSmrg  if (SetDIBColorTable (pScreenPriv->hdcShadow,
97205b261ecSmrg			0,
97305b261ecSmrg			WIN_NUM_PALETTE_ENTRIES,
97405b261ecSmrg			pCmapPriv->rgbColors) == 0)
97505b261ecSmrg    {
97605b261ecSmrg      ErrorF ("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () "
97705b261ecSmrg	      "failed\n");
97805b261ecSmrg      return FALSE;
97905b261ecSmrg    }
98005b261ecSmrg
98105b261ecSmrg  return TRUE;
98205b261ecSmrg}
98305b261ecSmrg
98405b261ecSmrg
98505b261ecSmrg/*
98605b261ecSmrg * Install the specified colormap
98705b261ecSmrg */
98805b261ecSmrg
98905b261ecSmrgstatic Bool
99005b261ecSmrgwinInstallColormapShadowGDI (ColormapPtr pColormap)
99105b261ecSmrg{
99205b261ecSmrg  ScreenPtr		pScreen = pColormap->pScreen;
99305b261ecSmrg  winScreenPriv(pScreen);
99405b261ecSmrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
99505b261ecSmrg  winCmapPriv(pColormap);
99605b261ecSmrg
99705b261ecSmrg  /*
99805b261ecSmrg   * Tell Windows to install the new colormap
99905b261ecSmrg   */
100005b261ecSmrg  if (SelectPalette (pScreenPriv->hdcScreen,
100105b261ecSmrg		     pCmapPriv->hPalette,
100205b261ecSmrg		     FALSE) == NULL)
100305b261ecSmrg    {
100405b261ecSmrg      ErrorF ("winInstallColormapShadowGDI - SelectPalette () failed\n");
100505b261ecSmrg      return FALSE;
100605b261ecSmrg    }
100705b261ecSmrg
100805b261ecSmrg  /* Realize the palette */
100905b261ecSmrg  if (GDI_ERROR == RealizePalette (pScreenPriv->hdcScreen))
101005b261ecSmrg    {
101105b261ecSmrg      ErrorF ("winInstallColormapShadowGDI - RealizePalette () failed\n");
101205b261ecSmrg      return FALSE;
101305b261ecSmrg    }
101405b261ecSmrg
101505b261ecSmrg  /* Set the DIB color table */
101605b261ecSmrg  if (SetDIBColorTable (pScreenPriv->hdcShadow,
101705b261ecSmrg			0,
101805b261ecSmrg			WIN_NUM_PALETTE_ENTRIES,
101905b261ecSmrg			pCmapPriv->rgbColors) == 0)
102005b261ecSmrg    {
102105b261ecSmrg      ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
102205b261ecSmrg      return FALSE;
102305b261ecSmrg    }
102405b261ecSmrg
102505b261ecSmrg  /* Redraw the whole window, to take account for the new colors */
102605b261ecSmrg  BitBlt (pScreenPriv->hdcScreen,
102705b261ecSmrg	  0, 0,
102805b261ecSmrg	  pScreenInfo->dwWidth, pScreenInfo->dwHeight,
102905b261ecSmrg	  pScreenPriv->hdcShadow,
103005b261ecSmrg	  0, 0,
103105b261ecSmrg	  SRCCOPY);
103205b261ecSmrg
103305b261ecSmrg  /* Save a pointer to the newly installed colormap */
103405b261ecSmrg  pScreenPriv->pcmapInstalled = pColormap;
103505b261ecSmrg
103605b261ecSmrg#ifdef XWIN_MULTIWINDOW
103705b261ecSmrg  /* Redraw all windows */
103805b261ecSmrg  if (pScreenInfo->fMultiWindow)
103905b261ecSmrg    EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
104005b261ecSmrg#endif
104105b261ecSmrg
104205b261ecSmrg  return TRUE;
104305b261ecSmrg}
104405b261ecSmrg
104505b261ecSmrg
104605b261ecSmrg/*
104705b261ecSmrg * Store the specified colors in the specified colormap
104805b261ecSmrg */
104905b261ecSmrg
105005b261ecSmrgstatic Bool
105105b261ecSmrgwinStoreColorsShadowGDI (ColormapPtr pColormap,
105205b261ecSmrg			 int ndef,
105305b261ecSmrg			 xColorItem *pdefs)
105405b261ecSmrg{
105505b261ecSmrg  ScreenPtr		pScreen = pColormap->pScreen;
105605b261ecSmrg  winScreenPriv(pScreen);
105705b261ecSmrg  winCmapPriv(pColormap);
105805b261ecSmrg  ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
105905b261ecSmrg
106005b261ecSmrg  /* Put the X colormap entries into the Windows logical palette */
106105b261ecSmrg  if (SetPaletteEntries (pCmapPriv->hPalette,
106205b261ecSmrg			 pdefs[0].pixel,
106305b261ecSmrg			 ndef,
106405b261ecSmrg			 pCmapPriv->peColors + pdefs[0].pixel) == 0)
106505b261ecSmrg    {
106605b261ecSmrg      ErrorF ("winStoreColorsShadowGDI - SetPaletteEntries () failed\n");
106705b261ecSmrg      return FALSE;
106805b261ecSmrg    }
106905b261ecSmrg
107005b261ecSmrg  /* Don't install the Windows palette if the colormap is not installed */
107105b261ecSmrg  if (pColormap != curpmap)
107205b261ecSmrg    {
107305b261ecSmrg      return TRUE;
107405b261ecSmrg    }
107505b261ecSmrg
107605b261ecSmrg  /* Try to install the newly modified colormap */
107705b261ecSmrg  if (!winInstallColormapShadowGDI (pColormap))
107805b261ecSmrg    {
107905b261ecSmrg      ErrorF ("winInstallColormapShadowGDI - winInstallColormapShadowGDI "
108005b261ecSmrg	      "failed\n");
108105b261ecSmrg      return FALSE;
108205b261ecSmrg    }
108305b261ecSmrg
108405b261ecSmrg#if 0
108505b261ecSmrg  /* Tell Windows that the palette has changed */
108605b261ecSmrg  RealizePalette (pScreenPriv->hdcScreen);
108705b261ecSmrg
108805b261ecSmrg  /* Set the DIB color table */
108905b261ecSmrg  if (SetDIBColorTable (pScreenPriv->hdcShadow,
109005b261ecSmrg			pdefs[0].pixel,
109105b261ecSmrg			ndef,
109205b261ecSmrg			pCmapPriv->rgbColors + pdefs[0].pixel) == 0)
109305b261ecSmrg    {
109405b261ecSmrg      ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
109505b261ecSmrg      return FALSE;
109605b261ecSmrg    }
109705b261ecSmrg
109805b261ecSmrg  /* Save a pointer to the newly installed colormap */
109905b261ecSmrg  pScreenPriv->pcmapInstalled = pColormap;
110005b261ecSmrg#endif
110105b261ecSmrg
110205b261ecSmrg  return TRUE;
110305b261ecSmrg}
110405b261ecSmrg
110505b261ecSmrg
110605b261ecSmrg/*
110705b261ecSmrg * Colormap initialization procedure
110805b261ecSmrg */
110905b261ecSmrg
111005b261ecSmrgstatic Bool
111105b261ecSmrgwinCreateColormapShadowGDI (ColormapPtr pColormap)
111205b261ecSmrg{
111305b261ecSmrg  LPLOGPALETTE		lpPaletteNew = NULL;
111405b261ecSmrg  DWORD			dwEntriesMax;
111505b261ecSmrg  VisualPtr		pVisual;
111605b261ecSmrg  HPALETTE		hpalNew = NULL;
111705b261ecSmrg  winCmapPriv(pColormap);
111805b261ecSmrg
111905b261ecSmrg  /* Get a pointer to the visual that the colormap belongs to */
112005b261ecSmrg  pVisual = pColormap->pVisual;
112105b261ecSmrg
112205b261ecSmrg  /* Get the maximum number of palette entries for this visual */
112305b261ecSmrg  dwEntriesMax = pVisual->ColormapEntries;
112405b261ecSmrg
112505b261ecSmrg  /* Allocate a Windows logical color palette with max entries */
112605b261ecSmrg  lpPaletteNew = malloc (sizeof (LOGPALETTE)
112705b261ecSmrg			 + (dwEntriesMax - 1) * sizeof (PALETTEENTRY));
112805b261ecSmrg  if (lpPaletteNew == NULL)
112905b261ecSmrg    {
113005b261ecSmrg      ErrorF ("winCreateColormapShadowGDI - Couldn't allocate palette "
113105b261ecSmrg	      "with %d entries\n",
113205b261ecSmrg	      (int) dwEntriesMax);
113305b261ecSmrg      return FALSE;
113405b261ecSmrg    }
113505b261ecSmrg
113605b261ecSmrg  /* Zero out the colormap */
113705b261ecSmrg  ZeroMemory (lpPaletteNew, sizeof (LOGPALETTE)
113805b261ecSmrg	      + (dwEntriesMax - 1) * sizeof (PALETTEENTRY));
113905b261ecSmrg
114005b261ecSmrg  /* Set the logical palette structure */
114105b261ecSmrg  lpPaletteNew->palVersion = 0x0300;
114205b261ecSmrg  lpPaletteNew->palNumEntries = dwEntriesMax;
114305b261ecSmrg
114405b261ecSmrg  /* Tell Windows to create the palette */
114505b261ecSmrg  hpalNew = CreatePalette (lpPaletteNew);
114605b261ecSmrg  if (hpalNew == NULL)
114705b261ecSmrg    {
114805b261ecSmrg      ErrorF ("winCreateColormapShadowGDI - CreatePalette () failed\n");
114905b261ecSmrg      free (lpPaletteNew);
115005b261ecSmrg      return FALSE;
115105b261ecSmrg    }
115205b261ecSmrg
115305b261ecSmrg  /* Save the Windows logical palette handle in the X colormaps' privates */
115405b261ecSmrg  pCmapPriv->hPalette = hpalNew;
115505b261ecSmrg
115605b261ecSmrg  /* Free the palette initialization memory */
115705b261ecSmrg  free (lpPaletteNew);
115805b261ecSmrg
115905b261ecSmrg  return TRUE;
116005b261ecSmrg}
116105b261ecSmrg
116205b261ecSmrg
116305b261ecSmrg/*
116405b261ecSmrg * Colormap destruction procedure
116505b261ecSmrg */
116605b261ecSmrg
116705b261ecSmrgstatic Bool
116805b261ecSmrgwinDestroyColormapShadowGDI (ColormapPtr pColormap)
116905b261ecSmrg{
117005b261ecSmrg  winScreenPriv(pColormap->pScreen);
117105b261ecSmrg  winCmapPriv(pColormap);
117205b261ecSmrg
117305b261ecSmrg  /*
117405b261ecSmrg   * Is colormap to be destroyed the default?
117505b261ecSmrg   *
117605b261ecSmrg   * Non-default colormaps should have had winUninstallColormap
117705b261ecSmrg   * called on them before we get here.  The default colormap
117805b261ecSmrg   * will not have had winUninstallColormap called on it.  Thus,
117905b261ecSmrg   * we need to handle the default colormap in a special way.
118005b261ecSmrg   */
118105b261ecSmrg  if (pColormap->flags & IsDefault)
118205b261ecSmrg    {
118305b261ecSmrg#if CYGDEBUG
118405b261ecSmrg      winDebug ("winDestroyColormapShadowGDI - Destroying default "
118505b261ecSmrg	      "colormap\n");
118605b261ecSmrg#endif
118705b261ecSmrg
118805b261ecSmrg      /*
118905b261ecSmrg       * FIXME: Walk the list of all screens, popping the default
119005b261ecSmrg       * palette out of each screen device context.
119105b261ecSmrg       */
119205b261ecSmrg
119305b261ecSmrg      /* Pop the palette out of the device context */
119405b261ecSmrg      SelectPalette (pScreenPriv->hdcScreen,
119505b261ecSmrg		     GetStockObject (DEFAULT_PALETTE),
119605b261ecSmrg		     FALSE);
119705b261ecSmrg
119805b261ecSmrg      /* Clear our private installed colormap pointer */
119905b261ecSmrg      pScreenPriv->pcmapInstalled = NULL;
120005b261ecSmrg    }
120105b261ecSmrg
120205b261ecSmrg  /* Try to delete the logical palette */
120305b261ecSmrg  if (DeleteObject (pCmapPriv->hPalette) == 0)
120405b261ecSmrg    {
120505b261ecSmrg      ErrorF ("winDestroyColormap - DeleteObject () failed\n");
120605b261ecSmrg      return FALSE;
120705b261ecSmrg    }
120805b261ecSmrg
120905b261ecSmrg  /* Invalidate the colormap privates */
121005b261ecSmrg  pCmapPriv->hPalette = NULL;
121105b261ecSmrg
121205b261ecSmrg  return TRUE;
121305b261ecSmrg}
121405b261ecSmrg
121505b261ecSmrg
121605b261ecSmrg/*
121705b261ecSmrg * Set engine specific funtions
121805b261ecSmrg */
121905b261ecSmrg
122005b261ecSmrgBool
122105b261ecSmrgwinSetEngineFunctionsShadowGDI (ScreenPtr pScreen)
122205b261ecSmrg{
122305b261ecSmrg  winScreenPriv(pScreen);
122405b261ecSmrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
122505b261ecSmrg
122605b261ecSmrg  /* Set our pointers */
122705b261ecSmrg  pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI;
12289ace9065Smrg  pScreenPriv->pwinFreeFB = winFreeFBShadowGDI;
122905b261ecSmrg  pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI;
12309ace9065Smrg  pScreenPriv->pwinInitScreen = winInitScreenShadowGDI;
123105b261ecSmrg  pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI;
123205b261ecSmrg  pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI;
123305b261ecSmrg  pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI;
123405b261ecSmrg  if (pScreenInfo->fFullScreen)
123505b261ecSmrg    pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen;
123605b261ecSmrg  else
123705b261ecSmrg    pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
123805b261ecSmrg  pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
123905b261ecSmrg  pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI;
124005b261ecSmrg  pScreenPriv->pwinActivateApp = winActivateAppShadowGDI;
124105b261ecSmrg  pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI;
124205b261ecSmrg  pScreenPriv->pwinRealizeInstalledPalette =
124305b261ecSmrg    winRealizeInstalledPaletteShadowGDI;
124405b261ecSmrg  pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI;
124505b261ecSmrg  pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI;
124605b261ecSmrg  pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI;
124705b261ecSmrg  pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI;
124805b261ecSmrg  pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA;
124905b261ecSmrg  pScreenPriv->pwinCreatePrimarySurface
125005b261ecSmrg    = (winCreatePrimarySurfaceProcPtr) (void (*)(void))NoopDDA;
125105b261ecSmrg  pScreenPriv->pwinReleasePrimarySurface
125205b261ecSmrg    = (winReleasePrimarySurfaceProcPtr) (void (*)(void))NoopDDA;
125305b261ecSmrg#ifdef XWIN_MULTIWINDOW
125405b261ecSmrg  pScreenPriv->pwinFinishCreateWindowsWindow =
125505b261ecSmrg    (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA;
125605b261ecSmrg#endif
125705b261ecSmrg
125805b261ecSmrg  return TRUE;
125905b261ecSmrg}
1260