1706f2543Smrg/*
2706f2543Smrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. 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 THE XFREE86 PROJECT 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 the XFree86 Project
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 the XFree86 Project.
27706f2543Smrg *
28706f2543Smrg * Authors:	Dakshinamurthy Karra
29706f2543Smrg *		Suhaib M Siddiqi
30706f2543Smrg *		Peter Busch
31706f2543Smrg *		Harold L Hunt II
32706f2543Smrg */
33706f2543Smrg
34706f2543Smrg#ifdef HAVE_XWIN_CONFIG_H
35706f2543Smrg#include <xwin-config.h>
36706f2543Smrg#endif
37706f2543Smrg#include "win.h"
38706f2543Smrg
39706f2543Smrg
40706f2543Smrg/*
41706f2543Smrg * FIXME: Headers are broken, DEFINE_GUID doesn't work correctly,
42706f2543Smrg * so we have to redefine it here.
43706f2543Smrg */
44706f2543Smrg#ifdef DEFINE_GUID
45706f2543Smrg#undef DEFINE_GUID
46706f2543Smrg#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
47706f2543Smrg#endif /* DEFINE_GUID */
48706f2543Smrg
49706f2543Smrg/*
50706f2543Smrg * FIXME: Headers are broken, IID_IDirectDraw4 has to be defined
51706f2543Smrg * here manually.  Should be handled by ddraw.h
52706f2543Smrg */
53706f2543Smrg#ifndef IID_IDirectDraw4
54706f2543SmrgDEFINE_GUID( IID_IDirectDraw4, 0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 );
55706f2543Smrg#endif /* IID_IDirectDraw4 */
56706f2543Smrg
57706f2543Smrg#define FAIL_MSG_MAX_BLT	10
58706f2543Smrg
59706f2543Smrg
60706f2543Smrg/*
61706f2543Smrg * Local prototypes
62706f2543Smrg */
63706f2543Smrg
64706f2543Smrgstatic Bool
65706f2543SmrgwinAllocateFBShadowDDNL (ScreenPtr pScreen);
66706f2543Smrg
67706f2543Smrgstatic void
68706f2543SmrgwinShadowUpdateDDNL (ScreenPtr pScreen,
69706f2543Smrg		     shadowBufPtr pBuf);
70706f2543Smrg
71706f2543Smrgstatic Bool
72706f2543SmrgwinCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen);
73706f2543Smrg
74706f2543Smrgstatic Bool
75706f2543SmrgwinInitVisualsShadowDDNL (ScreenPtr pScreen);
76706f2543Smrg
77706f2543Smrgstatic Bool
78706f2543SmrgwinAdjustVideoModeShadowDDNL (ScreenPtr pScreen);
79706f2543Smrg
80706f2543Smrgstatic Bool
81706f2543SmrgwinBltExposedRegionsShadowDDNL (ScreenPtr pScreen);
82706f2543Smrg
83706f2543Smrgstatic Bool
84706f2543SmrgwinActivateAppShadowDDNL (ScreenPtr pScreen);
85706f2543Smrg
86706f2543Smrgstatic Bool
87706f2543SmrgwinRedrawScreenShadowDDNL (ScreenPtr pScreen);
88706f2543Smrg
89706f2543Smrgstatic Bool
90706f2543SmrgwinRealizeInstalledPaletteShadowDDNL (ScreenPtr pScreen);
91706f2543Smrg
92706f2543Smrgstatic Bool
93706f2543SmrgwinInstallColormapShadowDDNL (ColormapPtr pColormap);
94706f2543Smrg
95706f2543Smrgstatic Bool
96706f2543SmrgwinStoreColorsShadowDDNL (ColormapPtr pmap,
97706f2543Smrg			  int ndef,
98706f2543Smrg			  xColorItem *pdefs);
99706f2543Smrg
100706f2543Smrgstatic Bool
101706f2543SmrgwinCreateColormapShadowDDNL (ColormapPtr pColormap);
102706f2543Smrg
103706f2543Smrgstatic Bool
104706f2543SmrgwinDestroyColormapShadowDDNL (ColormapPtr pColormap);
105706f2543Smrg
106706f2543Smrgstatic Bool
107706f2543SmrgwinCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen);
108706f2543Smrg
109706f2543Smrgstatic Bool
110706f2543SmrgwinReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen);
111706f2543Smrg
112706f2543Smrg
113706f2543Smrg/*
114706f2543Smrg * Create the primary surface and attach the clipper.
115706f2543Smrg * Used for both the initial surface creation and during
116706f2543Smrg * WM_DISPLAYCHANGE messages.
117706f2543Smrg */
118706f2543Smrg
119706f2543Smrgstatic Bool
120706f2543SmrgwinCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen)
121706f2543Smrg{
122706f2543Smrg  winScreenPriv(pScreen);
123706f2543Smrg  HRESULT		ddrval = DD_OK;
124706f2543Smrg  DDSURFACEDESC2	ddsd;
125706f2543Smrg
126706f2543Smrg  winDebug ("winCreatePrimarySurfaceShadowDDNL - Creating primary surface\n");
127706f2543Smrg
128706f2543Smrg  /* Describe the primary surface */
129706f2543Smrg  ZeroMemory (&ddsd, sizeof (ddsd));
130706f2543Smrg  ddsd.dwSize = sizeof (ddsd);
131706f2543Smrg  ddsd.dwFlags = DDSD_CAPS;
132706f2543Smrg  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
133706f2543Smrg
134706f2543Smrg  /* Create the primary surface */
135706f2543Smrg  ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4,
136706f2543Smrg				       &ddsd,
137706f2543Smrg				       &pScreenPriv->pddsPrimary4,
138706f2543Smrg				       NULL);
139706f2543Smrg  pScreenPriv->fRetryCreateSurface = FALSE;
140706f2543Smrg  if (FAILED (ddrval))
141706f2543Smrg    {
142706f2543Smrg      if (ddrval == DDERR_NOEXCLUSIVEMODE)
143706f2543Smrg        {
144706f2543Smrg          /* Recreating the surface failed. Mark screen to retry later */
145706f2543Smrg          pScreenPriv->fRetryCreateSurface = TRUE;
146706f2543Smrg          winDebug ("winCreatePrimarySurfaceShadowDDNL - Could not create "
147706f2543Smrg	          "primary surface: DDERR_NOEXCLUSIVEMODE\n");
148706f2543Smrg        }
149706f2543Smrg      else
150706f2543Smrg        {
151706f2543Smrg          ErrorF ("winCreatePrimarySurfaceShadowDDNL - Could not create "
152706f2543Smrg	          "primary surface: %08x\n", (unsigned int) ddrval);
153706f2543Smrg        }
154706f2543Smrg      return FALSE;
155706f2543Smrg    }
156706f2543Smrg
157706f2543Smrg#if 1
158706f2543Smrg  winDebug ("winCreatePrimarySurfaceShadowDDNL - Created primary surface\n");
159706f2543Smrg#endif
160706f2543Smrg
161706f2543Smrg  /* Attach our clipper to our primary surface handle */
162706f2543Smrg  ddrval = IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4,
163706f2543Smrg					   pScreenPriv->pddcPrimary);
164706f2543Smrg  if (FAILED (ddrval))
165706f2543Smrg    {
166706f2543Smrg      ErrorF ("winCreatePrimarySurfaceShadowDDNL - Primary attach clipper "
167706f2543Smrg	      "failed: %08x\n",
168706f2543Smrg	      (unsigned int) ddrval);
169706f2543Smrg      return FALSE;
170706f2543Smrg    }
171706f2543Smrg
172706f2543Smrg#if 1
173706f2543Smrg  winDebug ("winCreatePrimarySurfaceShadowDDNL - Attached clipper to primary "
174706f2543Smrg	  "surface\n");
175706f2543Smrg#endif
176706f2543Smrg
177706f2543Smrg  /* Everything was correct */
178706f2543Smrg  return TRUE;
179706f2543Smrg}
180706f2543Smrg
181706f2543Smrg
182706f2543Smrg/*
183706f2543Smrg * Detach the clipper and release the primary surface.
184706f2543Smrg * Called from WM_DISPLAYCHANGE.
185706f2543Smrg */
186706f2543Smrg
187706f2543Smrgstatic Bool
188706f2543SmrgwinReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen)
189706f2543Smrg{
190706f2543Smrg  winScreenPriv(pScreen);
191706f2543Smrg
192706f2543Smrg  winDebug ("winReleasePrimarySurfaceShadowDDNL - Hello\n");
193706f2543Smrg
194706f2543Smrg  /* Release the primary surface and clipper, if they exist */
195706f2543Smrg  if (pScreenPriv->pddsPrimary4)
196706f2543Smrg    {
197706f2543Smrg      /*
198706f2543Smrg       * Detach the clipper from the primary surface.
199706f2543Smrg       * NOTE: We do this explicity for clarity.  The Clipper is not released.
200706f2543Smrg       */
201706f2543Smrg      IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4,
202706f2543Smrg				      NULL);
203706f2543Smrg
204706f2543Smrg      winDebug ("winReleasePrimarySurfaceShadowDDNL - Detached clipper\n");
205706f2543Smrg
206706f2543Smrg      /* Release the primary surface */
207706f2543Smrg      IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4);
208706f2543Smrg      pScreenPriv->pddsPrimary4 = NULL;
209706f2543Smrg    }
210706f2543Smrg
211706f2543Smrg  winDebug ("winReleasePrimarySurfaceShadowDDNL - Released primary surface\n");
212706f2543Smrg
213706f2543Smrg  return TRUE;
214706f2543Smrg}
215706f2543Smrg
216706f2543Smrg
217706f2543Smrg/*
218706f2543Smrg * Create a DirectDraw surface for the shadow framebuffer; also create
219706f2543Smrg * a primary surface object so we can blit to the display.
220706f2543Smrg *
221706f2543Smrg * Install a DirectDraw clipper on our primary surface object
222706f2543Smrg * that clips our blits to the unobscured client area of our display window.
223706f2543Smrg */
224706f2543Smrg
225706f2543SmrgBool
226706f2543SmrgwinAllocateFBShadowDDNL (ScreenPtr pScreen)
227706f2543Smrg{
228706f2543Smrg  winScreenPriv(pScreen);
229706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
230706f2543Smrg  HRESULT		ddrval = DD_OK;
231706f2543Smrg  DDSURFACEDESC2	ddsdShadow;
232706f2543Smrg  char			*lpSurface = NULL;
233706f2543Smrg  DDPIXELFORMAT		ddpfPrimary;
234706f2543Smrg
235706f2543Smrg#if CYGDEBUG
236706f2543Smrg  winDebug ("winAllocateFBShadowDDNL - w %d h %d d %d\n",
237706f2543Smrg	  pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwDepth);
238706f2543Smrg#endif
239706f2543Smrg
240706f2543Smrg  /* Set the padded screen width */
241706f2543Smrg  pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth,
242706f2543Smrg					      pScreenInfo->dwBPP);
243706f2543Smrg
244706f2543Smrg  /* Allocate memory for our shadow surface */
245706f2543Smrg  lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight);
246706f2543Smrg  if (lpSurface == NULL)
247706f2543Smrg    {
248706f2543Smrg      ErrorF ("winAllocateFBShadowDDNL - Could not allocate bits\n");
249706f2543Smrg      return FALSE;
250706f2543Smrg    }
251706f2543Smrg
252706f2543Smrg  /*
253706f2543Smrg   * Initialize the framebuffer memory so we don't get a
254706f2543Smrg   * strange display at startup
255706f2543Smrg   */
256706f2543Smrg  ZeroMemory (lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight);
257706f2543Smrg
258706f2543Smrg  /* Create a clipper */
259706f2543Smrg  ddrval = (*g_fpDirectDrawCreateClipper) (0,
260706f2543Smrg					   &pScreenPriv->pddcPrimary,
261706f2543Smrg					   NULL);
262706f2543Smrg  if (FAILED (ddrval))
263706f2543Smrg    {
264706f2543Smrg      ErrorF ("winAllocateFBShadowDDNL - Could not attach clipper: %08x\n",
265706f2543Smrg	      (unsigned int) ddrval);
266706f2543Smrg      return FALSE;
267706f2543Smrg    }
268706f2543Smrg
269706f2543Smrg#if CYGDEBUG
270706f2543Smrg  winDebug ("winAllocateFBShadowDDNL - Created a clipper\n");
271706f2543Smrg#endif
272706f2543Smrg
273706f2543Smrg  /* Attach the clipper to our display window */
274706f2543Smrg  ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary,
275706f2543Smrg				       0,
276706f2543Smrg				       pScreenPriv->hwndScreen);
277706f2543Smrg  if (FAILED (ddrval))
278706f2543Smrg    {
279706f2543Smrg      ErrorF ("winAllocateFBShadowDDNL - Clipper not attached "
280706f2543Smrg	      "to window: %08x\n",
281706f2543Smrg	      (unsigned int) ddrval);
282706f2543Smrg      return FALSE;
283706f2543Smrg    }
284706f2543Smrg
285706f2543Smrg#if CYGDEBUG
286706f2543Smrg  winDebug ("winAllocateFBShadowDDNL - Attached clipper to window\n");
287706f2543Smrg#endif
288706f2543Smrg
289706f2543Smrg  /* Create a DirectDraw object, store the address at lpdd */
290706f2543Smrg  ddrval = (*g_fpDirectDrawCreate) (NULL,
291706f2543Smrg				    (LPDIRECTDRAW*) &pScreenPriv->pdd,
292706f2543Smrg				    NULL);
293706f2543Smrg  if (FAILED (ddrval))
294706f2543Smrg    {
295706f2543Smrg      ErrorF ("winAllocateFBShadowDDNL - Could not start "
296706f2543Smrg	      "DirectDraw: %08x\n",
297706f2543Smrg	      (unsigned int) ddrval);
298706f2543Smrg      return FALSE;
299706f2543Smrg    }
300706f2543Smrg
301706f2543Smrg#if CYGDEBUG
302706f2543Smrg  winDebug ("winAllocateFBShadowDDNL - Created and initialized DD\n");
303706f2543Smrg#endif
304706f2543Smrg
305706f2543Smrg  /* Get a DirectDraw4 interface pointer */
306706f2543Smrg  ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd,
307706f2543Smrg				       &IID_IDirectDraw4,
308706f2543Smrg				       (LPVOID*) &pScreenPriv->pdd4);
309706f2543Smrg  if (FAILED (ddrval))
310706f2543Smrg    {
311706f2543Smrg      ErrorF ("winAllocateFBShadowDDNL - Failed DD4 query: %08x\n",
312706f2543Smrg	      (unsigned int) ddrval);
313706f2543Smrg      return FALSE;
314706f2543Smrg    }
315706f2543Smrg
316706f2543Smrg  /* Are we full screen? */
317706f2543Smrg  if (pScreenInfo->fFullScreen)
318706f2543Smrg    {
319706f2543Smrg      DDSURFACEDESC2	ddsdCurrent;
320706f2543Smrg      DWORD		dwRefreshRateCurrent = 0;
321706f2543Smrg      HDC		hdc = NULL;
322706f2543Smrg
323706f2543Smrg      /* Set the cooperative level to full screen */
324706f2543Smrg      ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4,
325706f2543Smrg						 pScreenPriv->hwndScreen,
326706f2543Smrg						 DDSCL_EXCLUSIVE
327706f2543Smrg						 | DDSCL_FULLSCREEN);
328706f2543Smrg      if (FAILED (ddrval))
329706f2543Smrg	{
330706f2543Smrg	  ErrorF ("winAllocateFBShadowDDNL - Could not set "
331706f2543Smrg		  "cooperative level: %08x\n",
332706f2543Smrg		  (unsigned int) ddrval);
333706f2543Smrg	  return FALSE;
334706f2543Smrg	}
335706f2543Smrg
336706f2543Smrg      /*
337706f2543Smrg       * We only need to get the current refresh rate for comparison
338706f2543Smrg       * if a refresh rate has been passed on the command line.
339706f2543Smrg       */
340706f2543Smrg      if (pScreenInfo->dwRefreshRate != 0)
341706f2543Smrg	{
342706f2543Smrg	  ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent));
343706f2543Smrg	  ddsdCurrent.dwSize = sizeof (ddsdCurrent);
344706f2543Smrg
345706f2543Smrg	  /* Get information about current display settings */
346706f2543Smrg	  ddrval = IDirectDraw4_GetDisplayMode (pScreenPriv->pdd4,
347706f2543Smrg						&ddsdCurrent);
348706f2543Smrg	  if (FAILED (ddrval))
349706f2543Smrg	    {
350706f2543Smrg	      ErrorF ("winAllocateFBShadowDDNL - Could not get current "
351706f2543Smrg		      "refresh rate: %08x.  Continuing.\n",
352706f2543Smrg		      (unsigned int) ddrval);
353706f2543Smrg	      dwRefreshRateCurrent = 0;
354706f2543Smrg	    }
355706f2543Smrg	  else
356706f2543Smrg	    {
357706f2543Smrg	      /* Grab the current refresh rate */
358706f2543Smrg	      dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate;
359706f2543Smrg	    }
360706f2543Smrg	}
361706f2543Smrg
362706f2543Smrg      /* Clean up the refresh rate */
363706f2543Smrg      if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate)
364706f2543Smrg	{
365706f2543Smrg	  /*
366706f2543Smrg	   * Refresh rate is non-specified or equal to current.
367706f2543Smrg	   */
368706f2543Smrg	  pScreenInfo->dwRefreshRate = 0;
369706f2543Smrg	}
370706f2543Smrg
371706f2543Smrg      /* Grab a device context for the screen */
372706f2543Smrg      hdc = GetDC (NULL);
373706f2543Smrg      if (hdc == NULL)
374706f2543Smrg	{
375706f2543Smrg	  ErrorF ("winAllocateFBShadowDDNL - GetDC () failed\n");
376706f2543Smrg	  return FALSE;
377706f2543Smrg	}
378706f2543Smrg
379706f2543Smrg      /* Only change the video mode when different than current mode */
380706f2543Smrg      if (!pScreenInfo->fMultipleMonitors
381706f2543Smrg	  && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN)
382706f2543Smrg	      || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN)
383706f2543Smrg	      || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL)
384706f2543Smrg	      || pScreenInfo->dwRefreshRate != 0))
385706f2543Smrg	{
386706f2543Smrg	  winDebug ("winAllocateFBShadowDDNL - Changing video mode\n");
387706f2543Smrg
388706f2543Smrg	  /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */
389706f2543Smrg	  ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4,
390706f2543Smrg						pScreenInfo->dwWidth,
391706f2543Smrg						pScreenInfo->dwHeight,
392706f2543Smrg						pScreenInfo->dwBPP,
393706f2543Smrg						pScreenInfo->dwRefreshRate,
394706f2543Smrg						0);
395706f2543Smrg	  if (FAILED (ddrval))
396706f2543Smrg	    {
397706f2543Smrg	      ErrorF ("winAllocateFBShadowDDNL - Could not set "
398706f2543Smrg		      "full screen display mode: %08x\n",
399706f2543Smrg		      (unsigned int) ddrval);
400706f2543Smrg	      ErrorF ("winAllocateFBShadowDDNL - Using default driver refresh rate\n");
401706f2543Smrg	      ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4,
402706f2543Smrg						    pScreenInfo->dwWidth,
403706f2543Smrg						    pScreenInfo->dwHeight,
404706f2543Smrg						    pScreenInfo->dwBPP,
405706f2543Smrg						    0,
406706f2543Smrg						    0);
407706f2543Smrg	      if (FAILED(ddrval))
408706f2543Smrg		{
409706f2543Smrg			ErrorF ("winAllocateFBShadowDDNL - Could not set default refresh rate "
410706f2543Smrg				"full screen display mode: %08x\n",
411706f2543Smrg				(unsigned int) ddrval);
412706f2543Smrg			return FALSE;
413706f2543Smrg		}
414706f2543Smrg	    }
415706f2543Smrg	}
416706f2543Smrg      else
417706f2543Smrg	{
418706f2543Smrg	  winDebug ("winAllocateFBShadowDDNL - Not changing video mode\n");
419706f2543Smrg	}
420706f2543Smrg
421706f2543Smrg      /* Release our DC */
422706f2543Smrg      ReleaseDC (NULL, hdc);
423706f2543Smrg      hdc = NULL;
424706f2543Smrg    }
425706f2543Smrg  else
426706f2543Smrg    {
427706f2543Smrg      /* Set the cooperative level for windowed mode */
428706f2543Smrg      ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4,
429706f2543Smrg						 pScreenPriv->hwndScreen,
430706f2543Smrg						 DDSCL_NORMAL);
431706f2543Smrg      if (FAILED (ddrval))
432706f2543Smrg	{
433706f2543Smrg	  ErrorF ("winAllocateFBShadowDDNL - Could not set "
434706f2543Smrg		  "cooperative level: %08x\n",
435706f2543Smrg		  (unsigned int) ddrval);
436706f2543Smrg	  return FALSE;
437706f2543Smrg	}
438706f2543Smrg    }
439706f2543Smrg
440706f2543Smrg  /* Create the primary surface */
441706f2543Smrg  if (!winCreatePrimarySurfaceShadowDDNL (pScreen))
442706f2543Smrg    {
443706f2543Smrg      ErrorF ("winAllocateFBShadowDDNL - winCreatePrimarySurfaceShadowDDNL "
444706f2543Smrg	      "failed\n");
445706f2543Smrg      return FALSE;
446706f2543Smrg    }
447706f2543Smrg
448706f2543Smrg  /* Get primary surface's pixel format */
449706f2543Smrg  ZeroMemory (&ddpfPrimary, sizeof (ddpfPrimary));
450706f2543Smrg  ddpfPrimary.dwSize = sizeof (ddpfPrimary);
451706f2543Smrg  ddrval = IDirectDrawSurface4_GetPixelFormat (pScreenPriv->pddsPrimary4,
452706f2543Smrg					       &ddpfPrimary);
453706f2543Smrg  if (FAILED (ddrval))
454706f2543Smrg    {
455706f2543Smrg      ErrorF ("winAllocateFBShadowDDNL - Could not get primary "
456706f2543Smrg	      "pixformat: %08x\n",
457706f2543Smrg	      (unsigned int) ddrval);
458706f2543Smrg      return FALSE;
459706f2543Smrg    }
460706f2543Smrg
461706f2543Smrg#if CYGDEBUG
462706f2543Smrg  winDebug ("winAllocateFBShadowDDNL - Primary masks: %08x %08x %08x "
463706f2543Smrg	  "dwRGBBitCount: %d\n",
464706f2543Smrg	  ddpfPrimary.u2.dwRBitMask,
465706f2543Smrg	  ddpfPrimary.u3.dwGBitMask,
466706f2543Smrg	  ddpfPrimary.u4.dwBBitMask,
467706f2543Smrg	  ddpfPrimary.u1.dwRGBBitCount);
468706f2543Smrg#endif
469706f2543Smrg
470706f2543Smrg  /* Describe the shadow surface to be created */
471706f2543Smrg  /*
472706f2543Smrg   * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface,
473706f2543Smrg   * as drawing, locking, and unlocking take forever
474706f2543Smrg   * with video memory surfaces.  In addition,
475706f2543Smrg   * video memory is a somewhat scarce resource,
476706f2543Smrg   * so you shouldn't be allocating video memory when
477706f2543Smrg   * you have the option of using system memory instead.
478706f2543Smrg   */
479706f2543Smrg  ZeroMemory (&ddsdShadow, sizeof (ddsdShadow));
480706f2543Smrg  ddsdShadow.dwSize = sizeof (ddsdShadow);
481706f2543Smrg  ddsdShadow.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH
482706f2543Smrg    | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT;
483706f2543Smrg  ddsdShadow.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
484706f2543Smrg  ddsdShadow.dwHeight = pScreenInfo->dwHeight;
485706f2543Smrg  ddsdShadow.dwWidth = pScreenInfo->dwWidth;
486706f2543Smrg  ddsdShadow.u1.lPitch = pScreenInfo->dwPaddedWidth;
487706f2543Smrg  ddsdShadow.lpSurface = lpSurface;
488706f2543Smrg  ddsdShadow.u4.ddpfPixelFormat = ddpfPrimary;
489706f2543Smrg
490706f2543Smrg  winDebug ("winAllocateFBShadowDDNL - lPitch: %d\n",
491706f2543Smrg	  (int) pScreenInfo->dwPaddedWidth);
492706f2543Smrg
493706f2543Smrg  /* Create the shadow surface */
494706f2543Smrg  ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4,
495706f2543Smrg				       &ddsdShadow,
496706f2543Smrg				       &pScreenPriv->pddsShadow4,
497706f2543Smrg				       NULL);
498706f2543Smrg  if (FAILED (ddrval))
499706f2543Smrg    {
500706f2543Smrg      ErrorF ("winAllocateFBShadowDDNL - Could not create shadow "
501706f2543Smrg	      "surface: %08x\n", (unsigned int) ddrval);
502706f2543Smrg      return FALSE;
503706f2543Smrg    }
504706f2543Smrg
505706f2543Smrg#if CYGDEBUG || YES
506706f2543Smrg  winDebug ("winAllocateFBShadowDDNL - Created shadow pitch: %d\n",
507706f2543Smrg	  (int) ddsdShadow.u1.lPitch);
508706f2543Smrg#endif
509706f2543Smrg
510706f2543Smrg  /* Grab the pitch from the surface desc */
511706f2543Smrg  pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8)
512706f2543Smrg    / pScreenInfo->dwBPP;
513706f2543Smrg
514706f2543Smrg#if CYGDEBUG || YES
515706f2543Smrg  winDebug ("winAllocateFBShadowDDNL - Created shadow stride: %d\n",
516706f2543Smrg	  (int) pScreenInfo->dwStride);
517706f2543Smrg#endif
518706f2543Smrg
519706f2543Smrg  /* Save the pointer to our surface memory */
520706f2543Smrg  pScreenInfo->pfb = lpSurface;
521706f2543Smrg
522706f2543Smrg  /* Grab the masks from the surface description */
523706f2543Smrg  pScreenPriv->dwRedMask = ddsdShadow.u4.ddpfPixelFormat.u2.dwRBitMask;
524706f2543Smrg  pScreenPriv->dwGreenMask = ddsdShadow.u4.ddpfPixelFormat.u3.dwGBitMask;
525706f2543Smrg  pScreenPriv->dwBlueMask = ddsdShadow.u4.ddpfPixelFormat.u4.dwBBitMask;
526706f2543Smrg
527706f2543Smrg#if CYGDEBUG
528706f2543Smrg  winDebug ("winAllocateFBShadowDDNL - Returning\n");
529706f2543Smrg#endif
530706f2543Smrg
531706f2543Smrg  return TRUE;
532706f2543Smrg}
533706f2543Smrg
534706f2543Smrgstatic void
535706f2543SmrgwinFreeFBShadowDDNL(ScreenPtr pScreen)
536706f2543Smrg{
537706f2543Smrg  winScreenPriv(pScreen);
538706f2543Smrg  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
539706f2543Smrg
540706f2543Smrg  /* Free the shadow surface, if there is one */
541706f2543Smrg  if (pScreenPriv->pddsShadow4)
542706f2543Smrg    {
543706f2543Smrg      IDirectDrawSurface4_Release (pScreenPriv->pddsShadow4);
544706f2543Smrg      free (pScreenInfo->pfb);
545706f2543Smrg      pScreenInfo->pfb = NULL;
546706f2543Smrg      pScreenPriv->pddsShadow4 = NULL;
547706f2543Smrg    }
548706f2543Smrg
549706f2543Smrg  /* Detach the clipper from the primary surface and release the primary surface, if there is one */
550706f2543Smrg  winReleasePrimarySurfaceShadowDDNL(pScreen);
551706f2543Smrg
552706f2543Smrg  /* Release the clipper object */
553706f2543Smrg  if (pScreenPriv->pddcPrimary)
554706f2543Smrg    {
555706f2543Smrg      IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
556706f2543Smrg      pScreenPriv->pddcPrimary = NULL;
557706f2543Smrg    }
558706f2543Smrg
559706f2543Smrg  /* Free the DirectDraw4 object, if there is one */
560706f2543Smrg  if (pScreenPriv->pdd4)
561706f2543Smrg    {
562706f2543Smrg      IDirectDraw4_RestoreDisplayMode (pScreenPriv->pdd4);
563706f2543Smrg      IDirectDraw4_Release (pScreenPriv->pdd4);
564706f2543Smrg      pScreenPriv->pdd4 = NULL;
565706f2543Smrg    }
566706f2543Smrg
567706f2543Smrg  /* Free the DirectDraw object, if there is one */
568706f2543Smrg  if (pScreenPriv->pdd)
569706f2543Smrg    {
570706f2543Smrg      IDirectDraw_Release (pScreenPriv->pdd);
571706f2543Smrg      pScreenPriv->pdd = NULL;
572706f2543Smrg    }
573706f2543Smrg
574706f2543Smrg  /* Invalidate the ScreenInfo's fb pointer */
575706f2543Smrg  pScreenInfo->pfb = NULL;
576706f2543Smrg}
577706f2543Smrg
578706f2543Smrg#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
579706f2543Smrg/*
580706f2543Smrg * Create a DirectDraw surface for the new multi-window window
581706f2543Smrg */
582706f2543Smrg
583706f2543Smrgstatic
584706f2543SmrgBool
585706f2543SmrgwinFinishCreateWindowsWindowDDNL (WindowPtr pWin)
586706f2543Smrg{
587706f2543Smrg  winWindowPriv(pWin);
588706f2543Smrg  winPrivScreenPtr	pScreenPriv = pWinPriv->pScreenPriv;
589706f2543Smrg  HRESULT		ddrval = DD_OK;
590706f2543Smrg  DDSURFACEDESC2	ddsd;
591706f2543Smrg  int			iWidth, iHeight;
592706f2543Smrg  int			iX, iY;
593706f2543Smrg
594706f2543Smrg  winDebug ("winFinishCreateWindowsWindowDDNL!\n\n");
595706f2543Smrg
596706f2543Smrg  iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
597706f2543Smrg  iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
598706f2543Smrg
599706f2543Smrg  iWidth = pWin->drawable.width;
600706f2543Smrg  iHeight = pWin->drawable.height;
601706f2543Smrg
602706f2543Smrg  /* Describe the primary surface */
603706f2543Smrg  ZeroMemory (&ddsd, sizeof (ddsd));
604706f2543Smrg  ddsd.dwSize = sizeof (ddsd);
605706f2543Smrg  ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
606706f2543Smrg  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
607706f2543Smrg  ddsd.dwHeight = iHeight;
608706f2543Smrg  ddsd.dwWidth = iWidth;
609706f2543Smrg
610706f2543Smrg  /* Create the primary surface */
611706f2543Smrg  ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4,
612706f2543Smrg				       &ddsd,
613706f2543Smrg				       &pWinPriv->pddsPrimary4,
614706f2543Smrg				       NULL);
615706f2543Smrg  if (FAILED (ddrval))
616706f2543Smrg    {
617706f2543Smrg      ErrorF ("winFinishCreateWindowsWindowDDNL - Could not create primary "
618706f2543Smrg	      "surface: %08x\n",
619706f2543Smrg	      (unsigned int)ddrval);
620706f2543Smrg      return FALSE;
621706f2543Smrg    }
622706f2543Smrg  return TRUE;
623706f2543Smrg}
624706f2543Smrg#endif
625706f2543Smrg
626706f2543Smrg
627706f2543Smrg/*
628706f2543Smrg * Transfer the damaged regions of the shadow framebuffer to the display.
629706f2543Smrg */
630706f2543Smrg
631706f2543Smrgstatic void
632706f2543SmrgwinShadowUpdateDDNL (ScreenPtr pScreen,
633706f2543Smrg		     shadowBufPtr pBuf)
634706f2543Smrg{
635706f2543Smrg  winScreenPriv(pScreen);
636706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
637706f2543Smrg  RegionPtr		damage = shadowDamage(pBuf);
638706f2543Smrg  HRESULT		ddrval = DD_OK;
639706f2543Smrg  RECT			rcDest, rcSrc;
640706f2543Smrg  POINT			ptOrigin;
641706f2543Smrg  DWORD			dwBox = RegionNumRects (damage);
642706f2543Smrg  BoxPtr		pBox = RegionRects (damage);
643706f2543Smrg  HRGN			hrgnTemp = NULL, hrgnCombined = NULL;
644706f2543Smrg
645706f2543Smrg  /*
646706f2543Smrg   * Return immediately if the app is not active
647706f2543Smrg   * and we are fullscreen, or if we have a bad display depth
648706f2543Smrg   */
649706f2543Smrg  if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
650706f2543Smrg      || pScreenPriv->fBadDepth) return;
651706f2543Smrg
652706f2543Smrg  /* Return immediately if we didn't get needed surfaces */
653706f2543Smrg  if (!pScreenPriv->pddsPrimary4 || !pScreenPriv->pddsShadow4)
654706f2543Smrg    return;
655706f2543Smrg
656706f2543Smrg  /* Get the origin of the window in the screen coords */
657706f2543Smrg  ptOrigin.x = pScreenInfo->dwXOffset;
658706f2543Smrg  ptOrigin.y = pScreenInfo->dwYOffset;
659706f2543Smrg  MapWindowPoints (pScreenPriv->hwndScreen,
660706f2543Smrg		   HWND_DESKTOP,
661706f2543Smrg		   (LPPOINT)&ptOrigin, 1);
662706f2543Smrg
663706f2543Smrg  /*
664706f2543Smrg   * Handle small regions with multiple blits,
665706f2543Smrg   * handle large regions by creating a clipping region and
666706f2543Smrg   * doing a single blit constrained to that clipping region.
667706f2543Smrg   */
668706f2543Smrg  if (pScreenInfo->dwClipUpdatesNBoxes == 0
669706f2543Smrg      || dwBox < pScreenInfo->dwClipUpdatesNBoxes)
670706f2543Smrg    {
671706f2543Smrg      /* Loop through all boxes in the damaged region */
672706f2543Smrg      while (dwBox--)
673706f2543Smrg	{
674706f2543Smrg	  /* Assign damage box to source rectangle */
675706f2543Smrg	  rcSrc.left = pBox->x1;
676706f2543Smrg	  rcSrc.top = pBox->y1;
677706f2543Smrg	  rcSrc.right = pBox->x2;
678706f2543Smrg	  rcSrc.bottom = pBox->y2;
679706f2543Smrg
680706f2543Smrg	  /* Calculate destination rectangle */
681706f2543Smrg	  rcDest.left = ptOrigin.x + rcSrc.left;
682706f2543Smrg	  rcDest.top = ptOrigin.y + rcSrc.top;
683706f2543Smrg	  rcDest.right = ptOrigin.x + rcSrc.right;
684706f2543Smrg	  rcDest.bottom = ptOrigin.y + rcSrc.bottom;
685706f2543Smrg
686706f2543Smrg	  /* Blit the damaged areas */
687706f2543Smrg	  ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4,
688706f2543Smrg					    &rcDest,
689706f2543Smrg					    pScreenPriv->pddsShadow4,
690706f2543Smrg					    &rcSrc,
691706f2543Smrg					    DDBLT_WAIT,
692706f2543Smrg					    NULL);
693706f2543Smrg	  if (FAILED (ddrval))
694706f2543Smrg	    {
695706f2543Smrg	      static int	s_iFailCount = 0;
696706f2543Smrg
697706f2543Smrg	      if (s_iFailCount < FAIL_MSG_MAX_BLT)
698706f2543Smrg		{
699706f2543Smrg		  ErrorF ("winShadowUpdateDDNL - IDirectDrawSurface4_Blt () "
700706f2543Smrg			  "failed: %08x\n",
701706f2543Smrg			  (unsigned int) ddrval);
702706f2543Smrg
703706f2543Smrg		  ++s_iFailCount;
704706f2543Smrg
705706f2543Smrg		  if (s_iFailCount == FAIL_MSG_MAX_BLT)
706706f2543Smrg		    {
707706f2543Smrg		      ErrorF ("winShadowUpdateDDNL - IDirectDrawSurface4_Blt "
708706f2543Smrg			      "failure message maximum (%d) reached.  No "
709706f2543Smrg			      "more failure messages will be printed.\n",
710706f2543Smrg			      FAIL_MSG_MAX_BLT);
711706f2543Smrg		    }
712706f2543Smrg		}
713706f2543Smrg	    }
714706f2543Smrg
715706f2543Smrg	  /* Get a pointer to the next box */
716706f2543Smrg	  ++pBox;
717706f2543Smrg	}
718706f2543Smrg    }
719706f2543Smrg  else
720706f2543Smrg    {
721706f2543Smrg      BoxPtr		pBoxExtents = RegionExtents(damage);
722706f2543Smrg
723706f2543Smrg      /* Compute a GDI region from the damaged region */
724706f2543Smrg      hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
725706f2543Smrg      dwBox--;
726706f2543Smrg      pBox++;
727706f2543Smrg      while (dwBox--)
728706f2543Smrg	{
729706f2543Smrg	  hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
730706f2543Smrg	  CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
731706f2543Smrg	  DeleteObject (hrgnTemp);
732706f2543Smrg	  pBox++;
733706f2543Smrg	}
734706f2543Smrg
735706f2543Smrg      /* Install the GDI region as a clipping region */
736706f2543Smrg      SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined);
737706f2543Smrg      DeleteObject (hrgnCombined);
738706f2543Smrg      hrgnCombined = NULL;
739706f2543Smrg
740706f2543Smrg#if CYGDEBUG
741706f2543Smrg      winDebug ("winShadowUpdateDDNL - be x1 %d y1 %d x2 %d y2 %d\n",
742706f2543Smrg	      pBoxExtents->x1, pBoxExtents->y1,
743706f2543Smrg	      pBoxExtents->x2, pBoxExtents->y2);
744706f2543Smrg#endif
745706f2543Smrg
746706f2543Smrg      /* Calculating a bounding box for the source is easy */
747706f2543Smrg      rcSrc.left = pBoxExtents->x1;
748706f2543Smrg      rcSrc.top = pBoxExtents->y1;
749706f2543Smrg      rcSrc.right = pBoxExtents->x2;
750706f2543Smrg      rcSrc.bottom = pBoxExtents->y2;
751706f2543Smrg
752706f2543Smrg      /* Calculating a bounding box for the destination is trickier */
753706f2543Smrg      rcDest.left = ptOrigin.x + rcSrc.left;
754706f2543Smrg      rcDest.top = ptOrigin.y + rcSrc.top;
755706f2543Smrg      rcDest.right = ptOrigin.x + rcSrc.right;
756706f2543Smrg      rcDest.bottom = ptOrigin.y + rcSrc.bottom;
757706f2543Smrg
758706f2543Smrg      /* Our Blt should be clipped to the invalidated region */
759706f2543Smrg      ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4,
760706f2543Smrg					&rcDest,
761706f2543Smrg					pScreenPriv->pddsShadow4,
762706f2543Smrg					&rcSrc,
763706f2543Smrg					DDBLT_WAIT,
764706f2543Smrg					NULL);
765706f2543Smrg
766706f2543Smrg      /* Reset the clip region */
767706f2543Smrg      SelectClipRgn (pScreenPriv->hdcScreen, NULL);
768706f2543Smrg    }
769706f2543Smrg}
770706f2543Smrg
771706f2543Smrgstatic Bool
772706f2543SmrgwinInitScreenShadowDDNL(ScreenPtr pScreen)
773706f2543Smrg{
774706f2543Smrg  winScreenPriv(pScreen);
775706f2543Smrg
776706f2543Smrg  /* Get a device context for the screen  */
777706f2543Smrg  pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
778706f2543Smrg
779706f2543Smrg  return winAllocateFBShadowDDNL(pScreen);
780706f2543Smrg}
781706f2543Smrg
782706f2543Smrg/*
783706f2543Smrg * Call the wrapped CloseScreen function.
784706f2543Smrg *
785706f2543Smrg * Free our resources and private structures.
786706f2543Smrg */
787706f2543Smrg
788706f2543Smrgstatic Bool
789706f2543SmrgwinCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen)
790706f2543Smrg{
791706f2543Smrg  winScreenPriv(pScreen);
792706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
793706f2543Smrg  Bool			fReturn;
794706f2543Smrg
795706f2543Smrg#if CYGDEBUG
796706f2543Smrg  winDebug ("winCloseScreenShadowDDNL - Freeing screen resources\n");
797706f2543Smrg#endif
798706f2543Smrg
799706f2543Smrg  /* Flag that the screen is closed */
800706f2543Smrg  pScreenPriv->fClosed = TRUE;
801706f2543Smrg  pScreenPriv->fActive = FALSE;
802706f2543Smrg
803706f2543Smrg  /* Call the wrapped CloseScreen procedure */
804706f2543Smrg  WIN_UNWRAP(CloseScreen);
805706f2543Smrg  fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);
806706f2543Smrg
807706f2543Smrg  winFreeFBShadowDDNL(pScreen);
808706f2543Smrg
809706f2543Smrg  /* Free the screen DC */
810706f2543Smrg  ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
811706f2543Smrg
812706f2543Smrg  /* Delete the window property */
813706f2543Smrg  RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
814706f2543Smrg
815706f2543Smrg  /* Delete tray icon, if we have one */
816706f2543Smrg  if (!pScreenInfo->fNoTrayIcon)
817706f2543Smrg    winDeleteNotifyIcon (pScreenPriv);
818706f2543Smrg
819706f2543Smrg  /* Free the exit confirmation dialog box, if it exists */
820706f2543Smrg  if (g_hDlgExit != NULL)
821706f2543Smrg    {
822706f2543Smrg      DestroyWindow (g_hDlgExit);
823706f2543Smrg      g_hDlgExit = NULL;
824706f2543Smrg    }
825706f2543Smrg
826706f2543Smrg  /* Kill our window */
827706f2543Smrg  if (pScreenPriv->hwndScreen)
828706f2543Smrg    {
829706f2543Smrg      DestroyWindow (pScreenPriv->hwndScreen);
830706f2543Smrg      pScreenPriv->hwndScreen = NULL;
831706f2543Smrg    }
832706f2543Smrg
833706f2543Smrg#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
834706f2543Smrg  /* Destroy the thread startup mutex */
835706f2543Smrg  pthread_mutex_destroy (&pScreenPriv->pmServerStarted);
836706f2543Smrg#endif
837706f2543Smrg
838706f2543Smrg  /* Kill our screeninfo's pointer to the screen */
839706f2543Smrg  pScreenInfo->pScreen = NULL;
840706f2543Smrg
841706f2543Smrg  /* Free the screen privates for this screen */
842706f2543Smrg  free ((pointer) pScreenPriv);
843706f2543Smrg
844706f2543Smrg  return fReturn;
845706f2543Smrg}
846706f2543Smrg
847706f2543Smrg
848706f2543Smrg/*
849706f2543Smrg * Tell mi what sort of visuals we need.
850706f2543Smrg *
851706f2543Smrg * Generally we only need one visual, as our screen can only
852706f2543Smrg * handle one format at a time, I believe.  You may want
853706f2543Smrg * to verify that last sentence.
854706f2543Smrg */
855706f2543Smrg
856706f2543Smrgstatic Bool
857706f2543SmrgwinInitVisualsShadowDDNL (ScreenPtr pScreen)
858706f2543Smrg{
859706f2543Smrg  winScreenPriv(pScreen);
860706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
861706f2543Smrg  DWORD			dwRedBits, dwGreenBits, dwBlueBits;
862706f2543Smrg
863706f2543Smrg  /* Count the number of ones in each color mask */
864706f2543Smrg  dwRedBits = winCountBits (pScreenPriv->dwRedMask);
865706f2543Smrg  dwGreenBits = winCountBits (pScreenPriv->dwGreenMask);
866706f2543Smrg  dwBlueBits = winCountBits (pScreenPriv->dwBlueMask);
867706f2543Smrg
868706f2543Smrg  /* Store the maximum number of ones in a color mask as the bitsPerRGB */
869706f2543Smrg  if (dwRedBits == 0 || dwGreenBits == 0 || dwBlueBits == 0)
870706f2543Smrg    pScreenPriv->dwBitsPerRGB = 8;
871706f2543Smrg  else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
872706f2543Smrg    pScreenPriv->dwBitsPerRGB = dwRedBits;
873706f2543Smrg  else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
874706f2543Smrg    pScreenPriv->dwBitsPerRGB = dwGreenBits;
875706f2543Smrg  else
876706f2543Smrg    pScreenPriv->dwBitsPerRGB = dwBlueBits;
877706f2543Smrg
878706f2543Smrg  winDebug ("winInitVisualsShadowDDNL - Masks %08x %08x %08x BPRGB %d d %d "
879706f2543Smrg	  "bpp %d\n",
880706f2543Smrg	  (unsigned int) pScreenPriv->dwRedMask,
881706f2543Smrg	  (unsigned int) pScreenPriv->dwGreenMask,
882706f2543Smrg	  (unsigned int) pScreenPriv->dwBlueMask,
883706f2543Smrg	  (int) pScreenPriv->dwBitsPerRGB,
884706f2543Smrg	  (int) pScreenInfo->dwDepth,
885706f2543Smrg	  (int) pScreenInfo->dwBPP);
886706f2543Smrg
887706f2543Smrg  /* Create a single visual according to the Windows screen depth */
888706f2543Smrg  switch (pScreenInfo->dwDepth)
889706f2543Smrg    {
890706f2543Smrg    case 24:
891706f2543Smrg    case 16:
892706f2543Smrg    case 15:
893706f2543Smrg      /* Setup the real visual */
894706f2543Smrg      if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
895706f2543Smrg				     TrueColorMask,
896706f2543Smrg				     pScreenPriv->dwBitsPerRGB,
897706f2543Smrg				     -1,
898706f2543Smrg				     pScreenPriv->dwRedMask,
899706f2543Smrg				     pScreenPriv->dwGreenMask,
900706f2543Smrg				     pScreenPriv->dwBlueMask))
901706f2543Smrg	{
902706f2543Smrg	  ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks "
903706f2543Smrg		  "failed for TrueColor\n");
904706f2543Smrg	  return FALSE;
905706f2543Smrg	}
906706f2543Smrg
907706f2543Smrg#ifdef XWIN_EMULATEPSEUDO
908706f2543Smrg      if (!pScreenInfo->fEmulatePseudo)
909706f2543Smrg	break;
910706f2543Smrg
911706f2543Smrg      /* Setup a pseudocolor visual */
912706f2543Smrg      if (!miSetVisualTypesAndMasks (8,
913706f2543Smrg				     PseudoColorMask,
914706f2543Smrg				     8,
915706f2543Smrg				     -1,
916706f2543Smrg				     0,
917706f2543Smrg				     0,
918706f2543Smrg				     0))
919706f2543Smrg	{
920706f2543Smrg	  ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks "
921706f2543Smrg		  "failed for PseudoColor\n");
922706f2543Smrg	  return FALSE;
923706f2543Smrg	}
924706f2543Smrg#endif
925706f2543Smrg      break;
926706f2543Smrg
927706f2543Smrg    case 8:
928706f2543Smrg      if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
929706f2543Smrg				     pScreenInfo->fFullScreen
930706f2543Smrg				     ? PseudoColorMask : StaticColorMask,
931706f2543Smrg				     pScreenPriv->dwBitsPerRGB,
932706f2543Smrg				     pScreenInfo->fFullScreen
933706f2543Smrg				     ? PseudoColor : StaticColor,
934706f2543Smrg				     pScreenPriv->dwRedMask,
935706f2543Smrg				     pScreenPriv->dwGreenMask,
936706f2543Smrg				     pScreenPriv->dwBlueMask))
937706f2543Smrg	{
938706f2543Smrg	  ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks "
939706f2543Smrg		  "failed\n");
940706f2543Smrg	  return FALSE;
941706f2543Smrg	}
942706f2543Smrg      break;
943706f2543Smrg
944706f2543Smrg    default:
945706f2543Smrg      ErrorF ("winInitVisualsShadowDDNL - Unknown screen depth\n");
946706f2543Smrg      return FALSE;
947706f2543Smrg    }
948706f2543Smrg
949706f2543Smrg#if CYGDEBUG
950706f2543Smrg  winDebug ("winInitVisualsShadowDDNL - Returning\n");
951706f2543Smrg#endif
952706f2543Smrg
953706f2543Smrg  return TRUE;
954706f2543Smrg}
955706f2543Smrg
956706f2543Smrg
957706f2543Smrg/*
958706f2543Smrg * Adjust the user proposed video mode
959706f2543Smrg */
960706f2543Smrg
961706f2543Smrgstatic Bool
962706f2543SmrgwinAdjustVideoModeShadowDDNL (ScreenPtr pScreen)
963706f2543Smrg{
964706f2543Smrg  winScreenPriv(pScreen);
965706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
966706f2543Smrg  HDC			hdc = NULL;
967706f2543Smrg  DWORD			dwBPP;
968706f2543Smrg
969706f2543Smrg  /* We're in serious trouble if we can't get a DC */
970706f2543Smrg  hdc = GetDC (NULL);
971706f2543Smrg  if (hdc == NULL)
972706f2543Smrg    {
973706f2543Smrg      ErrorF ("winAdjustVideoModeShadowDDNL - GetDC () failed\n");
974706f2543Smrg      return FALSE;
975706f2543Smrg    }
976706f2543Smrg
977706f2543Smrg  /* Query GDI for current display depth */
978706f2543Smrg  dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
979706f2543Smrg
980706f2543Smrg  /* DirectDraw can only change the depth in fullscreen mode */
981706f2543Smrg  if (!(pScreenInfo->fFullScreen &&
982706f2543Smrg        (pScreenInfo->dwBPP != WIN_DEFAULT_BPP)))
983706f2543Smrg    {
984706f2543Smrg      /* Otherwise, We'll use GDI's depth */
985706f2543Smrg      pScreenInfo->dwBPP = dwBPP;
986706f2543Smrg    }
987706f2543Smrg
988706f2543Smrg  /* Release our DC */
989706f2543Smrg  ReleaseDC (NULL, hdc);
990706f2543Smrg
991706f2543Smrg  return TRUE;
992706f2543Smrg}
993706f2543Smrg
994706f2543Smrg
995706f2543Smrg/*
996706f2543Smrg * Blt exposed regions to the screen
997706f2543Smrg */
998706f2543Smrg
999706f2543Smrgstatic Bool
1000706f2543SmrgwinBltExposedRegionsShadowDDNL (ScreenPtr pScreen)
1001706f2543Smrg{
1002706f2543Smrg  winScreenPriv(pScreen);
1003706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
1004706f2543Smrg  RECT			rcSrc, rcDest;
1005706f2543Smrg  POINT			ptOrigin;
1006706f2543Smrg  HDC			hdcUpdate;
1007706f2543Smrg  PAINTSTRUCT		ps;
1008706f2543Smrg  HRESULT		ddrval = DD_OK;
1009706f2543Smrg  Bool			fReturn = TRUE;
1010706f2543Smrg  int			i;
1011706f2543Smrg
1012706f2543Smrg  /* Quite common case. The primary surface was lost (maybe because of depth
1013706f2543Smrg   * change). Try to create a new primary surface. Bail out if this fails */
1014706f2543Smrg  if (pScreenPriv->pddsPrimary4 == NULL && pScreenPriv->fRetryCreateSurface &&
1015706f2543Smrg      !winCreatePrimarySurfaceShadowDDNL(pScreen))
1016706f2543Smrg    {
1017706f2543Smrg      Sleep(100);
1018706f2543Smrg      return FALSE;
1019706f2543Smrg    }
1020706f2543Smrg  if (pScreenPriv->pddsPrimary4 == NULL)
1021706f2543Smrg    return FALSE;
1022706f2543Smrg
1023706f2543Smrg  /* BeginPaint gives us an hdc that clips to the invalidated region */
1024706f2543Smrg  hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps);
1025706f2543Smrg  if (hdcUpdate == NULL)
1026706f2543Smrg    {
1027706f2543Smrg      fReturn = FALSE;
1028706f2543Smrg      ErrorF ("winBltExposedRegionsShadowDDNL - BeginPaint () returned "
1029706f2543Smrg	      "a NULL device context handle.  Aborting blit attempt.\n");
1030706f2543Smrg      goto winBltExposedRegionsShadowDDNL_Exit;
1031706f2543Smrg    }
1032706f2543Smrg
1033706f2543Smrg  /* Get the origin of the window in the screen coords */
1034706f2543Smrg  ptOrigin.x = pScreenInfo->dwXOffset;
1035706f2543Smrg  ptOrigin.y = pScreenInfo->dwYOffset;
1036706f2543Smrg
1037706f2543Smrg  MapWindowPoints (pScreenPriv->hwndScreen,
1038706f2543Smrg		   HWND_DESKTOP,
1039706f2543Smrg		   (LPPOINT)&ptOrigin, 1);
1040706f2543Smrg  rcDest.left = ptOrigin.x;
1041706f2543Smrg  rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
1042706f2543Smrg  rcDest.top = ptOrigin.y;
1043706f2543Smrg  rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
1044706f2543Smrg
1045706f2543Smrg  /* Source can be entire shadow surface, as Blt should clip for us */
1046706f2543Smrg  rcSrc.left = 0;
1047706f2543Smrg  rcSrc.top = 0;
1048706f2543Smrg  rcSrc.right = pScreenInfo->dwWidth;
1049706f2543Smrg  rcSrc.bottom = pScreenInfo->dwHeight;
1050706f2543Smrg
1051706f2543Smrg  /* Try to regain the primary surface and blit again if we've lost it */
1052706f2543Smrg  for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i)
1053706f2543Smrg    {
1054706f2543Smrg      /* Our Blt should be clipped to the invalidated region */
1055706f2543Smrg      ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4,
1056706f2543Smrg					&rcDest,
1057706f2543Smrg					pScreenPriv->pddsShadow4,
1058706f2543Smrg					&rcSrc,
1059706f2543Smrg					DDBLT_WAIT,
1060706f2543Smrg					NULL);
1061706f2543Smrg      if (ddrval == DDERR_SURFACELOST)
1062706f2543Smrg	{
1063706f2543Smrg	  /* Surface was lost */
1064706f2543Smrg	  winErrorFVerb (1, "winBltExposedRegionsShadowDDNL - "
1065706f2543Smrg          "IDirectDrawSurface4_Blt reported that the primary "
1066706f2543Smrg          "surface was lost, trying to restore, retry: %d\n", i + 1);
1067706f2543Smrg
1068706f2543Smrg	  /* Try to restore the surface, once */
1069706f2543Smrg
1070706f2543Smrg	  ddrval = IDirectDrawSurface4_Restore (pScreenPriv->pddsPrimary4);
1071706f2543Smrg	  winDebug ("winBltExposedRegionsShadowDDNL - "
1072706f2543Smrg		  "IDirectDrawSurface4_Restore returned: ");
1073706f2543Smrg	  if (ddrval == DD_OK)
1074706f2543Smrg	    winDebug ("DD_OK\n");
1075706f2543Smrg	  else if (ddrval == DDERR_WRONGMODE)
1076706f2543Smrg	    winDebug ("DDERR_WRONGMODE\n");
1077706f2543Smrg	  else if (ddrval == DDERR_INCOMPATIBLEPRIMARY)
1078706f2543Smrg	    winDebug ("DDERR_INCOMPATIBLEPRIMARY\n");
1079706f2543Smrg	  else if (ddrval == DDERR_UNSUPPORTED)
1080706f2543Smrg	    winDebug ("DDERR_UNSUPPORTED\n");
1081706f2543Smrg	  else if (ddrval == DDERR_INVALIDPARAMS)
1082706f2543Smrg	    winDebug ("DDERR_INVALIDPARAMS\n");
1083706f2543Smrg	  else if (ddrval == DDERR_INVALIDOBJECT)
1084706f2543Smrg	    winDebug ("DDERR_INVALIDOBJECT\n");
1085706f2543Smrg	  else
1086706f2543Smrg	    winDebug ("unknown error: %08x\n", (unsigned int) ddrval);
1087706f2543Smrg
1088706f2543Smrg	  /* Loop around to try the blit one more time */
1089706f2543Smrg	  continue;
1090706f2543Smrg	}
1091706f2543Smrg      else if (FAILED (ddrval))
1092706f2543Smrg	{
1093706f2543Smrg	  fReturn = FALSE;
1094706f2543Smrg	  winErrorFVerb (1, "winBltExposedRegionsShadowDDNL - "
1095706f2543Smrg		  "IDirectDrawSurface4_Blt failed, but surface not "
1096706f2543Smrg		  "lost: %08x %d\n",
1097706f2543Smrg		  (unsigned int) ddrval, (int) ddrval);
1098706f2543Smrg	  goto winBltExposedRegionsShadowDDNL_Exit;
1099706f2543Smrg	}
1100706f2543Smrg      else
1101706f2543Smrg	{
1102706f2543Smrg	  /* Success, stop looping */
1103706f2543Smrg	  break;
1104706f2543Smrg	}
1105706f2543Smrg    }
1106706f2543Smrg
1107706f2543Smrg winBltExposedRegionsShadowDDNL_Exit:
1108706f2543Smrg  /* EndPaint frees the DC */
1109706f2543Smrg  if (hdcUpdate != NULL)
1110706f2543Smrg    EndPaint (pScreenPriv->hwndScreen, &ps);
1111706f2543Smrg  return fReturn;
1112706f2543Smrg}
1113706f2543Smrg
1114706f2543Smrg
1115706f2543Smrg/*
1116706f2543Smrg * Do any engine-specific application-activation processing
1117706f2543Smrg */
1118706f2543Smrg
1119706f2543Smrgstatic Bool
1120706f2543SmrgwinActivateAppShadowDDNL (ScreenPtr pScreen)
1121706f2543Smrg{
1122706f2543Smrg  winScreenPriv(pScreen);
1123706f2543Smrg
1124706f2543Smrg  /*
1125706f2543Smrg   * Do we have a surface?
1126706f2543Smrg   * Are we active?
1127706f2543Smrg   * Are we full screen?
1128706f2543Smrg   */
1129706f2543Smrg  if (pScreenPriv != NULL
1130706f2543Smrg      && pScreenPriv->pddsPrimary4 != NULL
1131706f2543Smrg      && pScreenPriv->fActive)
1132706f2543Smrg    {
1133706f2543Smrg      /* Primary surface was lost, restore it */
1134706f2543Smrg      IDirectDrawSurface4_Restore (pScreenPriv->pddsPrimary4);
1135706f2543Smrg    }
1136706f2543Smrg
1137706f2543Smrg  return TRUE;
1138706f2543Smrg}
1139706f2543Smrg
1140706f2543Smrg
1141706f2543Smrg/*
1142706f2543Smrg * Reblit the shadow framebuffer to the screen.
1143706f2543Smrg */
1144706f2543Smrg
1145706f2543Smrgstatic Bool
1146706f2543SmrgwinRedrawScreenShadowDDNL (ScreenPtr pScreen)
1147706f2543Smrg{
1148706f2543Smrg  winScreenPriv(pScreen);
1149706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
1150706f2543Smrg  HRESULT		ddrval = DD_OK;
1151706f2543Smrg  RECT			rcSrc, rcDest;
1152706f2543Smrg  POINT			ptOrigin;
1153706f2543Smrg
1154706f2543Smrg  /* Get the origin of the window in the screen coords */
1155706f2543Smrg  ptOrigin.x = pScreenInfo->dwXOffset;
1156706f2543Smrg  ptOrigin.y = pScreenInfo->dwYOffset;
1157706f2543Smrg  MapWindowPoints (pScreenPriv->hwndScreen,
1158706f2543Smrg		   HWND_DESKTOP,
1159706f2543Smrg		   (LPPOINT)&ptOrigin, 1);
1160706f2543Smrg  rcDest.left = ptOrigin.x;
1161706f2543Smrg  rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
1162706f2543Smrg  rcDest.top = ptOrigin.y;
1163706f2543Smrg  rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
1164706f2543Smrg
1165706f2543Smrg  /* Source can be entire shadow surface, as Blt should clip for us */
1166706f2543Smrg  rcSrc.left = 0;
1167706f2543Smrg  rcSrc.top = 0;
1168706f2543Smrg  rcSrc.right = pScreenInfo->dwWidth;
1169706f2543Smrg  rcSrc.bottom = pScreenInfo->dwHeight;
1170706f2543Smrg
1171706f2543Smrg  /* Redraw the whole window, to take account for the new colors */
1172706f2543Smrg  ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4,
1173706f2543Smrg				    &rcDest,
1174706f2543Smrg				    pScreenPriv->pddsShadow4,
1175706f2543Smrg				    &rcSrc,
1176706f2543Smrg				    DDBLT_WAIT,
1177706f2543Smrg				    NULL);
1178706f2543Smrg  if (FAILED (ddrval))
1179706f2543Smrg    {
1180706f2543Smrg      ErrorF ("winRedrawScreenShadowDDNL - IDirectDrawSurface4_Blt () "
1181706f2543Smrg	      "failed: %08x\n",
1182706f2543Smrg	      (unsigned int) ddrval);
1183706f2543Smrg    }
1184706f2543Smrg
1185706f2543Smrg  return TRUE;
1186706f2543Smrg}
1187706f2543Smrg
1188706f2543Smrg
1189706f2543Smrg/*
1190706f2543Smrg * Realize the currently installed colormap
1191706f2543Smrg */
1192706f2543Smrg
1193706f2543Smrgstatic Bool
1194706f2543SmrgwinRealizeInstalledPaletteShadowDDNL (ScreenPtr pScreen)
1195706f2543Smrg{
1196706f2543Smrg  return TRUE;
1197706f2543Smrg}
1198706f2543Smrg
1199706f2543Smrg
1200706f2543Smrg/*
1201706f2543Smrg * Install the specified colormap
1202706f2543Smrg */
1203706f2543Smrg
1204706f2543Smrgstatic Bool
1205706f2543SmrgwinInstallColormapShadowDDNL (ColormapPtr pColormap)
1206706f2543Smrg{
1207706f2543Smrg  ScreenPtr		pScreen = pColormap->pScreen;
1208706f2543Smrg  winScreenPriv(pScreen);
1209706f2543Smrg  winCmapPriv(pColormap);
1210706f2543Smrg  HRESULT		ddrval = DD_OK;
1211706f2543Smrg
1212706f2543Smrg  /* Install the DirectDraw palette on the primary surface */
1213706f2543Smrg  ddrval = IDirectDrawSurface4_SetPalette (pScreenPriv->pddsPrimary4,
1214706f2543Smrg					   pCmapPriv->lpDDPalette);
1215706f2543Smrg  if (FAILED (ddrval))
1216706f2543Smrg    {
1217706f2543Smrg      ErrorF ("winInstallColormapShadowDDNL - Failed installing the "
1218706f2543Smrg	      "DirectDraw palette.\n");
1219706f2543Smrg      return FALSE;
1220706f2543Smrg    }
1221706f2543Smrg
1222706f2543Smrg  /* Save a pointer to the newly installed colormap */
1223706f2543Smrg  pScreenPriv->pcmapInstalled = pColormap;
1224706f2543Smrg
1225706f2543Smrg  return TRUE;
1226706f2543Smrg}
1227706f2543Smrg
1228706f2543Smrg
1229706f2543Smrg/*
1230706f2543Smrg * Store the specified colors in the specified colormap
1231706f2543Smrg */
1232706f2543Smrg
1233706f2543Smrgstatic Bool
1234706f2543SmrgwinStoreColorsShadowDDNL (ColormapPtr pColormap,
1235706f2543Smrg			  int ndef,
1236706f2543Smrg			  xColorItem *pdefs)
1237706f2543Smrg{
1238706f2543Smrg  ScreenPtr		pScreen = pColormap->pScreen;
1239706f2543Smrg  winScreenPriv(pScreen);
1240706f2543Smrg  winCmapPriv(pColormap);
1241706f2543Smrg  ColormapPtr		curpmap = pScreenPriv->pcmapInstalled;
1242706f2543Smrg  HRESULT		ddrval = DD_OK;
1243706f2543Smrg
1244706f2543Smrg  /* Put the X colormap entries into the Windows logical palette */
1245706f2543Smrg  ddrval = IDirectDrawPalette_SetEntries (pCmapPriv->lpDDPalette,
1246706f2543Smrg					  0,
1247706f2543Smrg					  pdefs[0].pixel,
1248706f2543Smrg					  ndef,
1249706f2543Smrg					  pCmapPriv->peColors
1250706f2543Smrg					  + pdefs[0].pixel);
1251706f2543Smrg  if (FAILED (ddrval))
1252706f2543Smrg    {
1253706f2543Smrg      ErrorF ("winStoreColorsShadowDDNL - SetEntries () failed: %08x\n", (unsigned int) ddrval);
1254706f2543Smrg      return FALSE;
1255706f2543Smrg    }
1256706f2543Smrg
1257706f2543Smrg  /* Don't install the DirectDraw palette if the colormap is not installed */
1258706f2543Smrg  if (pColormap != curpmap)
1259706f2543Smrg    {
1260706f2543Smrg      return TRUE;
1261706f2543Smrg    }
1262706f2543Smrg
1263706f2543Smrg  if (!winInstallColormapShadowDDNL (pColormap))
1264706f2543Smrg    {
1265706f2543Smrg      ErrorF ("winStoreColorsShadowDDNL - Failed installing colormap\n");
1266706f2543Smrg      return FALSE;
1267706f2543Smrg    }
1268706f2543Smrg
1269706f2543Smrg  return TRUE;
1270706f2543Smrg}
1271706f2543Smrg
1272706f2543Smrg
1273706f2543Smrg/*
1274706f2543Smrg * Colormap initialization procedure
1275706f2543Smrg */
1276706f2543Smrg
1277706f2543Smrgstatic Bool
1278706f2543SmrgwinCreateColormapShadowDDNL (ColormapPtr pColormap)
1279706f2543Smrg{
1280706f2543Smrg  HRESULT		ddrval = DD_OK;
1281706f2543Smrg  ScreenPtr		pScreen = pColormap->pScreen;
1282706f2543Smrg  winScreenPriv(pScreen);
1283706f2543Smrg  winCmapPriv(pColormap);
1284706f2543Smrg
1285706f2543Smrg  /* Create a DirectDraw palette */
1286706f2543Smrg  ddrval = IDirectDraw4_CreatePalette (pScreenPriv->pdd4,
1287706f2543Smrg				       DDPCAPS_8BIT | DDPCAPS_ALLOW256,
1288706f2543Smrg				       pCmapPriv->peColors,
1289706f2543Smrg				       &pCmapPriv->lpDDPalette,
1290706f2543Smrg				       NULL);
1291706f2543Smrg  if (FAILED (ddrval))
1292706f2543Smrg    {
1293706f2543Smrg      ErrorF ("winCreateColormapShadowDDNL - CreatePalette failed\n");
1294706f2543Smrg      return FALSE;
1295706f2543Smrg    }
1296706f2543Smrg
1297706f2543Smrg  return TRUE;
1298706f2543Smrg}
1299706f2543Smrg
1300706f2543Smrg
1301706f2543Smrg/*
1302706f2543Smrg * Colormap destruction procedure
1303706f2543Smrg */
1304706f2543Smrg
1305706f2543Smrgstatic Bool
1306706f2543SmrgwinDestroyColormapShadowDDNL (ColormapPtr pColormap)
1307706f2543Smrg{
1308706f2543Smrg  winScreenPriv(pColormap->pScreen);
1309706f2543Smrg  winCmapPriv(pColormap);
1310706f2543Smrg  HRESULT		ddrval = DD_OK;
1311706f2543Smrg
1312706f2543Smrg  /*
1313706f2543Smrg   * Is colormap to be destroyed the default?
1314706f2543Smrg   *
1315706f2543Smrg   * Non-default colormaps should have had winUninstallColormap
1316706f2543Smrg   * called on them before we get here.  The default colormap
1317706f2543Smrg   * will not have had winUninstallColormap called on it.  Thus,
1318706f2543Smrg   * we need to handle the default colormap in a special way.
1319706f2543Smrg   */
1320706f2543Smrg  if (pColormap->flags & IsDefault)
1321706f2543Smrg    {
1322706f2543Smrg#if CYGDEBUG
1323706f2543Smrg      winDebug ("winDestroyColormapShadowDDNL - Destroying default colormap\n");
1324706f2543Smrg#endif
1325706f2543Smrg
1326706f2543Smrg      /*
1327706f2543Smrg       * FIXME: Walk the list of all screens, popping the default
1328706f2543Smrg       * palette out of each screen device context.
1329706f2543Smrg       */
1330706f2543Smrg
1331706f2543Smrg      /* Pop the palette out of the primary surface */
1332706f2543Smrg      ddrval = IDirectDrawSurface4_SetPalette (pScreenPriv->pddsPrimary4,
1333706f2543Smrg					       NULL);
1334706f2543Smrg      if (FAILED (ddrval))
1335706f2543Smrg	{
1336706f2543Smrg	  ErrorF ("winDestroyColormapShadowDDNL - Failed freeing the "
1337706f2543Smrg		  "default colormap DirectDraw palette.\n");
1338706f2543Smrg	  return FALSE;
1339706f2543Smrg	}
1340706f2543Smrg
1341706f2543Smrg      /* Clear our private installed colormap pointer */
1342706f2543Smrg      pScreenPriv->pcmapInstalled = NULL;
1343706f2543Smrg    }
1344706f2543Smrg
1345706f2543Smrg  /* Release the palette */
1346706f2543Smrg  IDirectDrawPalette_Release (pCmapPriv->lpDDPalette);
1347706f2543Smrg
1348706f2543Smrg  /* Invalidate the colormap privates */
1349706f2543Smrg  pCmapPriv->lpDDPalette = NULL;
1350706f2543Smrg
1351706f2543Smrg  return TRUE;
1352706f2543Smrg}
1353706f2543Smrg
1354706f2543Smrg
1355706f2543Smrg/*
1356706f2543Smrg * Set pointers to our engine specific functions
1357706f2543Smrg */
1358706f2543Smrg
1359706f2543SmrgBool
1360706f2543SmrgwinSetEngineFunctionsShadowDDNL (ScreenPtr pScreen)
1361706f2543Smrg{
1362706f2543Smrg  winScreenPriv(pScreen);
1363706f2543Smrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
1364706f2543Smrg
1365706f2543Smrg  /* Set our pointers */
1366706f2543Smrg  pScreenPriv->pwinAllocateFB = winAllocateFBShadowDDNL;
1367706f2543Smrg  pScreenPriv->pwinFreeFB = winFreeFBShadowDDNL;
1368706f2543Smrg  pScreenPriv->pwinShadowUpdate = winShadowUpdateDDNL;
1369706f2543Smrg  pScreenPriv->pwinInitScreen = winInitScreenShadowDDNL;
1370706f2543Smrg  pScreenPriv->pwinCloseScreen = winCloseScreenShadowDDNL;
1371706f2543Smrg  pScreenPriv->pwinInitVisuals = winInitVisualsShadowDDNL;
1372706f2543Smrg  pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDDNL;
1373706f2543Smrg  if (pScreenInfo->fFullScreen)
1374706f2543Smrg    pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen;
1375706f2543Smrg  else
1376706f2543Smrg    pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
1377706f2543Smrg  pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
1378706f2543Smrg  pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDDNL;
1379706f2543Smrg  pScreenPriv->pwinActivateApp = winActivateAppShadowDDNL;
1380706f2543Smrg  pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDDNL;
1381706f2543Smrg  pScreenPriv->pwinRealizeInstalledPalette
1382706f2543Smrg    = winRealizeInstalledPaletteShadowDDNL;
1383706f2543Smrg  pScreenPriv->pwinInstallColormap = winInstallColormapShadowDDNL;
1384706f2543Smrg  pScreenPriv->pwinStoreColors = winStoreColorsShadowDDNL;
1385706f2543Smrg  pScreenPriv->pwinCreateColormap = winCreateColormapShadowDDNL;
1386706f2543Smrg  pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDDNL;
1387706f2543Smrg  pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA;
1388706f2543Smrg  pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDDNL;
1389706f2543Smrg  pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDDNL;
1390706f2543Smrg#ifdef XWIN_MULTIWINDOW
1391706f2543Smrg  pScreenPriv->pwinFinishCreateWindowsWindow
1392706f2543Smrg    = winFinishCreateWindowsWindowDDNL;
1393706f2543Smrg#endif
1394706f2543Smrg
1395706f2543Smrg  return TRUE;
1396706f2543Smrg}
1397