1706f2543Smrg/*
2706f2543Smrg *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved.
3706f2543Smrg *
4706f2543Smrg *Permission is hereby granted, free of charge, to any person obtaining
5706f2543Smrg * a copy of this software and associated documentation files (the
6706f2543Smrg *"Software"), to deal in the Software without restriction, including
7706f2543Smrg *without limitation the rights to use, copy, modify, merge, publish,
8706f2543Smrg *distribute, sublicense, and/or sell copies of the Software, and to
9706f2543Smrg *permit persons to whom the Software is furnished to do so, subject to
10706f2543Smrg *the following conditions:
11706f2543Smrg *
12706f2543Smrg *The above copyright notice and this permission notice shall be
13706f2543Smrg *included in all copies or substantial portions of the Software.
14706f2543Smrg *
15706f2543Smrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16706f2543Smrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17706f2543Smrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18706f2543Smrg *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR
19706f2543Smrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20706f2543Smrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21706f2543Smrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22706f2543Smrg *
23706f2543Smrg *Except as contained in this notice, the name of Harold L Hunt II
24706f2543Smrg *shall not be used in advertising or otherwise to promote the sale, use
25706f2543Smrg *or other dealings in this Software without prior written authorization
26706f2543Smrg *from Harold L Hunt II.
27706f2543Smrg *
28706f2543Smrg * Authors:	Harold L Hunt II
29706f2543Smrg */
30706f2543Smrg
31706f2543Smrg#ifdef HAVE_XWIN_CONFIG_H
32706f2543Smrg#include <xwin-config.h>
33706f2543Smrg#endif
34706f2543Smrg#include "win.h"
35706f2543Smrg
36706f2543Smrg
37706f2543Smrg/*
38706f2543Smrg * Local function prototypes
39706f2543Smrg */
40706f2543Smrg
41706f2543Smrg#ifdef XWIN_MULTIWINDOW
42706f2543Smrgstatic wBOOL CALLBACK
43706f2543SmrgwinRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam);
44706f2543Smrg
45706f2543Smrgstatic wBOOL CALLBACK
46706f2543SmrgwinRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam);
47706f2543Smrg#endif
48706f2543Smrg
49706f2543Smrgstatic Bool
50706f2543SmrgwinAllocateFBShadowGDI (ScreenPtr pScreen);
51706f2543Smrg
52706f2543Smrgstatic void
53706f2543SmrgwinShadowUpdateGDI (ScreenPtr pScreen,
54706f2543Smrg		    shadowBufPtr pBuf);
55706f2543Smrg
56706f2543Smrgstatic Bool
57706f2543SmrgwinCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen);
58706f2543Smrg
59706f2543Smrgstatic Bool
60706f2543SmrgwinInitVisualsShadowGDI (ScreenPtr pScreen);
61706f2543Smrg
62706f2543Smrgstatic Bool
63706f2543SmrgwinAdjustVideoModeShadowGDI (ScreenPtr pScreen);
64706f2543Smrg
65706f2543Smrgstatic Bool
66706f2543SmrgwinBltExposedRegionsShadowGDI (ScreenPtr pScreen);
67706f2543Smrg
68706f2543Smrgstatic Bool
69706f2543SmrgwinActivateAppShadowGDI (ScreenPtr pScreen);
70706f2543Smrg
71706f2543Smrgstatic Bool
72706f2543SmrgwinRedrawScreenShadowGDI (ScreenPtr pScreen);
73706f2543Smrg
74706f2543Smrgstatic Bool
75706f2543SmrgwinRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen);
76706f2543Smrg
77706f2543Smrgstatic Bool
78706f2543SmrgwinInstallColormapShadowGDI (ColormapPtr pColormap);
79706f2543Smrg
80706f2543Smrgstatic Bool
81706f2543SmrgwinStoreColorsShadowGDI (ColormapPtr pmap,
82706f2543Smrg			 int ndef,
83706f2543Smrg			 xColorItem *pdefs);
84706f2543Smrg
85706f2543Smrgstatic Bool
86706f2543SmrgwinCreateColormapShadowGDI (ColormapPtr pColormap);
87706f2543Smrg
88706f2543Smrgstatic Bool
89706f2543SmrgwinDestroyColormapShadowGDI (ColormapPtr pColormap);
90706f2543Smrg
91706f2543Smrg
92706f2543Smrg/*
93706f2543Smrg * Internal function to get the DIB format that is compatible with the screen
94706f2543Smrg */
95706f2543Smrg
96706f2543Smrgstatic
97706f2543SmrgBool
98706f2543SmrgwinQueryScreenDIBFormat (ScreenPtr pScreen, BITMAPINFOHEADER *pbmih)
99706f2543Smrg{
100706f2543Smrg  winScreenPriv(pScreen);
101706f2543Smrg  HBITMAP		hbmp;
102706f2543Smrg#if CYGDEBUG
103706f2543Smrg  LPDWORD		pdw = NULL;
104706f2543Smrg#endif
105706f2543Smrg
106706f2543Smrg  /* Create a memory bitmap compatible with the screen */
107706f2543Smrg  hbmp = CreateCompatibleBitmap (pScreenPriv->hdcScreen, 1, 1);
108706f2543Smrg  if (hbmp == NULL)
109706f2543Smrg    {
110706f2543Smrg      ErrorF ("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n");
111706f2543Smrg      return FALSE;
112706f2543Smrg    }
113706f2543Smrg
114706f2543Smrg  /* Initialize our bitmap info header */
115706f2543Smrg  ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD));
116706f2543Smrg  pbmih->biSize = sizeof (BITMAPINFOHEADER);
117706f2543Smrg
118706f2543Smrg  /* Get the biBitCount */
119706f2543Smrg  if (!GetDIBits (pScreenPriv->hdcScreen,
120706f2543Smrg		  hbmp,
121706f2543Smrg		  0, 1,
122706f2543Smrg		  NULL,
123706f2543Smrg		  (BITMAPINFO*) pbmih,
124706f2543Smrg		  DIB_RGB_COLORS))
125706f2543Smrg    {
126706f2543Smrg      ErrorF ("winQueryScreenDIBFormat - First call to GetDIBits failed\n");
127706f2543Smrg      DeleteObject (hbmp);
128706f2543Smrg      return FALSE;
129706f2543Smrg    }
130706f2543Smrg
131706f2543Smrg#if CYGDEBUG
132706f2543Smrg  /* Get a pointer to bitfields */
133706f2543Smrg  pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER));
134706f2543Smrg
135706f2543Smrg  winDebug ("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n",
136706f2543Smrg	  pdw[0], pdw[1], pdw[2]);
137706f2543Smrg#endif
138706f2543Smrg
139706f2543Smrg  /* Get optimal color table, or the optimal bitfields */
140706f2543Smrg  if (!GetDIBits (pScreenPriv->hdcScreen,
141706f2543Smrg		  hbmp,
142706f2543Smrg		  0, 1,
143706f2543Smrg		  NULL,
144706f2543Smrg		  (BITMAPINFO*)pbmih,
145706f2543Smrg		  DIB_RGB_COLORS))
146706f2543Smrg    {
147706f2543Smrg      ErrorF ("winQueryScreenDIBFormat - Second call to GetDIBits "
148706f2543Smrg	      "failed\n");
149706f2543Smrg      DeleteObject (hbmp);
150706f2543Smrg      return FALSE;
151706f2543Smrg    }
152706f2543Smrg
153706f2543Smrg  /* Free memory */
154706f2543Smrg  DeleteObject (hbmp);
155706f2543Smrg
156706f2543Smrg  return TRUE;
157706f2543Smrg}
158706f2543Smrg
159706f2543Smrg
160706f2543Smrg/*
161706f2543Smrg * Internal function to determine the GDI bits per rgb and bit masks
162706f2543Smrg */
163706f2543Smrg
164706f2543Smrgstatic
165706f2543SmrgBool
166706f2543SmrgwinQueryRGBBitsAndMasks (ScreenPtr pScreen)
167706f2543Smrg{
168706f2543Smrg  winScreenPriv(pScreen);
169706f2543Smrg  BITMAPINFOHEADER	*pbmih = NULL;
170706f2543Smrg  Bool			fReturn = TRUE;
171706f2543Smrg  LPDWORD		pdw = NULL;
172706f2543Smrg  DWORD			dwRedBits, dwGreenBits, dwBlueBits;
173706f2543Smrg
174706f2543Smrg  /* Color masks for 8 bpp are standardized */
175706f2543Smrg  if (GetDeviceCaps (pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE)
176706f2543Smrg    {
177706f2543Smrg      /*
178706f2543Smrg       * RGB BPP for 8 bit palletes is always 8
179706f2543Smrg       * and the color masks are always 0.
180706f2543Smrg       */
181706f2543Smrg      pScreenPriv->dwBitsPerRGB = 8;
182706f2543Smrg      pScreenPriv->dwRedMask = 0x0L;
183706f2543Smrg      pScreenPriv->dwGreenMask = 0x0L;
184706f2543Smrg      pScreenPriv->dwBlueMask = 0x0L;
185706f2543Smrg      return TRUE;
186706f2543Smrg    }
187706f2543Smrg
188706f2543Smrg  /* Color masks for 24 bpp are standardized */
189706f2543Smrg  if (GetDeviceCaps (pScreenPriv->hdcScreen, PLANES)
190706f2543Smrg      * GetDeviceCaps (pScreenPriv->hdcScreen, BITSPIXEL) == 24)
191706f2543Smrg    {
192706f2543Smrg      ErrorF ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) "
193706f2543Smrg	      "returned 24 for the screen.  Using default 24bpp masks.\n");
194706f2543Smrg
195706f2543Smrg      /* 8 bits per primary color */
196706f2543Smrg      pScreenPriv->dwBitsPerRGB = 8;
197706f2543Smrg
198706f2543Smrg      /* Set screen privates masks */
199706f2543Smrg      pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED;
200706f2543Smrg      pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN;
201706f2543Smrg      pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE;
202706f2543Smrg
203706f2543Smrg      return TRUE;
204706f2543Smrg    }
205706f2543Smrg
206706f2543Smrg  /* Allocate a bitmap header and color table */
207706f2543Smrg  pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
208706f2543Smrg				      + 256  * sizeof (RGBQUAD));
209706f2543Smrg  if (pbmih == NULL)
210706f2543Smrg    {
211706f2543Smrg      ErrorF ("winQueryRGBBitsAndMasks - malloc failed\n");
212706f2543Smrg      return FALSE;
213706f2543Smrg    }
214706f2543Smrg
215706f2543Smrg  /* Get screen description */
216706f2543Smrg  if (winQueryScreenDIBFormat (pScreen, pbmih))
217706f2543Smrg    {
218706f2543Smrg      /* Get a pointer to bitfields */
219706f2543Smrg      pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER));
220706f2543Smrg
221706f2543Smrg#if CYGDEBUG
222706f2543Smrg      winDebug ("%s - Masks: %08x %08x %08x\n", __FUNCTION__,
223706f2543Smrg	      pdw[0], pdw[1], pdw[2]);
224706f2543Smrg      winDebug ("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__,
225706f2543Smrg              pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount, pbmih->biPlanes);
226706f2543Smrg      winDebug ("%s - Compression: %d %s\n", __FUNCTION__,
227706f2543Smrg              pbmih->biCompression,
228706f2543Smrg              (pbmih->biCompression == BI_RGB?"(BI_RGB)":
229706f2543Smrg               (pbmih->biCompression == BI_RLE8?"(BI_RLE8)":
230706f2543Smrg                (pbmih->biCompression == BI_RLE4?"(BI_RLE4)":
231706f2543Smrg                 (pbmih->biCompression == BI_BITFIELDS?"(BI_BITFIELDS)":""
232706f2543Smrg                 )))));
233706f2543Smrg#endif
234706f2543Smrg
235706f2543Smrg      /* Handle BI_RGB case, which is returned by Wine */
236706f2543Smrg      if (pbmih->biCompression == BI_RGB)
237706f2543Smrg        {
238706f2543Smrg	  dwRedBits = 5;
239706f2543Smrg	  dwGreenBits = 5;
240706f2543Smrg	  dwBlueBits = 5;
241706f2543Smrg
242706f2543Smrg	  pScreenPriv->dwBitsPerRGB = 5;
243706f2543Smrg
244706f2543Smrg	  /* Set screen privates masks */
245706f2543Smrg	  pScreenPriv->dwRedMask = 0x7c00;
246706f2543Smrg	  pScreenPriv->dwGreenMask = 0x03e0;
247706f2543Smrg	  pScreenPriv->dwBlueMask = 0x001f;
248706f2543Smrg        }
249706f2543Smrg      else
250706f2543Smrg        {
251706f2543Smrg          /* Count the number of bits in each mask */
252706f2543Smrg          dwRedBits = winCountBits (pdw[0]);
253706f2543Smrg          dwGreenBits = winCountBits (pdw[1]);
254706f2543Smrg          dwBlueBits = winCountBits (pdw[2]);
255706f2543Smrg
256706f2543Smrg	  /* Find maximum bits per red, green, blue */
257706f2543Smrg	  if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
258706f2543Smrg	    pScreenPriv->dwBitsPerRGB = dwRedBits;
259706f2543Smrg	  else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
260706f2543Smrg	    pScreenPriv->dwBitsPerRGB = dwGreenBits;
261706f2543Smrg	  else
262706f2543Smrg	    pScreenPriv->dwBitsPerRGB = dwBlueBits;
263706f2543Smrg
264706f2543Smrg	  /* Set screen privates masks */
265706f2543Smrg	  pScreenPriv->dwRedMask = pdw[0];
266706f2543Smrg	  pScreenPriv->dwGreenMask = pdw[1];
267706f2543Smrg	  pScreenPriv->dwBlueMask = pdw[2];
268706f2543Smrg	}
269706f2543Smrg    }
270706f2543Smrg  else
271706f2543Smrg    {
272706f2543Smrg      ErrorF ("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n");
273706f2543Smrg      free (pbmih);
274706f2543Smrg      fReturn = FALSE;
275706f2543Smrg    }
276706f2543Smrg
277706f2543Smrg  /* Free memory */
278706f2543Smrg  free (pbmih);
279706f2543Smrg
280706f2543Smrg  return fReturn;
281706f2543Smrg}
282706f2543Smrg
283706f2543Smrg
284706f2543Smrg#ifdef XWIN_MULTIWINDOW
285706f2543Smrg/*
286706f2543Smrg * Redraw all ---?
287706f2543Smrg */
288706f2543Smrg
289706f2543Smrgstatic wBOOL CALLBACK
290706f2543SmrgwinRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam)
291706f2543Smrg{
292706f2543Smrg  if (hwnd == (HWND)lParam)
293706f2543Smrg    return TRUE;
294706f2543Smrg  InvalidateRect (hwnd, NULL, FALSE);
295706f2543Smrg  UpdateWindow (hwnd);
296706f2543Smrg  return TRUE;
297706f2543Smrg}
298706f2543Smrg
299706f2543Smrgstatic wBOOL CALLBACK
300706f2543SmrgwinRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam)
301706f2543Smrg{
302706f2543Smrg  BoxPtr pDamage = (BoxPtr)lParam;
303706f2543Smrg  RECT rcClient, rcDamage, rcRedraw;
304706f2543Smrg  POINT topLeft, bottomRight;
305706f2543Smrg
306706f2543Smrg  if (IsIconic (hwnd))
307706f2543Smrg    return TRUE; /* Don't care minimized windows */
308706f2543Smrg
309706f2543Smrg  /* Convert the damaged area from Screen coords to Client coords */
310706f2543Smrg  topLeft.x = pDamage->x1; topLeft.y = pDamage->y1;
311706f2543Smrg  bottomRight.x = pDamage->x2; bottomRight.y = pDamage->y2;
312706f2543Smrg  topLeft.x += GetSystemMetrics (SM_XVIRTUALSCREEN);
313706f2543Smrg  bottomRight.x += GetSystemMetrics (SM_XVIRTUALSCREEN);
314706f2543Smrg  topLeft.y += GetSystemMetrics (SM_YVIRTUALSCREEN);
315706f2543Smrg  bottomRight.y += GetSystemMetrics (SM_YVIRTUALSCREEN);
316706f2543Smrg  ScreenToClient (hwnd, &topLeft);
317706f2543Smrg  ScreenToClient (hwnd, &bottomRight);
318706f2543Smrg  SetRect (&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
319706f2543Smrg
320706f2543Smrg  GetClientRect (hwnd, &rcClient);
321706f2543Smrg
322706f2543Smrg  if (IntersectRect (&rcRedraw, &rcClient, &rcDamage))
323706f2543Smrg    {
324706f2543Smrg      InvalidateRect (hwnd, &rcRedraw, FALSE);
325706f2543Smrg      UpdateWindow (hwnd);
326706f2543Smrg    }
327706f2543Smrg  return TRUE;
328706f2543Smrg}
329706f2543Smrg#endif
330706f2543Smrg
331706f2543Smrg
332706f2543Smrg/*
333706f2543Smrg * Allocate a DIB for the shadow framebuffer GDI server
334706f2543Smrg */
335706f2543Smrg
336706f2543Smrgstatic Bool
337706f2543SmrgwinAllocateFBShadowGDI (ScreenPtr pScreen)
338706f2543Smrg{
339706f2543Smrg  winScreenPriv(pScreen);
340706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
341706f2543Smrg  DIBSECTION		dibsection;
342706f2543Smrg  Bool			fReturn = TRUE;
343706f2543Smrg
344706f2543Smrg  /* Describe shadow bitmap to be created */
345706f2543Smrg  pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth;
346706f2543Smrg  pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight;
347706f2543Smrg
348706f2543Smrg  ErrorF ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d "
349706f2543Smrg	  "depth: %d\n",
350706f2543Smrg	  (int) pScreenPriv->pbmih->biWidth, (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount);
351706f2543Smrg
352706f2543Smrg  /* Create a DI shadow bitmap with a bit pointer */
353706f2543Smrg  pScreenPriv->hbmpShadow = CreateDIBSection (pScreenPriv->hdcScreen,
354706f2543Smrg					      (BITMAPINFO *) pScreenPriv->pbmih,
355706f2543Smrg					      DIB_RGB_COLORS,
356706f2543Smrg					      (VOID**) &pScreenInfo->pfb,
357706f2543Smrg					      NULL,
358706f2543Smrg					      0);
359706f2543Smrg  if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL)
360706f2543Smrg    {
361706f2543Smrg      winW32Error (2, "winAllocateFBShadowGDI - CreateDIBSection failed:");
362706f2543Smrg      return FALSE;
363706f2543Smrg    }
364706f2543Smrg  else
365706f2543Smrg    {
366706f2543Smrg#if CYGDEBUG
367706f2543Smrg      winDebug ("winAllocateFBShadowGDI - Shadow buffer allocated\n");
368706f2543Smrg#endif
369706f2543Smrg    }
370706f2543Smrg
371706f2543Smrg  /* Get information about the bitmap that was allocated */
372706f2543Smrg  GetObject (pScreenPriv->hbmpShadow,
373706f2543Smrg	     sizeof (dibsection),
374706f2543Smrg	     &dibsection);
375706f2543Smrg
376706f2543Smrg#if CYGDEBUG || YES
377706f2543Smrg  /* Print information about bitmap allocated */
378706f2543Smrg  winDebug ("winAllocateFBShadowGDI - Dibsection width: %d height: %d "
379706f2543Smrg	  "depth: %d size image: %d\n",
380706f2543Smrg	  (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight,
381706f2543Smrg	  dibsection.dsBmih.biBitCount,
382706f2543Smrg	  (int) dibsection.dsBmih.biSizeImage);
383706f2543Smrg#endif
384706f2543Smrg
385706f2543Smrg  /* Select the shadow bitmap into the shadow DC */
386706f2543Smrg  SelectObject (pScreenPriv->hdcShadow,
387706f2543Smrg		pScreenPriv->hbmpShadow);
388706f2543Smrg
389706f2543Smrg#if CYGDEBUG
390706f2543Smrg  winDebug ("winAllocateFBShadowGDI - Attempting a shadow blit\n");
391706f2543Smrg#endif
392706f2543Smrg
393706f2543Smrg  /* Do a test blit from the shadow to the screen, I think */
394706f2543Smrg  fReturn = BitBlt (pScreenPriv->hdcScreen,
395706f2543Smrg		    0, 0,
396706f2543Smrg		    pScreenInfo->dwWidth, pScreenInfo->dwHeight,
397706f2543Smrg		    pScreenPriv->hdcShadow,
398706f2543Smrg		    0, 0,
399706f2543Smrg		    SRCCOPY);
400706f2543Smrg  if (fReturn)
401706f2543Smrg    {
402706f2543Smrg#if CYGDEBUG
403706f2543Smrg      winDebug ("winAllocateFBShadowGDI - Shadow blit success\n");
404706f2543Smrg#endif
405706f2543Smrg    }
406706f2543Smrg  else
407706f2543Smrg    {
408706f2543Smrg      winW32Error (2, "winAllocateFBShadowGDI - Shadow blit failure\n");
409706f2543Smrg#if 0
410706f2543Smrg      return FALSE;
411706f2543Smrg#else
412706f2543Smrg      /* ago: ignore this error. The blit fails with wine, but does not
413706f2543Smrg       * cause any problems later. */
414706f2543Smrg
415706f2543Smrg      fReturn = TRUE;
416706f2543Smrg#endif
417706f2543Smrg    }
418706f2543Smrg
419706f2543Smrg  /* Look for height weirdness */
420706f2543Smrg  if (dibsection.dsBmih.biHeight < 0)
421706f2543Smrg    {
422706f2543Smrg      dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight;
423706f2543Smrg    }
424706f2543Smrg
425706f2543Smrg  /* Set screeninfo stride */
426706f2543Smrg  pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage
427706f2543Smrg			    / dibsection.dsBmih.biHeight)
428706f2543Smrg			   * 8) / pScreenInfo->dwBPP;
429706f2543Smrg
430706f2543Smrg#if CYGDEBUG || YES
431706f2543Smrg  winDebug ("winAllocateFBShadowGDI - Created shadow stride: %d\n",
432706f2543Smrg	  (int) pScreenInfo->dwStride);
433706f2543Smrg#endif
434706f2543Smrg
435706f2543Smrg#ifdef XWIN_MULTIWINDOW
436706f2543Smrg  /* Redraw all windows */
437706f2543Smrg  if (pScreenInfo->fMultiWindow)
438706f2543Smrg    EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
439706f2543Smrg#endif
440706f2543Smrg
441706f2543Smrg  return fReturn;
442706f2543Smrg}
443706f2543Smrg
444706f2543Smrgstatic void
445706f2543SmrgwinFreeFBShadowGDI (ScreenPtr pScreen)
446706f2543Smrg{
447706f2543Smrg  winScreenPriv(pScreen);
448706f2543Smrg  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
449706f2543Smrg
450706f2543Smrg  /* Free the shadow bitmap */
451706f2543Smrg  DeleteObject (pScreenPriv->hbmpShadow);
452706f2543Smrg
453706f2543Smrg  /* Invalidate the ScreenInfo's fb pointer */
454706f2543Smrg  pScreenInfo->pfb = NULL;
455706f2543Smrg}
456706f2543Smrg
457706f2543Smrg/*
458706f2543Smrg * Blit the damaged regions of the shadow fb to the screen
459706f2543Smrg */
460706f2543Smrg
461706f2543Smrgstatic void
462706f2543SmrgwinShadowUpdateGDI (ScreenPtr pScreen,
463706f2543Smrg		    shadowBufPtr pBuf)
464706f2543Smrg{
465706f2543Smrg  winScreenPriv(pScreen);
466706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
467706f2543Smrg  RegionPtr		damage = shadowDamage(pBuf);
468706f2543Smrg  DWORD			dwBox = RegionNumRects (damage);
469706f2543Smrg  BoxPtr		pBox = RegionRects (damage);
470706f2543Smrg  int			x, y, w, h;
471706f2543Smrg  HRGN			hrgnTemp = NULL, hrgnCombined = NULL;
472706f2543Smrg#ifdef XWIN_UPDATESTATS
473706f2543Smrg  static DWORD		s_dwNonUnitRegions = 0;
474706f2543Smrg  static DWORD		s_dwTotalUpdates = 0;
475706f2543Smrg  static DWORD		s_dwTotalBoxes = 0;
476706f2543Smrg#endif
477706f2543Smrg  BoxPtr		pBoxExtents = RegionExtents(damage);
478706f2543Smrg
479706f2543Smrg  /*
480706f2543Smrg   * Return immediately if the app is not active
481706f2543Smrg   * and we are fullscreen, or if we have a bad display depth
482706f2543Smrg   */
483706f2543Smrg  if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
484706f2543Smrg      || pScreenPriv->fBadDepth) return;
485706f2543Smrg
486706f2543Smrg#ifdef XWIN_UPDATESTATS
487706f2543Smrg  ++s_dwTotalUpdates;
488706f2543Smrg  s_dwTotalBoxes += dwBox;
489706f2543Smrg
490706f2543Smrg  if (dwBox != 1)
491706f2543Smrg    {
492706f2543Smrg      ++s_dwNonUnitRegions;
493706f2543Smrg      ErrorF ("winShadowUpdatGDI - dwBox: %d\n", dwBox);
494706f2543Smrg    }
495706f2543Smrg
496706f2543Smrg  if ((s_dwTotalUpdates % 100) == 0)
497706f2543Smrg    ErrorF ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d "
498706f2543Smrg	    "nu: %d tu: %d\n",
499706f2543Smrg	    (s_dwNonUnitRegions * 100) / s_dwTotalUpdates,
500706f2543Smrg	    s_dwTotalBoxes / s_dwTotalUpdates,
501706f2543Smrg	    s_dwNonUnitRegions, s_dwTotalUpdates);
502706f2543Smrg#endif /* XWIN_UPDATESTATS */
503706f2543Smrg
504706f2543Smrg  /*
505706f2543Smrg   * Handle small regions with multiple blits,
506706f2543Smrg   * handle large regions by creating a clipping region and
507706f2543Smrg   * doing a single blit constrained to that clipping region.
508706f2543Smrg   */
509706f2543Smrg  if (!pScreenInfo->fMultiWindow &&
510706f2543Smrg      (pScreenInfo->dwClipUpdatesNBoxes == 0 ||
511706f2543Smrg      dwBox < pScreenInfo->dwClipUpdatesNBoxes))
512706f2543Smrg    {
513706f2543Smrg      /* Loop through all boxes in the damaged region */
514706f2543Smrg      while (dwBox--)
515706f2543Smrg	{
516706f2543Smrg	  /*
517706f2543Smrg	   * Calculate x offset, y offset, width, and height for
518706f2543Smrg	   * current damage box
519706f2543Smrg	   */
520706f2543Smrg	  x = pBox->x1;
521706f2543Smrg	  y = pBox->y1;
522706f2543Smrg	  w = pBox->x2 - pBox->x1;
523706f2543Smrg	  h = pBox->y2 - pBox->y1;
524706f2543Smrg
525706f2543Smrg	  BitBlt (pScreenPriv->hdcScreen,
526706f2543Smrg		  x, y,
527706f2543Smrg		  w, h,
528706f2543Smrg		  pScreenPriv->hdcShadow,
529706f2543Smrg		  x, y,
530706f2543Smrg		  SRCCOPY);
531706f2543Smrg
532706f2543Smrg	  /* Get a pointer to the next box */
533706f2543Smrg	  ++pBox;
534706f2543Smrg	}
535706f2543Smrg    }
536706f2543Smrg  else if (!pScreenInfo->fMultiWindow)
537706f2543Smrg    {
538706f2543Smrg      /* Compute a GDI region from the damaged region */
539706f2543Smrg      hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
540706f2543Smrg      dwBox--;
541706f2543Smrg      pBox++;
542706f2543Smrg      while (dwBox--)
543706f2543Smrg	{
544706f2543Smrg	  hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
545706f2543Smrg	  CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
546706f2543Smrg	  DeleteObject (hrgnTemp);
547706f2543Smrg	  pBox++;
548706f2543Smrg	}
549706f2543Smrg
550706f2543Smrg      /* Install the GDI region as a clipping region */
551706f2543Smrg      SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined);
552706f2543Smrg      DeleteObject (hrgnCombined);
553706f2543Smrg      hrgnCombined = NULL;
554706f2543Smrg
555706f2543Smrg      /*
556706f2543Smrg       * Blit the shadow buffer to the screen,
557706f2543Smrg       * constrained to the clipping region.
558706f2543Smrg       */
559706f2543Smrg      BitBlt (pScreenPriv->hdcScreen,
560706f2543Smrg	      pBoxExtents->x1, pBoxExtents->y1,
561706f2543Smrg	      pBoxExtents->x2 - pBoxExtents->x1,
562706f2543Smrg	      pBoxExtents->y2 - pBoxExtents->y1,
563706f2543Smrg	      pScreenPriv->hdcShadow,
564706f2543Smrg	      pBoxExtents->x1, pBoxExtents->y1,
565706f2543Smrg	      SRCCOPY);
566706f2543Smrg
567706f2543Smrg      /* Reset the clip region */
568706f2543Smrg      SelectClipRgn (pScreenPriv->hdcScreen, NULL);
569706f2543Smrg    }
570706f2543Smrg
571706f2543Smrg#ifdef XWIN_MULTIWINDOW
572706f2543Smrg  /* Redraw all multiwindow windows */
573706f2543Smrg  if (pScreenInfo->fMultiWindow)
574706f2543Smrg    EnumThreadWindows (g_dwCurrentThreadID,
575706f2543Smrg		       winRedrawDamagedWindowShadowGDI,
576706f2543Smrg		       (LPARAM)pBoxExtents);
577706f2543Smrg#endif
578706f2543Smrg}
579706f2543Smrg
580706f2543Smrg
581706f2543Smrgstatic Bool
582706f2543SmrgwinInitScreenShadowGDI (ScreenPtr pScreen)
583706f2543Smrg{
584706f2543Smrg  winScreenPriv(pScreen);
585706f2543Smrg
586706f2543Smrg  /* Get device contexts for the screen and shadow bitmap */
587706f2543Smrg  pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
588706f2543Smrg  pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen);
589706f2543Smrg
590706f2543Smrg  /* Allocate bitmap info header */
591706f2543Smrg  pScreenPriv->pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
592706f2543Smrg                                                   + 256 * sizeof (RGBQUAD));
593706f2543Smrg  if (pScreenPriv->pbmih == NULL)
594706f2543Smrg    {
595706f2543Smrg      ErrorF ("winInitScreenShadowGDI - malloc () failed\n");
596706f2543Smrg      return FALSE;
597706f2543Smrg    }
598706f2543Smrg
599706f2543Smrg  /* Query the screen format */
600706f2543Smrg  if (!winQueryScreenDIBFormat (pScreen, pScreenPriv->pbmih))
601706f2543Smrg    {
602706f2543Smrg      ErrorF ("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n");
603706f2543Smrg      return FALSE;
604706f2543Smrg    }
605706f2543Smrg
606706f2543Smrg  /* Determine our color masks */
607706f2543Smrg  if (!winQueryRGBBitsAndMasks (pScreen))
608706f2543Smrg    {
609706f2543Smrg      ErrorF ("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n");
610706f2543Smrg      return FALSE;
611706f2543Smrg    }
612706f2543Smrg
613706f2543Smrg  return winAllocateFBShadowGDI(pScreen);
614706f2543Smrg}
615706f2543Smrg
616706f2543Smrg/* See Porting Layer Definition - p. 33 */
617706f2543Smrg/*
618706f2543Smrg * We wrap whatever CloseScreen procedure was specified by fb;
619706f2543Smrg * a pointer to said procedure is stored in our privates.
620706f2543Smrg */
621706f2543Smrg
622706f2543Smrgstatic Bool
623706f2543SmrgwinCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen)
624706f2543Smrg{
625706f2543Smrg  winScreenPriv(pScreen);
626706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
627706f2543Smrg  Bool			fReturn;
628706f2543Smrg
629706f2543Smrg#if CYGDEBUG
630706f2543Smrg  winDebug ("winCloseScreenShadowGDI - Freeing screen resources\n");
631706f2543Smrg#endif
632706f2543Smrg
633706f2543Smrg  /* Flag that the screen is closed */
634706f2543Smrg  pScreenPriv->fClosed = TRUE;
635706f2543Smrg  pScreenPriv->fActive = FALSE;
636706f2543Smrg
637706f2543Smrg  /* Call the wrapped CloseScreen procedure */
638706f2543Smrg  WIN_UNWRAP(CloseScreen);
639706f2543Smrg  fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);
640706f2543Smrg
641706f2543Smrg  /* Delete the window property */
642706f2543Smrg  RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
643706f2543Smrg
644706f2543Smrg  /* Free the shadow DC; which allows the bitmap to be freed */
645706f2543Smrg  DeleteDC (pScreenPriv->hdcShadow);
646706f2543Smrg
647706f2543Smrg  winFreeFBShadowGDI(pScreen);
648706f2543Smrg
649706f2543Smrg  /* Free the screen DC */
650706f2543Smrg  ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
651706f2543Smrg
652706f2543Smrg  /* Delete tray icon, if we have one */
653706f2543Smrg  if (!pScreenInfo->fNoTrayIcon)
654706f2543Smrg    winDeleteNotifyIcon (pScreenPriv);
655706f2543Smrg
656706f2543Smrg  /* Free the exit confirmation dialog box, if it exists */
657706f2543Smrg  if (g_hDlgExit != NULL)
658706f2543Smrg    {
659706f2543Smrg      DestroyWindow (g_hDlgExit);
660706f2543Smrg      g_hDlgExit = NULL;
661706f2543Smrg    }
662706f2543Smrg
663706f2543Smrg  /* Kill our window */
664706f2543Smrg  if (pScreenPriv->hwndScreen)
665706f2543Smrg    {
666706f2543Smrg      DestroyWindow (pScreenPriv->hwndScreen);
667706f2543Smrg      pScreenPriv->hwndScreen = NULL;
668706f2543Smrg    }
669706f2543Smrg
670706f2543Smrg#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
671706f2543Smrg  /* Destroy the thread startup mutex */
672706f2543Smrg  pthread_mutex_destroy (&pScreenPriv->pmServerStarted);
673706f2543Smrg#endif
674706f2543Smrg
675706f2543Smrg  /* Invalidate our screeninfo's pointer to the screen */
676706f2543Smrg  pScreenInfo->pScreen = NULL;
677706f2543Smrg
678706f2543Smrg  /* Free the screen privates for this screen */
679706f2543Smrg  free ((pointer) pScreenPriv);
680706f2543Smrg
681706f2543Smrg  return fReturn;
682706f2543Smrg}
683706f2543Smrg
684706f2543Smrg
685706f2543Smrg/*
686706f2543Smrg * Tell mi what sort of visuals we need.
687706f2543Smrg *
688706f2543Smrg * Generally we only need one visual, as our screen can only
689706f2543Smrg * handle one format at a time, I believe.  You may want
690706f2543Smrg * to verify that last sentence.
691706f2543Smrg */
692706f2543Smrg
693706f2543Smrgstatic Bool
694706f2543SmrgwinInitVisualsShadowGDI (ScreenPtr pScreen)
695706f2543Smrg{
696706f2543Smrg  winScreenPriv(pScreen);
697706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
698706f2543Smrg
699706f2543Smrg  /* Display debugging information */
700706f2543Smrg  ErrorF ("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d "
701706f2543Smrg	  "bpp %d\n",
702706f2543Smrg	  (unsigned int) pScreenPriv->dwRedMask,
703706f2543Smrg	  (unsigned int) pScreenPriv->dwGreenMask,
704706f2543Smrg	  (unsigned int) pScreenPriv->dwBlueMask,
705706f2543Smrg	  (int) pScreenPriv->dwBitsPerRGB,
706706f2543Smrg	  (int) pScreenInfo->dwDepth,
707706f2543Smrg	  (int) pScreenInfo->dwBPP);
708706f2543Smrg
709706f2543Smrg  /* Create a single visual according to the Windows screen depth */
710706f2543Smrg  switch (pScreenInfo->dwDepth)
711706f2543Smrg    {
712706f2543Smrg    case 24:
713706f2543Smrg    case 16:
714706f2543Smrg    case 15:
715706f2543Smrg      /* Setup the real visual */
716706f2543Smrg      if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
717706f2543Smrg				     TrueColorMask,
718706f2543Smrg				     pScreenPriv->dwBitsPerRGB,
719706f2543Smrg				     -1,
720706f2543Smrg				     pScreenPriv->dwRedMask,
721706f2543Smrg				     pScreenPriv->dwGreenMask,
722706f2543Smrg				     pScreenPriv->dwBlueMask))
723706f2543Smrg	{
724706f2543Smrg	  ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
725706f2543Smrg		  "failed\n");
726706f2543Smrg	  return FALSE;
727706f2543Smrg	}
728706f2543Smrg
729706f2543Smrg#ifdef XWIN_EMULATEPSEUDO
730706f2543Smrg      if (!pScreenInfo->fEmulatePseudo)
731706f2543Smrg	break;
732706f2543Smrg
733706f2543Smrg      /* Setup a pseudocolor visual */
734706f2543Smrg      if (!miSetVisualTypesAndMasks (8,
735706f2543Smrg				     PseudoColorMask,
736706f2543Smrg				     8,
737706f2543Smrg				     -1,
738706f2543Smrg				     0,
739706f2543Smrg				     0,
740706f2543Smrg				     0))
741706f2543Smrg	{
742706f2543Smrg	  ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
743706f2543Smrg		  "failed for PseudoColor\n");
744706f2543Smrg	  return FALSE;
745706f2543Smrg	}
746706f2543Smrg#endif
747706f2543Smrg      break;
748706f2543Smrg
749706f2543Smrg    case 8:
750706f2543Smrg      if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
751706f2543Smrg				     PseudoColorMask,
752706f2543Smrg				     pScreenPriv->dwBitsPerRGB,
753706f2543Smrg				     PseudoColor,
754706f2543Smrg				     pScreenPriv->dwRedMask,
755706f2543Smrg				     pScreenPriv->dwGreenMask,
756706f2543Smrg				     pScreenPriv->dwBlueMask))
757706f2543Smrg	{
758706f2543Smrg	  ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
759706f2543Smrg		  "failed\n");
760706f2543Smrg	  return FALSE;
761706f2543Smrg	}
762706f2543Smrg      break;
763706f2543Smrg
764706f2543Smrg    default:
765706f2543Smrg      ErrorF ("winInitVisualsShadowGDI - Unknown screen depth\n");
766706f2543Smrg      return FALSE;
767706f2543Smrg    }
768706f2543Smrg
769706f2543Smrg#if CYGDEBUG
770706f2543Smrg  winDebug ("winInitVisualsShadowGDI - Returning\n");
771706f2543Smrg#endif
772706f2543Smrg
773706f2543Smrg  return TRUE;
774706f2543Smrg}
775706f2543Smrg
776706f2543Smrg
777706f2543Smrg/*
778706f2543Smrg * Adjust the proposed video mode
779706f2543Smrg */
780706f2543Smrg
781706f2543Smrgstatic Bool
782706f2543SmrgwinAdjustVideoModeShadowGDI (ScreenPtr pScreen)
783706f2543Smrg{
784706f2543Smrg  winScreenPriv(pScreen);
785706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
786706f2543Smrg  HDC			hdc;
787706f2543Smrg  DWORD			dwBPP;
788706f2543Smrg
789706f2543Smrg  hdc = GetDC (NULL);
790706f2543Smrg
791706f2543Smrg  /* We're in serious trouble if we can't get a DC */
792706f2543Smrg  if (hdc == NULL)
793706f2543Smrg    {
794706f2543Smrg      ErrorF ("winAdjustVideoModeShadowGDI - GetDC () failed\n");
795706f2543Smrg      return FALSE;
796706f2543Smrg    }
797706f2543Smrg
798706f2543Smrg  /* Query GDI for current display depth */
799706f2543Smrg  dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
800706f2543Smrg
801706f2543Smrg  /* GDI cannot change the screen depth, so always use GDI's depth */
802706f2543Smrg  pScreenInfo->dwBPP = dwBPP;
803706f2543Smrg
804706f2543Smrg  /* Release our DC */
805706f2543Smrg  ReleaseDC (NULL, hdc);
806706f2543Smrg  hdc = NULL;
807706f2543Smrg
808706f2543Smrg  return TRUE;
809706f2543Smrg}
810706f2543Smrg
811706f2543Smrg
812706f2543Smrg/*
813706f2543Smrg * Blt exposed regions to the screen
814706f2543Smrg */
815706f2543Smrg
816706f2543Smrgstatic Bool
817706f2543SmrgwinBltExposedRegionsShadowGDI (ScreenPtr pScreen)
818706f2543Smrg{
819706f2543Smrg  winScreenPriv(pScreen);
820706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
821706f2543Smrg  winPrivCmapPtr	pCmapPriv = NULL;
822706f2543Smrg  HDC			hdcUpdate;
823706f2543Smrg  PAINTSTRUCT		ps;
824706f2543Smrg
825706f2543Smrg  /* BeginPaint gives us an hdc that clips to the invalidated region */
826706f2543Smrg  hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps);
827706f2543Smrg
828706f2543Smrg  /* Realize the palette, if we have one */
829706f2543Smrg  if (pScreenPriv->pcmapInstalled != NULL)
830706f2543Smrg    {
831706f2543Smrg      pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled);
832706f2543Smrg
833706f2543Smrg      SelectPalette (hdcUpdate, pCmapPriv->hPalette, FALSE);
834706f2543Smrg      RealizePalette (hdcUpdate);
835706f2543Smrg    }
836706f2543Smrg
837706f2543Smrg  /* Our BitBlt will be clipped to the invalidated region */
838706f2543Smrg  BitBlt (hdcUpdate,
839706f2543Smrg	  0, 0,
840706f2543Smrg	  pScreenInfo->dwWidth, pScreenInfo->dwHeight,
841706f2543Smrg	  pScreenPriv->hdcShadow,
842706f2543Smrg	  0, 0,
843706f2543Smrg	  SRCCOPY);
844706f2543Smrg
845706f2543Smrg  /* EndPaint frees the DC */
846706f2543Smrg  EndPaint (pScreenPriv->hwndScreen, &ps);
847706f2543Smrg
848706f2543Smrg#ifdef XWIN_MULTIWINDOW
849706f2543Smrg  /* Redraw all windows */
850706f2543Smrg  if (pScreenInfo->fMultiWindow)
851706f2543Smrg    EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI,
852706f2543Smrg            (LPARAM)pScreenPriv->hwndScreen);
853706f2543Smrg#endif
854706f2543Smrg
855706f2543Smrg  return TRUE;
856706f2543Smrg}
857706f2543Smrg
858706f2543Smrg
859706f2543Smrg/*
860706f2543Smrg * Do any engine-specific appliation-activation processing
861706f2543Smrg */
862706f2543Smrg
863706f2543Smrgstatic Bool
864706f2543SmrgwinActivateAppShadowGDI (ScreenPtr pScreen)
865706f2543Smrg{
866706f2543Smrg  winScreenPriv(pScreen);
867706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
868706f2543Smrg
869706f2543Smrg  /*
870706f2543Smrg   * 2004/04/12 - Harold - We perform the restoring or minimizing
871706f2543Smrg   * manually for ShadowGDI in fullscreen modes so that this engine
872706f2543Smrg   * will perform just like ShadowDD and ShadowDDNL in fullscreen mode;
873706f2543Smrg   * if we do not do this then our fullscreen window will appear in the
874706f2543Smrg   * z-order when it is deactivated and it can be uncovered by resizing
875706f2543Smrg   * or minimizing another window that is on top of it, which is not how
876706f2543Smrg   * the DirectDraw engines work.  Therefore we keep this code here to
877706f2543Smrg   * make sure that all engines work the same in fullscreen mode.
878706f2543Smrg   */
879706f2543Smrg
880706f2543Smrg  /*
881706f2543Smrg   * Are we active?
882706f2543Smrg   * Are we fullscreen?
883706f2543Smrg   */
884706f2543Smrg  if (pScreenPriv->fActive
885706f2543Smrg      && pScreenInfo->fFullScreen)
886706f2543Smrg    {
887706f2543Smrg      /*
888706f2543Smrg       * Activating, attempt to bring our window
889706f2543Smrg       * to the top of the display
890706f2543Smrg       */
891706f2543Smrg      ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE);
892706f2543Smrg    }
893706f2543Smrg  else if (!pScreenPriv->fActive
894706f2543Smrg	   && pScreenInfo->fFullScreen)
895706f2543Smrg    {
896706f2543Smrg      /*
897706f2543Smrg       * Deactivating, stuff our window onto the
898706f2543Smrg       * task bar.
899706f2543Smrg       */
900706f2543Smrg      ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE);
901706f2543Smrg    }
902706f2543Smrg
903706f2543Smrg  return TRUE;
904706f2543Smrg}
905706f2543Smrg
906706f2543Smrg
907706f2543Smrg/*
908706f2543Smrg * Reblit the shadow framebuffer to the screen.
909706f2543Smrg */
910706f2543Smrg
911706f2543Smrgstatic Bool
912706f2543SmrgwinRedrawScreenShadowGDI (ScreenPtr pScreen)
913706f2543Smrg{
914706f2543Smrg  winScreenPriv(pScreen);
915706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
916706f2543Smrg
917706f2543Smrg  /* Redraw the whole window, to take account for the new colors */
918706f2543Smrg  BitBlt (pScreenPriv->hdcScreen,
919706f2543Smrg	  0, 0,
920706f2543Smrg	  pScreenInfo->dwWidth, pScreenInfo->dwHeight,
921706f2543Smrg	  pScreenPriv->hdcShadow,
922706f2543Smrg	  0, 0,
923706f2543Smrg	  SRCCOPY);
924706f2543Smrg
925706f2543Smrg#ifdef XWIN_MULTIWINDOW
926706f2543Smrg  /* Redraw all windows */
927706f2543Smrg  if (pScreenInfo->fMultiWindow)
928706f2543Smrg    EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
929706f2543Smrg#endif
930706f2543Smrg
931706f2543Smrg  return TRUE;
932706f2543Smrg}
933706f2543Smrg
934706f2543Smrg
935706f2543Smrg
936706f2543Smrg/*
937706f2543Smrg * Realize the currently installed colormap
938706f2543Smrg */
939706f2543Smrg
940706f2543Smrgstatic Bool
941706f2543SmrgwinRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen)
942706f2543Smrg{
943706f2543Smrg  winScreenPriv(pScreen);
944706f2543Smrg  winPrivCmapPtr	pCmapPriv = NULL;
945706f2543Smrg
946706f2543Smrg#if CYGDEBUG
947706f2543Smrg  winDebug ("winRealizeInstalledPaletteShadowGDI\n");
948706f2543Smrg#endif
949706f2543Smrg
950706f2543Smrg  /* Don't do anything if there is not a colormap */
951706f2543Smrg  if (pScreenPriv->pcmapInstalled == NULL)
952706f2543Smrg    {
953706f2543Smrg#if CYGDEBUG
954706f2543Smrg      winDebug ("winRealizeInstalledPaletteShadowGDI - No colormap "
955706f2543Smrg	      "installed\n");
956706f2543Smrg#endif
957706f2543Smrg      return TRUE;
958706f2543Smrg    }
959706f2543Smrg
960706f2543Smrg  pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled);
961706f2543Smrg
962706f2543Smrg  /* Realize our palette for the screen */
963706f2543Smrg  if (RealizePalette (pScreenPriv->hdcScreen) == GDI_ERROR)
964706f2543Smrg    {
965706f2543Smrg      ErrorF ("winRealizeInstalledPaletteShadowGDI - RealizePalette () "
966706f2543Smrg	      "failed\n");
967706f2543Smrg      return FALSE;
968706f2543Smrg    }
969706f2543Smrg
970706f2543Smrg  /* Set the DIB color table */
971706f2543Smrg  if (SetDIBColorTable (pScreenPriv->hdcShadow,
972706f2543Smrg			0,
973706f2543Smrg			WIN_NUM_PALETTE_ENTRIES,
974706f2543Smrg			pCmapPriv->rgbColors) == 0)
975706f2543Smrg    {
976706f2543Smrg      ErrorF ("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () "
977706f2543Smrg	      "failed\n");
978706f2543Smrg      return FALSE;
979706f2543Smrg    }
980706f2543Smrg
981706f2543Smrg  return TRUE;
982706f2543Smrg}
983706f2543Smrg
984706f2543Smrg
985706f2543Smrg/*
986706f2543Smrg * Install the specified colormap
987706f2543Smrg */
988706f2543Smrg
989706f2543Smrgstatic Bool
990706f2543SmrgwinInstallColormapShadowGDI (ColormapPtr pColormap)
991706f2543Smrg{
992706f2543Smrg  ScreenPtr		pScreen = pColormap->pScreen;
993706f2543Smrg  winScreenPriv(pScreen);
994706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
995706f2543Smrg  winCmapPriv(pColormap);
996706f2543Smrg
997706f2543Smrg  /*
998706f2543Smrg   * Tell Windows to install the new colormap
999706f2543Smrg   */
1000706f2543Smrg  if (SelectPalette (pScreenPriv->hdcScreen,
1001706f2543Smrg		     pCmapPriv->hPalette,
1002706f2543Smrg		     FALSE) == NULL)
1003706f2543Smrg    {
1004706f2543Smrg      ErrorF ("winInstallColormapShadowGDI - SelectPalette () failed\n");
1005706f2543Smrg      return FALSE;
1006706f2543Smrg    }
1007706f2543Smrg
1008706f2543Smrg  /* Realize the palette */
1009706f2543Smrg  if (GDI_ERROR == RealizePalette (pScreenPriv->hdcScreen))
1010706f2543Smrg    {
1011706f2543Smrg      ErrorF ("winInstallColormapShadowGDI - RealizePalette () failed\n");
1012706f2543Smrg      return FALSE;
1013706f2543Smrg    }
1014706f2543Smrg
1015706f2543Smrg  /* Set the DIB color table */
1016706f2543Smrg  if (SetDIBColorTable (pScreenPriv->hdcShadow,
1017706f2543Smrg			0,
1018706f2543Smrg			WIN_NUM_PALETTE_ENTRIES,
1019706f2543Smrg			pCmapPriv->rgbColors) == 0)
1020706f2543Smrg    {
1021706f2543Smrg      ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
1022706f2543Smrg      return FALSE;
1023706f2543Smrg    }
1024706f2543Smrg
1025706f2543Smrg  /* Redraw the whole window, to take account for the new colors */
1026706f2543Smrg  BitBlt (pScreenPriv->hdcScreen,
1027706f2543Smrg	  0, 0,
1028706f2543Smrg	  pScreenInfo->dwWidth, pScreenInfo->dwHeight,
1029706f2543Smrg	  pScreenPriv->hdcShadow,
1030706f2543Smrg	  0, 0,
1031706f2543Smrg	  SRCCOPY);
1032706f2543Smrg
1033706f2543Smrg  /* Save a pointer to the newly installed colormap */
1034706f2543Smrg  pScreenPriv->pcmapInstalled = pColormap;
1035706f2543Smrg
1036706f2543Smrg#ifdef XWIN_MULTIWINDOW
1037706f2543Smrg  /* Redraw all windows */
1038706f2543Smrg  if (pScreenInfo->fMultiWindow)
1039706f2543Smrg    EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
1040706f2543Smrg#endif
1041706f2543Smrg
1042706f2543Smrg  return TRUE;
1043706f2543Smrg}
1044706f2543Smrg
1045706f2543Smrg
1046706f2543Smrg/*
1047706f2543Smrg * Store the specified colors in the specified colormap
1048706f2543Smrg */
1049706f2543Smrg
1050706f2543Smrgstatic Bool
1051706f2543SmrgwinStoreColorsShadowGDI (ColormapPtr pColormap,
1052706f2543Smrg			 int ndef,
1053706f2543Smrg			 xColorItem *pdefs)
1054706f2543Smrg{
1055706f2543Smrg  ScreenPtr		pScreen = pColormap->pScreen;
1056706f2543Smrg  winScreenPriv(pScreen);
1057706f2543Smrg  winCmapPriv(pColormap);
1058706f2543Smrg  ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
1059706f2543Smrg
1060706f2543Smrg  /* Put the X colormap entries into the Windows logical palette */
1061706f2543Smrg  if (SetPaletteEntries (pCmapPriv->hPalette,
1062706f2543Smrg			 pdefs[0].pixel,
1063706f2543Smrg			 ndef,
1064706f2543Smrg			 pCmapPriv->peColors + pdefs[0].pixel) == 0)
1065706f2543Smrg    {
1066706f2543Smrg      ErrorF ("winStoreColorsShadowGDI - SetPaletteEntries () failed\n");
1067706f2543Smrg      return FALSE;
1068706f2543Smrg    }
1069706f2543Smrg
1070706f2543Smrg  /* Don't install the Windows palette if the colormap is not installed */
1071706f2543Smrg  if (pColormap != curpmap)
1072706f2543Smrg    {
1073706f2543Smrg      return TRUE;
1074706f2543Smrg    }
1075706f2543Smrg
1076706f2543Smrg  /* Try to install the newly modified colormap */
1077706f2543Smrg  if (!winInstallColormapShadowGDI (pColormap))
1078706f2543Smrg    {
1079706f2543Smrg      ErrorF ("winInstallColormapShadowGDI - winInstallColormapShadowGDI "
1080706f2543Smrg	      "failed\n");
1081706f2543Smrg      return FALSE;
1082706f2543Smrg    }
1083706f2543Smrg
1084706f2543Smrg#if 0
1085706f2543Smrg  /* Tell Windows that the palette has changed */
1086706f2543Smrg  RealizePalette (pScreenPriv->hdcScreen);
1087706f2543Smrg
1088706f2543Smrg  /* Set the DIB color table */
1089706f2543Smrg  if (SetDIBColorTable (pScreenPriv->hdcShadow,
1090706f2543Smrg			pdefs[0].pixel,
1091706f2543Smrg			ndef,
1092706f2543Smrg			pCmapPriv->rgbColors + pdefs[0].pixel) == 0)
1093706f2543Smrg    {
1094706f2543Smrg      ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
1095706f2543Smrg      return FALSE;
1096706f2543Smrg    }
1097706f2543Smrg
1098706f2543Smrg  /* Save a pointer to the newly installed colormap */
1099706f2543Smrg  pScreenPriv->pcmapInstalled = pColormap;
1100706f2543Smrg#endif
1101706f2543Smrg
1102706f2543Smrg  return TRUE;
1103706f2543Smrg}
1104706f2543Smrg
1105706f2543Smrg
1106706f2543Smrg/*
1107706f2543Smrg * Colormap initialization procedure
1108706f2543Smrg */
1109706f2543Smrg
1110706f2543Smrgstatic Bool
1111706f2543SmrgwinCreateColormapShadowGDI (ColormapPtr pColormap)
1112706f2543Smrg{
1113706f2543Smrg  LPLOGPALETTE		lpPaletteNew = NULL;
1114706f2543Smrg  DWORD			dwEntriesMax;
1115706f2543Smrg  VisualPtr		pVisual;
1116706f2543Smrg  HPALETTE		hpalNew = NULL;
1117706f2543Smrg  winCmapPriv(pColormap);
1118706f2543Smrg
1119706f2543Smrg  /* Get a pointer to the visual that the colormap belongs to */
1120706f2543Smrg  pVisual = pColormap->pVisual;
1121706f2543Smrg
1122706f2543Smrg  /* Get the maximum number of palette entries for this visual */
1123706f2543Smrg  dwEntriesMax = pVisual->ColormapEntries;
1124706f2543Smrg
1125706f2543Smrg  /* Allocate a Windows logical color palette with max entries */
1126706f2543Smrg  lpPaletteNew = malloc (sizeof (LOGPALETTE)
1127706f2543Smrg			 + (dwEntriesMax - 1) * sizeof (PALETTEENTRY));
1128706f2543Smrg  if (lpPaletteNew == NULL)
1129706f2543Smrg    {
1130706f2543Smrg      ErrorF ("winCreateColormapShadowGDI - Couldn't allocate palette "
1131706f2543Smrg	      "with %d entries\n",
1132706f2543Smrg	      (int) dwEntriesMax);
1133706f2543Smrg      return FALSE;
1134706f2543Smrg    }
1135706f2543Smrg
1136706f2543Smrg  /* Zero out the colormap */
1137706f2543Smrg  ZeroMemory (lpPaletteNew, sizeof (LOGPALETTE)
1138706f2543Smrg	      + (dwEntriesMax - 1) * sizeof (PALETTEENTRY));
1139706f2543Smrg
1140706f2543Smrg  /* Set the logical palette structure */
1141706f2543Smrg  lpPaletteNew->palVersion = 0x0300;
1142706f2543Smrg  lpPaletteNew->palNumEntries = dwEntriesMax;
1143706f2543Smrg
1144706f2543Smrg  /* Tell Windows to create the palette */
1145706f2543Smrg  hpalNew = CreatePalette (lpPaletteNew);
1146706f2543Smrg  if (hpalNew == NULL)
1147706f2543Smrg    {
1148706f2543Smrg      ErrorF ("winCreateColormapShadowGDI - CreatePalette () failed\n");
1149706f2543Smrg      free (lpPaletteNew);
1150706f2543Smrg      return FALSE;
1151706f2543Smrg    }
1152706f2543Smrg
1153706f2543Smrg  /* Save the Windows logical palette handle in the X colormaps' privates */
1154706f2543Smrg  pCmapPriv->hPalette = hpalNew;
1155706f2543Smrg
1156706f2543Smrg  /* Free the palette initialization memory */
1157706f2543Smrg  free (lpPaletteNew);
1158706f2543Smrg
1159706f2543Smrg  return TRUE;
1160706f2543Smrg}
1161706f2543Smrg
1162706f2543Smrg
1163706f2543Smrg/*
1164706f2543Smrg * Colormap destruction procedure
1165706f2543Smrg */
1166706f2543Smrg
1167706f2543Smrgstatic Bool
1168706f2543SmrgwinDestroyColormapShadowGDI (ColormapPtr pColormap)
1169706f2543Smrg{
1170706f2543Smrg  winScreenPriv(pColormap->pScreen);
1171706f2543Smrg  winCmapPriv(pColormap);
1172706f2543Smrg
1173706f2543Smrg  /*
1174706f2543Smrg   * Is colormap to be destroyed the default?
1175706f2543Smrg   *
1176706f2543Smrg   * Non-default colormaps should have had winUninstallColormap
1177706f2543Smrg   * called on them before we get here.  The default colormap
1178706f2543Smrg   * will not have had winUninstallColormap called on it.  Thus,
1179706f2543Smrg   * we need to handle the default colormap in a special way.
1180706f2543Smrg   */
1181706f2543Smrg  if (pColormap->flags & IsDefault)
1182706f2543Smrg    {
1183706f2543Smrg#if CYGDEBUG
1184706f2543Smrg      winDebug ("winDestroyColormapShadowGDI - Destroying default "
1185706f2543Smrg	      "colormap\n");
1186706f2543Smrg#endif
1187706f2543Smrg
1188706f2543Smrg      /*
1189706f2543Smrg       * FIXME: Walk the list of all screens, popping the default
1190706f2543Smrg       * palette out of each screen device context.
1191706f2543Smrg       */
1192706f2543Smrg
1193706f2543Smrg      /* Pop the palette out of the device context */
1194706f2543Smrg      SelectPalette (pScreenPriv->hdcScreen,
1195706f2543Smrg		     GetStockObject (DEFAULT_PALETTE),
1196706f2543Smrg		     FALSE);
1197706f2543Smrg
1198706f2543Smrg      /* Clear our private installed colormap pointer */
1199706f2543Smrg      pScreenPriv->pcmapInstalled = NULL;
1200706f2543Smrg    }
1201706f2543Smrg
1202706f2543Smrg  /* Try to delete the logical palette */
1203706f2543Smrg  if (DeleteObject (pCmapPriv->hPalette) == 0)
1204706f2543Smrg    {
1205706f2543Smrg      ErrorF ("winDestroyColormap - DeleteObject () failed\n");
1206706f2543Smrg      return FALSE;
1207706f2543Smrg    }
1208706f2543Smrg
1209706f2543Smrg  /* Invalidate the colormap privates */
1210706f2543Smrg  pCmapPriv->hPalette = NULL;
1211706f2543Smrg
1212706f2543Smrg  return TRUE;
1213706f2543Smrg}
1214706f2543Smrg
1215706f2543Smrg
1216706f2543Smrg/*
1217706f2543Smrg * Set engine specific funtions
1218706f2543Smrg */
1219706f2543Smrg
1220706f2543SmrgBool
1221706f2543SmrgwinSetEngineFunctionsShadowGDI (ScreenPtr pScreen)
1222706f2543Smrg{
1223706f2543Smrg  winScreenPriv(pScreen);
1224706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
1225706f2543Smrg
1226706f2543Smrg  /* Set our pointers */
1227706f2543Smrg  pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI;
1228706f2543Smrg  pScreenPriv->pwinFreeFB = winFreeFBShadowGDI;
1229706f2543Smrg  pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI;
1230706f2543Smrg  pScreenPriv->pwinInitScreen = winInitScreenShadowGDI;
1231706f2543Smrg  pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI;
1232706f2543Smrg  pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI;
1233706f2543Smrg  pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI;
1234706f2543Smrg  if (pScreenInfo->fFullScreen)
1235706f2543Smrg    pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen;
1236706f2543Smrg  else
1237706f2543Smrg    pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
1238706f2543Smrg  pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
1239706f2543Smrg  pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI;
1240706f2543Smrg  pScreenPriv->pwinActivateApp = winActivateAppShadowGDI;
1241706f2543Smrg  pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI;
1242706f2543Smrg  pScreenPriv->pwinRealizeInstalledPalette =
1243706f2543Smrg    winRealizeInstalledPaletteShadowGDI;
1244706f2543Smrg  pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI;
1245706f2543Smrg  pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI;
1246706f2543Smrg  pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI;
1247706f2543Smrg  pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI;
1248706f2543Smrg  pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA;
1249706f2543Smrg  pScreenPriv->pwinCreatePrimarySurface
1250706f2543Smrg    = (winCreatePrimarySurfaceProcPtr) (void (*)(void))NoopDDA;
1251706f2543Smrg  pScreenPriv->pwinReleasePrimarySurface
1252706f2543Smrg    = (winReleasePrimarySurfaceProcPtr) (void (*)(void))NoopDDA;
1253706f2543Smrg#ifdef XWIN_MULTIWINDOW
1254706f2543Smrg  pScreenPriv->pwinFinishCreateWindowsWindow =
1255706f2543Smrg    (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA;
1256706f2543Smrg#endif
1257706f2543Smrg
1258706f2543Smrg  return TRUE;
1259706f2543Smrg}
1260