winshadddnl.c revision 706f2543
1/*
2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3 *
4 *Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 *"Software"), to deal in the Software without restriction, including
7 *without limitation the rights to use, copy, modify, merge, publish,
8 *distribute, sublicense, and/or sell copies of the Software, and to
9 *permit persons to whom the Software is furnished to do so, subject to
10 *the following conditions:
11 *
12 *The above copyright notice and this permission notice shall be
13 *included in all copies or substantial portions of the Software.
14 *
15 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
19 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 *Except as contained in this notice, the name of the XFree86 Project
24 *shall not be used in advertising or otherwise to promote the sale, use
25 *or other dealings in this Software without prior written authorization
26 *from the XFree86 Project.
27 *
28 * Authors:	Dakshinamurthy Karra
29 *		Suhaib M Siddiqi
30 *		Peter Busch
31 *		Harold L Hunt II
32 */
33
34#ifdef HAVE_XWIN_CONFIG_H
35#include <xwin-config.h>
36#endif
37#include "win.h"
38
39
40/*
41 * FIXME: Headers are broken, DEFINE_GUID doesn't work correctly,
42 * so we have to redefine it here.
43 */
44#ifdef DEFINE_GUID
45#undef DEFINE_GUID
46#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}}
47#endif /* DEFINE_GUID */
48
49/*
50 * FIXME: Headers are broken, IID_IDirectDraw4 has to be defined
51 * here manually.  Should be handled by ddraw.h
52 */
53#ifndef IID_IDirectDraw4
54DEFINE_GUID( IID_IDirectDraw4, 0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 );
55#endif /* IID_IDirectDraw4 */
56
57#define FAIL_MSG_MAX_BLT	10
58
59
60/*
61 * Local prototypes
62 */
63
64static Bool
65winAllocateFBShadowDDNL (ScreenPtr pScreen);
66
67static void
68winShadowUpdateDDNL (ScreenPtr pScreen,
69		     shadowBufPtr pBuf);
70
71static Bool
72winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen);
73
74static Bool
75winInitVisualsShadowDDNL (ScreenPtr pScreen);
76
77static Bool
78winAdjustVideoModeShadowDDNL (ScreenPtr pScreen);
79
80static Bool
81winBltExposedRegionsShadowDDNL (ScreenPtr pScreen);
82
83static Bool
84winActivateAppShadowDDNL (ScreenPtr pScreen);
85
86static Bool
87winRedrawScreenShadowDDNL (ScreenPtr pScreen);
88
89static Bool
90winRealizeInstalledPaletteShadowDDNL (ScreenPtr pScreen);
91
92static Bool
93winInstallColormapShadowDDNL (ColormapPtr pColormap);
94
95static Bool
96winStoreColorsShadowDDNL (ColormapPtr pmap,
97			  int ndef,
98			  xColorItem *pdefs);
99
100static Bool
101winCreateColormapShadowDDNL (ColormapPtr pColormap);
102
103static Bool
104winDestroyColormapShadowDDNL (ColormapPtr pColormap);
105
106static Bool
107winCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen);
108
109static Bool
110winReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen);
111
112
113/*
114 * Create the primary surface and attach the clipper.
115 * Used for both the initial surface creation and during
116 * WM_DISPLAYCHANGE messages.
117 */
118
119static Bool
120winCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen)
121{
122  winScreenPriv(pScreen);
123  HRESULT		ddrval = DD_OK;
124  DDSURFACEDESC2	ddsd;
125
126  winDebug ("winCreatePrimarySurfaceShadowDDNL - Creating primary surface\n");
127
128  /* Describe the primary surface */
129  ZeroMemory (&ddsd, sizeof (ddsd));
130  ddsd.dwSize = sizeof (ddsd);
131  ddsd.dwFlags = DDSD_CAPS;
132  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
133
134  /* Create the primary surface */
135  ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4,
136				       &ddsd,
137				       &pScreenPriv->pddsPrimary4,
138				       NULL);
139  pScreenPriv->fRetryCreateSurface = FALSE;
140  if (FAILED (ddrval))
141    {
142      if (ddrval == DDERR_NOEXCLUSIVEMODE)
143        {
144          /* Recreating the surface failed. Mark screen to retry later */
145          pScreenPriv->fRetryCreateSurface = TRUE;
146          winDebug ("winCreatePrimarySurfaceShadowDDNL - Could not create "
147	          "primary surface: DDERR_NOEXCLUSIVEMODE\n");
148        }
149      else
150        {
151          ErrorF ("winCreatePrimarySurfaceShadowDDNL - Could not create "
152	          "primary surface: %08x\n", (unsigned int) ddrval);
153        }
154      return FALSE;
155    }
156
157#if 1
158  winDebug ("winCreatePrimarySurfaceShadowDDNL - Created primary surface\n");
159#endif
160
161  /* Attach our clipper to our primary surface handle */
162  ddrval = IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4,
163					   pScreenPriv->pddcPrimary);
164  if (FAILED (ddrval))
165    {
166      ErrorF ("winCreatePrimarySurfaceShadowDDNL - Primary attach clipper "
167	      "failed: %08x\n",
168	      (unsigned int) ddrval);
169      return FALSE;
170    }
171
172#if 1
173  winDebug ("winCreatePrimarySurfaceShadowDDNL - Attached clipper to primary "
174	  "surface\n");
175#endif
176
177  /* Everything was correct */
178  return TRUE;
179}
180
181
182/*
183 * Detach the clipper and release the primary surface.
184 * Called from WM_DISPLAYCHANGE.
185 */
186
187static Bool
188winReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen)
189{
190  winScreenPriv(pScreen);
191
192  winDebug ("winReleasePrimarySurfaceShadowDDNL - Hello\n");
193
194  /* Release the primary surface and clipper, if they exist */
195  if (pScreenPriv->pddsPrimary4)
196    {
197      /*
198       * Detach the clipper from the primary surface.
199       * NOTE: We do this explicity for clarity.  The Clipper is not released.
200       */
201      IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4,
202				      NULL);
203
204      winDebug ("winReleasePrimarySurfaceShadowDDNL - Detached clipper\n");
205
206      /* Release the primary surface */
207      IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4);
208      pScreenPriv->pddsPrimary4 = NULL;
209    }
210
211  winDebug ("winReleasePrimarySurfaceShadowDDNL - Released primary surface\n");
212
213  return TRUE;
214}
215
216
217/*
218 * Create a DirectDraw surface for the shadow framebuffer; also create
219 * a primary surface object so we can blit to the display.
220 *
221 * Install a DirectDraw clipper on our primary surface object
222 * that clips our blits to the unobscured client area of our display window.
223 */
224
225Bool
226winAllocateFBShadowDDNL (ScreenPtr pScreen)
227{
228  winScreenPriv(pScreen);
229  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
230  HRESULT		ddrval = DD_OK;
231  DDSURFACEDESC2	ddsdShadow;
232  char			*lpSurface = NULL;
233  DDPIXELFORMAT		ddpfPrimary;
234
235#if CYGDEBUG
236  winDebug ("winAllocateFBShadowDDNL - w %d h %d d %d\n",
237	  pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwDepth);
238#endif
239
240  /* Set the padded screen width */
241  pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth,
242					      pScreenInfo->dwBPP);
243
244  /* Allocate memory for our shadow surface */
245  lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight);
246  if (lpSurface == NULL)
247    {
248      ErrorF ("winAllocateFBShadowDDNL - Could not allocate bits\n");
249      return FALSE;
250    }
251
252  /*
253   * Initialize the framebuffer memory so we don't get a
254   * strange display at startup
255   */
256  ZeroMemory (lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight);
257
258  /* Create a clipper */
259  ddrval = (*g_fpDirectDrawCreateClipper) (0,
260					   &pScreenPriv->pddcPrimary,
261					   NULL);
262  if (FAILED (ddrval))
263    {
264      ErrorF ("winAllocateFBShadowDDNL - Could not attach clipper: %08x\n",
265	      (unsigned int) ddrval);
266      return FALSE;
267    }
268
269#if CYGDEBUG
270  winDebug ("winAllocateFBShadowDDNL - Created a clipper\n");
271#endif
272
273  /* Attach the clipper to our display window */
274  ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary,
275				       0,
276				       pScreenPriv->hwndScreen);
277  if (FAILED (ddrval))
278    {
279      ErrorF ("winAllocateFBShadowDDNL - Clipper not attached "
280	      "to window: %08x\n",
281	      (unsigned int) ddrval);
282      return FALSE;
283    }
284
285#if CYGDEBUG
286  winDebug ("winAllocateFBShadowDDNL - Attached clipper to window\n");
287#endif
288
289  /* Create a DirectDraw object, store the address at lpdd */
290  ddrval = (*g_fpDirectDrawCreate) (NULL,
291				    (LPDIRECTDRAW*) &pScreenPriv->pdd,
292				    NULL);
293  if (FAILED (ddrval))
294    {
295      ErrorF ("winAllocateFBShadowDDNL - Could not start "
296	      "DirectDraw: %08x\n",
297	      (unsigned int) ddrval);
298      return FALSE;
299    }
300
301#if CYGDEBUG
302  winDebug ("winAllocateFBShadowDDNL - Created and initialized DD\n");
303#endif
304
305  /* Get a DirectDraw4 interface pointer */
306  ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd,
307				       &IID_IDirectDraw4,
308				       (LPVOID*) &pScreenPriv->pdd4);
309  if (FAILED (ddrval))
310    {
311      ErrorF ("winAllocateFBShadowDDNL - Failed DD4 query: %08x\n",
312	      (unsigned int) ddrval);
313      return FALSE;
314    }
315
316  /* Are we full screen? */
317  if (pScreenInfo->fFullScreen)
318    {
319      DDSURFACEDESC2	ddsdCurrent;
320      DWORD		dwRefreshRateCurrent = 0;
321      HDC		hdc = NULL;
322
323      /* Set the cooperative level to full screen */
324      ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4,
325						 pScreenPriv->hwndScreen,
326						 DDSCL_EXCLUSIVE
327						 | DDSCL_FULLSCREEN);
328      if (FAILED (ddrval))
329	{
330	  ErrorF ("winAllocateFBShadowDDNL - Could not set "
331		  "cooperative level: %08x\n",
332		  (unsigned int) ddrval);
333	  return FALSE;
334	}
335
336      /*
337       * We only need to get the current refresh rate for comparison
338       * if a refresh rate has been passed on the command line.
339       */
340      if (pScreenInfo->dwRefreshRate != 0)
341	{
342	  ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent));
343	  ddsdCurrent.dwSize = sizeof (ddsdCurrent);
344
345	  /* Get information about current display settings */
346	  ddrval = IDirectDraw4_GetDisplayMode (pScreenPriv->pdd4,
347						&ddsdCurrent);
348	  if (FAILED (ddrval))
349	    {
350	      ErrorF ("winAllocateFBShadowDDNL - Could not get current "
351		      "refresh rate: %08x.  Continuing.\n",
352		      (unsigned int) ddrval);
353	      dwRefreshRateCurrent = 0;
354	    }
355	  else
356	    {
357	      /* Grab the current refresh rate */
358	      dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate;
359	    }
360	}
361
362      /* Clean up the refresh rate */
363      if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate)
364	{
365	  /*
366	   * Refresh rate is non-specified or equal to current.
367	   */
368	  pScreenInfo->dwRefreshRate = 0;
369	}
370
371      /* Grab a device context for the screen */
372      hdc = GetDC (NULL);
373      if (hdc == NULL)
374	{
375	  ErrorF ("winAllocateFBShadowDDNL - GetDC () failed\n");
376	  return FALSE;
377	}
378
379      /* Only change the video mode when different than current mode */
380      if (!pScreenInfo->fMultipleMonitors
381	  && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN)
382	      || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN)
383	      || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL)
384	      || pScreenInfo->dwRefreshRate != 0))
385	{
386	  winDebug ("winAllocateFBShadowDDNL - Changing video mode\n");
387
388	  /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */
389	  ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4,
390						pScreenInfo->dwWidth,
391						pScreenInfo->dwHeight,
392						pScreenInfo->dwBPP,
393						pScreenInfo->dwRefreshRate,
394						0);
395	  if (FAILED (ddrval))
396	    {
397	      ErrorF ("winAllocateFBShadowDDNL - Could not set "
398		      "full screen display mode: %08x\n",
399		      (unsigned int) ddrval);
400	      ErrorF ("winAllocateFBShadowDDNL - Using default driver refresh rate\n");
401	      ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4,
402						    pScreenInfo->dwWidth,
403						    pScreenInfo->dwHeight,
404						    pScreenInfo->dwBPP,
405						    0,
406						    0);
407	      if (FAILED(ddrval))
408		{
409			ErrorF ("winAllocateFBShadowDDNL - Could not set default refresh rate "
410				"full screen display mode: %08x\n",
411				(unsigned int) ddrval);
412			return FALSE;
413		}
414	    }
415	}
416      else
417	{
418	  winDebug ("winAllocateFBShadowDDNL - Not changing video mode\n");
419	}
420
421      /* Release our DC */
422      ReleaseDC (NULL, hdc);
423      hdc = NULL;
424    }
425  else
426    {
427      /* Set the cooperative level for windowed mode */
428      ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4,
429						 pScreenPriv->hwndScreen,
430						 DDSCL_NORMAL);
431      if (FAILED (ddrval))
432	{
433	  ErrorF ("winAllocateFBShadowDDNL - Could not set "
434		  "cooperative level: %08x\n",
435		  (unsigned int) ddrval);
436	  return FALSE;
437	}
438    }
439
440  /* Create the primary surface */
441  if (!winCreatePrimarySurfaceShadowDDNL (pScreen))
442    {
443      ErrorF ("winAllocateFBShadowDDNL - winCreatePrimarySurfaceShadowDDNL "
444	      "failed\n");
445      return FALSE;
446    }
447
448  /* Get primary surface's pixel format */
449  ZeroMemory (&ddpfPrimary, sizeof (ddpfPrimary));
450  ddpfPrimary.dwSize = sizeof (ddpfPrimary);
451  ddrval = IDirectDrawSurface4_GetPixelFormat (pScreenPriv->pddsPrimary4,
452					       &ddpfPrimary);
453  if (FAILED (ddrval))
454    {
455      ErrorF ("winAllocateFBShadowDDNL - Could not get primary "
456	      "pixformat: %08x\n",
457	      (unsigned int) ddrval);
458      return FALSE;
459    }
460
461#if CYGDEBUG
462  winDebug ("winAllocateFBShadowDDNL - Primary masks: %08x %08x %08x "
463	  "dwRGBBitCount: %d\n",
464	  ddpfPrimary.u2.dwRBitMask,
465	  ddpfPrimary.u3.dwGBitMask,
466	  ddpfPrimary.u4.dwBBitMask,
467	  ddpfPrimary.u1.dwRGBBitCount);
468#endif
469
470  /* Describe the shadow surface to be created */
471  /*
472   * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface,
473   * as drawing, locking, and unlocking take forever
474   * with video memory surfaces.  In addition,
475   * video memory is a somewhat scarce resource,
476   * so you shouldn't be allocating video memory when
477   * you have the option of using system memory instead.
478   */
479  ZeroMemory (&ddsdShadow, sizeof (ddsdShadow));
480  ddsdShadow.dwSize = sizeof (ddsdShadow);
481  ddsdShadow.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH
482    | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT;
483  ddsdShadow.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
484  ddsdShadow.dwHeight = pScreenInfo->dwHeight;
485  ddsdShadow.dwWidth = pScreenInfo->dwWidth;
486  ddsdShadow.u1.lPitch = pScreenInfo->dwPaddedWidth;
487  ddsdShadow.lpSurface = lpSurface;
488  ddsdShadow.u4.ddpfPixelFormat = ddpfPrimary;
489
490  winDebug ("winAllocateFBShadowDDNL - lPitch: %d\n",
491	  (int) pScreenInfo->dwPaddedWidth);
492
493  /* Create the shadow surface */
494  ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4,
495				       &ddsdShadow,
496				       &pScreenPriv->pddsShadow4,
497				       NULL);
498  if (FAILED (ddrval))
499    {
500      ErrorF ("winAllocateFBShadowDDNL - Could not create shadow "
501	      "surface: %08x\n", (unsigned int) ddrval);
502      return FALSE;
503    }
504
505#if CYGDEBUG || YES
506  winDebug ("winAllocateFBShadowDDNL - Created shadow pitch: %d\n",
507	  (int) ddsdShadow.u1.lPitch);
508#endif
509
510  /* Grab the pitch from the surface desc */
511  pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8)
512    / pScreenInfo->dwBPP;
513
514#if CYGDEBUG || YES
515  winDebug ("winAllocateFBShadowDDNL - Created shadow stride: %d\n",
516	  (int) pScreenInfo->dwStride);
517#endif
518
519  /* Save the pointer to our surface memory */
520  pScreenInfo->pfb = lpSurface;
521
522  /* Grab the masks from the surface description */
523  pScreenPriv->dwRedMask = ddsdShadow.u4.ddpfPixelFormat.u2.dwRBitMask;
524  pScreenPriv->dwGreenMask = ddsdShadow.u4.ddpfPixelFormat.u3.dwGBitMask;
525  pScreenPriv->dwBlueMask = ddsdShadow.u4.ddpfPixelFormat.u4.dwBBitMask;
526
527#if CYGDEBUG
528  winDebug ("winAllocateFBShadowDDNL - Returning\n");
529#endif
530
531  return TRUE;
532}
533
534static void
535winFreeFBShadowDDNL(ScreenPtr pScreen)
536{
537  winScreenPriv(pScreen);
538  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
539
540  /* Free the shadow surface, if there is one */
541  if (pScreenPriv->pddsShadow4)
542    {
543      IDirectDrawSurface4_Release (pScreenPriv->pddsShadow4);
544      free (pScreenInfo->pfb);
545      pScreenInfo->pfb = NULL;
546      pScreenPriv->pddsShadow4 = NULL;
547    }
548
549  /* Detach the clipper from the primary surface and release the primary surface, if there is one */
550  winReleasePrimarySurfaceShadowDDNL(pScreen);
551
552  /* Release the clipper object */
553  if (pScreenPriv->pddcPrimary)
554    {
555      IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
556      pScreenPriv->pddcPrimary = NULL;
557    }
558
559  /* Free the DirectDraw4 object, if there is one */
560  if (pScreenPriv->pdd4)
561    {
562      IDirectDraw4_RestoreDisplayMode (pScreenPriv->pdd4);
563      IDirectDraw4_Release (pScreenPriv->pdd4);
564      pScreenPriv->pdd4 = NULL;
565    }
566
567  /* Free the DirectDraw object, if there is one */
568  if (pScreenPriv->pdd)
569    {
570      IDirectDraw_Release (pScreenPriv->pdd);
571      pScreenPriv->pdd = NULL;
572    }
573
574  /* Invalidate the ScreenInfo's fb pointer */
575  pScreenInfo->pfb = NULL;
576}
577
578#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
579/*
580 * Create a DirectDraw surface for the new multi-window window
581 */
582
583static
584Bool
585winFinishCreateWindowsWindowDDNL (WindowPtr pWin)
586{
587  winWindowPriv(pWin);
588  winPrivScreenPtr	pScreenPriv = pWinPriv->pScreenPriv;
589  HRESULT		ddrval = DD_OK;
590  DDSURFACEDESC2	ddsd;
591  int			iWidth, iHeight;
592  int			iX, iY;
593
594  winDebug ("winFinishCreateWindowsWindowDDNL!\n\n");
595
596  iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
597  iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
598
599  iWidth = pWin->drawable.width;
600  iHeight = pWin->drawable.height;
601
602  /* Describe the primary surface */
603  ZeroMemory (&ddsd, sizeof (ddsd));
604  ddsd.dwSize = sizeof (ddsd);
605  ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
606  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
607  ddsd.dwHeight = iHeight;
608  ddsd.dwWidth = iWidth;
609
610  /* Create the primary surface */
611  ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4,
612				       &ddsd,
613				       &pWinPriv->pddsPrimary4,
614				       NULL);
615  if (FAILED (ddrval))
616    {
617      ErrorF ("winFinishCreateWindowsWindowDDNL - Could not create primary "
618	      "surface: %08x\n",
619	      (unsigned int)ddrval);
620      return FALSE;
621    }
622  return TRUE;
623}
624#endif
625
626
627/*
628 * Transfer the damaged regions of the shadow framebuffer to the display.
629 */
630
631static void
632winShadowUpdateDDNL (ScreenPtr pScreen,
633		     shadowBufPtr pBuf)
634{
635  winScreenPriv(pScreen);
636  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
637  RegionPtr		damage = shadowDamage(pBuf);
638  HRESULT		ddrval = DD_OK;
639  RECT			rcDest, rcSrc;
640  POINT			ptOrigin;
641  DWORD			dwBox = RegionNumRects (damage);
642  BoxPtr		pBox = RegionRects (damage);
643  HRGN			hrgnTemp = NULL, hrgnCombined = NULL;
644
645  /*
646   * Return immediately if the app is not active
647   * and we are fullscreen, or if we have a bad display depth
648   */
649  if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
650      || pScreenPriv->fBadDepth) return;
651
652  /* Return immediately if we didn't get needed surfaces */
653  if (!pScreenPriv->pddsPrimary4 || !pScreenPriv->pddsShadow4)
654    return;
655
656  /* Get the origin of the window in the screen coords */
657  ptOrigin.x = pScreenInfo->dwXOffset;
658  ptOrigin.y = pScreenInfo->dwYOffset;
659  MapWindowPoints (pScreenPriv->hwndScreen,
660		   HWND_DESKTOP,
661		   (LPPOINT)&ptOrigin, 1);
662
663  /*
664   * Handle small regions with multiple blits,
665   * handle large regions by creating a clipping region and
666   * doing a single blit constrained to that clipping region.
667   */
668  if (pScreenInfo->dwClipUpdatesNBoxes == 0
669      || dwBox < pScreenInfo->dwClipUpdatesNBoxes)
670    {
671      /* Loop through all boxes in the damaged region */
672      while (dwBox--)
673	{
674	  /* Assign damage box to source rectangle */
675	  rcSrc.left = pBox->x1;
676	  rcSrc.top = pBox->y1;
677	  rcSrc.right = pBox->x2;
678	  rcSrc.bottom = pBox->y2;
679
680	  /* Calculate destination rectangle */
681	  rcDest.left = ptOrigin.x + rcSrc.left;
682	  rcDest.top = ptOrigin.y + rcSrc.top;
683	  rcDest.right = ptOrigin.x + rcSrc.right;
684	  rcDest.bottom = ptOrigin.y + rcSrc.bottom;
685
686	  /* Blit the damaged areas */
687	  ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4,
688					    &rcDest,
689					    pScreenPriv->pddsShadow4,
690					    &rcSrc,
691					    DDBLT_WAIT,
692					    NULL);
693	  if (FAILED (ddrval))
694	    {
695	      static int	s_iFailCount = 0;
696
697	      if (s_iFailCount < FAIL_MSG_MAX_BLT)
698		{
699		  ErrorF ("winShadowUpdateDDNL - IDirectDrawSurface4_Blt () "
700			  "failed: %08x\n",
701			  (unsigned int) ddrval);
702
703		  ++s_iFailCount;
704
705		  if (s_iFailCount == FAIL_MSG_MAX_BLT)
706		    {
707		      ErrorF ("winShadowUpdateDDNL - IDirectDrawSurface4_Blt "
708			      "failure message maximum (%d) reached.  No "
709			      "more failure messages will be printed.\n",
710			      FAIL_MSG_MAX_BLT);
711		    }
712		}
713	    }
714
715	  /* Get a pointer to the next box */
716	  ++pBox;
717	}
718    }
719  else
720    {
721      BoxPtr		pBoxExtents = RegionExtents(damage);
722
723      /* Compute a GDI region from the damaged region */
724      hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
725      dwBox--;
726      pBox++;
727      while (dwBox--)
728	{
729	  hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
730	  CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
731	  DeleteObject (hrgnTemp);
732	  pBox++;
733	}
734
735      /* Install the GDI region as a clipping region */
736      SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined);
737      DeleteObject (hrgnCombined);
738      hrgnCombined = NULL;
739
740#if CYGDEBUG
741      winDebug ("winShadowUpdateDDNL - be x1 %d y1 %d x2 %d y2 %d\n",
742	      pBoxExtents->x1, pBoxExtents->y1,
743	      pBoxExtents->x2, pBoxExtents->y2);
744#endif
745
746      /* Calculating a bounding box for the source is easy */
747      rcSrc.left = pBoxExtents->x1;
748      rcSrc.top = pBoxExtents->y1;
749      rcSrc.right = pBoxExtents->x2;
750      rcSrc.bottom = pBoxExtents->y2;
751
752      /* Calculating a bounding box for the destination is trickier */
753      rcDest.left = ptOrigin.x + rcSrc.left;
754      rcDest.top = ptOrigin.y + rcSrc.top;
755      rcDest.right = ptOrigin.x + rcSrc.right;
756      rcDest.bottom = ptOrigin.y + rcSrc.bottom;
757
758      /* Our Blt should be clipped to the invalidated region */
759      ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4,
760					&rcDest,
761					pScreenPriv->pddsShadow4,
762					&rcSrc,
763					DDBLT_WAIT,
764					NULL);
765
766      /* Reset the clip region */
767      SelectClipRgn (pScreenPriv->hdcScreen, NULL);
768    }
769}
770
771static Bool
772winInitScreenShadowDDNL(ScreenPtr pScreen)
773{
774  winScreenPriv(pScreen);
775
776  /* Get a device context for the screen  */
777  pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
778
779  return winAllocateFBShadowDDNL(pScreen);
780}
781
782/*
783 * Call the wrapped CloseScreen function.
784 *
785 * Free our resources and private structures.
786 */
787
788static Bool
789winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen)
790{
791  winScreenPriv(pScreen);
792  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
793  Bool			fReturn;
794
795#if CYGDEBUG
796  winDebug ("winCloseScreenShadowDDNL - Freeing screen resources\n");
797#endif
798
799  /* Flag that the screen is closed */
800  pScreenPriv->fClosed = TRUE;
801  pScreenPriv->fActive = FALSE;
802
803  /* Call the wrapped CloseScreen procedure */
804  WIN_UNWRAP(CloseScreen);
805  fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);
806
807  winFreeFBShadowDDNL(pScreen);
808
809  /* Free the screen DC */
810  ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
811
812  /* Delete the window property */
813  RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
814
815  /* Delete tray icon, if we have one */
816  if (!pScreenInfo->fNoTrayIcon)
817    winDeleteNotifyIcon (pScreenPriv);
818
819  /* Free the exit confirmation dialog box, if it exists */
820  if (g_hDlgExit != NULL)
821    {
822      DestroyWindow (g_hDlgExit);
823      g_hDlgExit = NULL;
824    }
825
826  /* Kill our window */
827  if (pScreenPriv->hwndScreen)
828    {
829      DestroyWindow (pScreenPriv->hwndScreen);
830      pScreenPriv->hwndScreen = NULL;
831    }
832
833#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
834  /* Destroy the thread startup mutex */
835  pthread_mutex_destroy (&pScreenPriv->pmServerStarted);
836#endif
837
838  /* Kill our screeninfo's pointer to the screen */
839  pScreenInfo->pScreen = NULL;
840
841  /* Free the screen privates for this screen */
842  free ((pointer) pScreenPriv);
843
844  return fReturn;
845}
846
847
848/*
849 * Tell mi what sort of visuals we need.
850 *
851 * Generally we only need one visual, as our screen can only
852 * handle one format at a time, I believe.  You may want
853 * to verify that last sentence.
854 */
855
856static Bool
857winInitVisualsShadowDDNL (ScreenPtr pScreen)
858{
859  winScreenPriv(pScreen);
860  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
861  DWORD			dwRedBits, dwGreenBits, dwBlueBits;
862
863  /* Count the number of ones in each color mask */
864  dwRedBits = winCountBits (pScreenPriv->dwRedMask);
865  dwGreenBits = winCountBits (pScreenPriv->dwGreenMask);
866  dwBlueBits = winCountBits (pScreenPriv->dwBlueMask);
867
868  /* Store the maximum number of ones in a color mask as the bitsPerRGB */
869  if (dwRedBits == 0 || dwGreenBits == 0 || dwBlueBits == 0)
870    pScreenPriv->dwBitsPerRGB = 8;
871  else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
872    pScreenPriv->dwBitsPerRGB = dwRedBits;
873  else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
874    pScreenPriv->dwBitsPerRGB = dwGreenBits;
875  else
876    pScreenPriv->dwBitsPerRGB = dwBlueBits;
877
878  winDebug ("winInitVisualsShadowDDNL - Masks %08x %08x %08x BPRGB %d d %d "
879	  "bpp %d\n",
880	  (unsigned int) pScreenPriv->dwRedMask,
881	  (unsigned int) pScreenPriv->dwGreenMask,
882	  (unsigned int) pScreenPriv->dwBlueMask,
883	  (int) pScreenPriv->dwBitsPerRGB,
884	  (int) pScreenInfo->dwDepth,
885	  (int) pScreenInfo->dwBPP);
886
887  /* Create a single visual according to the Windows screen depth */
888  switch (pScreenInfo->dwDepth)
889    {
890    case 24:
891    case 16:
892    case 15:
893      /* Setup the real visual */
894      if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
895				     TrueColorMask,
896				     pScreenPriv->dwBitsPerRGB,
897				     -1,
898				     pScreenPriv->dwRedMask,
899				     pScreenPriv->dwGreenMask,
900				     pScreenPriv->dwBlueMask))
901	{
902	  ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks "
903		  "failed for TrueColor\n");
904	  return FALSE;
905	}
906
907#ifdef XWIN_EMULATEPSEUDO
908      if (!pScreenInfo->fEmulatePseudo)
909	break;
910
911      /* Setup a pseudocolor visual */
912      if (!miSetVisualTypesAndMasks (8,
913				     PseudoColorMask,
914				     8,
915				     -1,
916				     0,
917				     0,
918				     0))
919	{
920	  ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks "
921		  "failed for PseudoColor\n");
922	  return FALSE;
923	}
924#endif
925      break;
926
927    case 8:
928      if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
929				     pScreenInfo->fFullScreen
930				     ? PseudoColorMask : StaticColorMask,
931				     pScreenPriv->dwBitsPerRGB,
932				     pScreenInfo->fFullScreen
933				     ? PseudoColor : StaticColor,
934				     pScreenPriv->dwRedMask,
935				     pScreenPriv->dwGreenMask,
936				     pScreenPriv->dwBlueMask))
937	{
938	  ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks "
939		  "failed\n");
940	  return FALSE;
941	}
942      break;
943
944    default:
945      ErrorF ("winInitVisualsShadowDDNL - Unknown screen depth\n");
946      return FALSE;
947    }
948
949#if CYGDEBUG
950  winDebug ("winInitVisualsShadowDDNL - Returning\n");
951#endif
952
953  return TRUE;
954}
955
956
957/*
958 * Adjust the user proposed video mode
959 */
960
961static Bool
962winAdjustVideoModeShadowDDNL (ScreenPtr pScreen)
963{
964  winScreenPriv(pScreen);
965  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
966  HDC			hdc = NULL;
967  DWORD			dwBPP;
968
969  /* We're in serious trouble if we can't get a DC */
970  hdc = GetDC (NULL);
971  if (hdc == NULL)
972    {
973      ErrorF ("winAdjustVideoModeShadowDDNL - GetDC () failed\n");
974      return FALSE;
975    }
976
977  /* Query GDI for current display depth */
978  dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
979
980  /* DirectDraw can only change the depth in fullscreen mode */
981  if (!(pScreenInfo->fFullScreen &&
982        (pScreenInfo->dwBPP != WIN_DEFAULT_BPP)))
983    {
984      /* Otherwise, We'll use GDI's depth */
985      pScreenInfo->dwBPP = dwBPP;
986    }
987
988  /* Release our DC */
989  ReleaseDC (NULL, hdc);
990
991  return TRUE;
992}
993
994
995/*
996 * Blt exposed regions to the screen
997 */
998
999static Bool
1000winBltExposedRegionsShadowDDNL (ScreenPtr pScreen)
1001{
1002  winScreenPriv(pScreen);
1003  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
1004  RECT			rcSrc, rcDest;
1005  POINT			ptOrigin;
1006  HDC			hdcUpdate;
1007  PAINTSTRUCT		ps;
1008  HRESULT		ddrval = DD_OK;
1009  Bool			fReturn = TRUE;
1010  int			i;
1011
1012  /* Quite common case. The primary surface was lost (maybe because of depth
1013   * change). Try to create a new primary surface. Bail out if this fails */
1014  if (pScreenPriv->pddsPrimary4 == NULL && pScreenPriv->fRetryCreateSurface &&
1015      !winCreatePrimarySurfaceShadowDDNL(pScreen))
1016    {
1017      Sleep(100);
1018      return FALSE;
1019    }
1020  if (pScreenPriv->pddsPrimary4 == NULL)
1021    return FALSE;
1022
1023  /* BeginPaint gives us an hdc that clips to the invalidated region */
1024  hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps);
1025  if (hdcUpdate == NULL)
1026    {
1027      fReturn = FALSE;
1028      ErrorF ("winBltExposedRegionsShadowDDNL - BeginPaint () returned "
1029	      "a NULL device context handle.  Aborting blit attempt.\n");
1030      goto winBltExposedRegionsShadowDDNL_Exit;
1031    }
1032
1033  /* Get the origin of the window in the screen coords */
1034  ptOrigin.x = pScreenInfo->dwXOffset;
1035  ptOrigin.y = pScreenInfo->dwYOffset;
1036
1037  MapWindowPoints (pScreenPriv->hwndScreen,
1038		   HWND_DESKTOP,
1039		   (LPPOINT)&ptOrigin, 1);
1040  rcDest.left = ptOrigin.x;
1041  rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
1042  rcDest.top = ptOrigin.y;
1043  rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
1044
1045  /* Source can be entire shadow surface, as Blt should clip for us */
1046  rcSrc.left = 0;
1047  rcSrc.top = 0;
1048  rcSrc.right = pScreenInfo->dwWidth;
1049  rcSrc.bottom = pScreenInfo->dwHeight;
1050
1051  /* Try to regain the primary surface and blit again if we've lost it */
1052  for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i)
1053    {
1054      /* Our Blt should be clipped to the invalidated region */
1055      ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4,
1056					&rcDest,
1057					pScreenPriv->pddsShadow4,
1058					&rcSrc,
1059					DDBLT_WAIT,
1060					NULL);
1061      if (ddrval == DDERR_SURFACELOST)
1062	{
1063	  /* Surface was lost */
1064	  winErrorFVerb (1, "winBltExposedRegionsShadowDDNL - "
1065          "IDirectDrawSurface4_Blt reported that the primary "
1066          "surface was lost, trying to restore, retry: %d\n", i + 1);
1067
1068	  /* Try to restore the surface, once */
1069
1070	  ddrval = IDirectDrawSurface4_Restore (pScreenPriv->pddsPrimary4);
1071	  winDebug ("winBltExposedRegionsShadowDDNL - "
1072		  "IDirectDrawSurface4_Restore returned: ");
1073	  if (ddrval == DD_OK)
1074	    winDebug ("DD_OK\n");
1075	  else if (ddrval == DDERR_WRONGMODE)
1076	    winDebug ("DDERR_WRONGMODE\n");
1077	  else if (ddrval == DDERR_INCOMPATIBLEPRIMARY)
1078	    winDebug ("DDERR_INCOMPATIBLEPRIMARY\n");
1079	  else if (ddrval == DDERR_UNSUPPORTED)
1080	    winDebug ("DDERR_UNSUPPORTED\n");
1081	  else if (ddrval == DDERR_INVALIDPARAMS)
1082	    winDebug ("DDERR_INVALIDPARAMS\n");
1083	  else if (ddrval == DDERR_INVALIDOBJECT)
1084	    winDebug ("DDERR_INVALIDOBJECT\n");
1085	  else
1086	    winDebug ("unknown error: %08x\n", (unsigned int) ddrval);
1087
1088	  /* Loop around to try the blit one more time */
1089	  continue;
1090	}
1091      else if (FAILED (ddrval))
1092	{
1093	  fReturn = FALSE;
1094	  winErrorFVerb (1, "winBltExposedRegionsShadowDDNL - "
1095		  "IDirectDrawSurface4_Blt failed, but surface not "
1096		  "lost: %08x %d\n",
1097		  (unsigned int) ddrval, (int) ddrval);
1098	  goto winBltExposedRegionsShadowDDNL_Exit;
1099	}
1100      else
1101	{
1102	  /* Success, stop looping */
1103	  break;
1104	}
1105    }
1106
1107 winBltExposedRegionsShadowDDNL_Exit:
1108  /* EndPaint frees the DC */
1109  if (hdcUpdate != NULL)
1110    EndPaint (pScreenPriv->hwndScreen, &ps);
1111  return fReturn;
1112}
1113
1114
1115/*
1116 * Do any engine-specific application-activation processing
1117 */
1118
1119static Bool
1120winActivateAppShadowDDNL (ScreenPtr pScreen)
1121{
1122  winScreenPriv(pScreen);
1123
1124  /*
1125   * Do we have a surface?
1126   * Are we active?
1127   * Are we full screen?
1128   */
1129  if (pScreenPriv != NULL
1130      && pScreenPriv->pddsPrimary4 != NULL
1131      && pScreenPriv->fActive)
1132    {
1133      /* Primary surface was lost, restore it */
1134      IDirectDrawSurface4_Restore (pScreenPriv->pddsPrimary4);
1135    }
1136
1137  return TRUE;
1138}
1139
1140
1141/*
1142 * Reblit the shadow framebuffer to the screen.
1143 */
1144
1145static Bool
1146winRedrawScreenShadowDDNL (ScreenPtr pScreen)
1147{
1148  winScreenPriv(pScreen);
1149  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
1150  HRESULT		ddrval = DD_OK;
1151  RECT			rcSrc, rcDest;
1152  POINT			ptOrigin;
1153
1154  /* Get the origin of the window in the screen coords */
1155  ptOrigin.x = pScreenInfo->dwXOffset;
1156  ptOrigin.y = pScreenInfo->dwYOffset;
1157  MapWindowPoints (pScreenPriv->hwndScreen,
1158		   HWND_DESKTOP,
1159		   (LPPOINT)&ptOrigin, 1);
1160  rcDest.left = ptOrigin.x;
1161  rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
1162  rcDest.top = ptOrigin.y;
1163  rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
1164
1165  /* Source can be entire shadow surface, as Blt should clip for us */
1166  rcSrc.left = 0;
1167  rcSrc.top = 0;
1168  rcSrc.right = pScreenInfo->dwWidth;
1169  rcSrc.bottom = pScreenInfo->dwHeight;
1170
1171  /* Redraw the whole window, to take account for the new colors */
1172  ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4,
1173				    &rcDest,
1174				    pScreenPriv->pddsShadow4,
1175				    &rcSrc,
1176				    DDBLT_WAIT,
1177				    NULL);
1178  if (FAILED (ddrval))
1179    {
1180      ErrorF ("winRedrawScreenShadowDDNL - IDirectDrawSurface4_Blt () "
1181	      "failed: %08x\n",
1182	      (unsigned int) ddrval);
1183    }
1184
1185  return TRUE;
1186}
1187
1188
1189/*
1190 * Realize the currently installed colormap
1191 */
1192
1193static Bool
1194winRealizeInstalledPaletteShadowDDNL (ScreenPtr pScreen)
1195{
1196  return TRUE;
1197}
1198
1199
1200/*
1201 * Install the specified colormap
1202 */
1203
1204static Bool
1205winInstallColormapShadowDDNL (ColormapPtr pColormap)
1206{
1207  ScreenPtr		pScreen = pColormap->pScreen;
1208  winScreenPriv(pScreen);
1209  winCmapPriv(pColormap);
1210  HRESULT		ddrval = DD_OK;
1211
1212  /* Install the DirectDraw palette on the primary surface */
1213  ddrval = IDirectDrawSurface4_SetPalette (pScreenPriv->pddsPrimary4,
1214					   pCmapPriv->lpDDPalette);
1215  if (FAILED (ddrval))
1216    {
1217      ErrorF ("winInstallColormapShadowDDNL - Failed installing the "
1218	      "DirectDraw palette.\n");
1219      return FALSE;
1220    }
1221
1222  /* Save a pointer to the newly installed colormap */
1223  pScreenPriv->pcmapInstalled = pColormap;
1224
1225  return TRUE;
1226}
1227
1228
1229/*
1230 * Store the specified colors in the specified colormap
1231 */
1232
1233static Bool
1234winStoreColorsShadowDDNL (ColormapPtr pColormap,
1235			  int ndef,
1236			  xColorItem *pdefs)
1237{
1238  ScreenPtr		pScreen = pColormap->pScreen;
1239  winScreenPriv(pScreen);
1240  winCmapPriv(pColormap);
1241  ColormapPtr		curpmap = pScreenPriv->pcmapInstalled;
1242  HRESULT		ddrval = DD_OK;
1243
1244  /* Put the X colormap entries into the Windows logical palette */
1245  ddrval = IDirectDrawPalette_SetEntries (pCmapPriv->lpDDPalette,
1246					  0,
1247					  pdefs[0].pixel,
1248					  ndef,
1249					  pCmapPriv->peColors
1250					  + pdefs[0].pixel);
1251  if (FAILED (ddrval))
1252    {
1253      ErrorF ("winStoreColorsShadowDDNL - SetEntries () failed: %08x\n", (unsigned int) ddrval);
1254      return FALSE;
1255    }
1256
1257  /* Don't install the DirectDraw palette if the colormap is not installed */
1258  if (pColormap != curpmap)
1259    {
1260      return TRUE;
1261    }
1262
1263  if (!winInstallColormapShadowDDNL (pColormap))
1264    {
1265      ErrorF ("winStoreColorsShadowDDNL - Failed installing colormap\n");
1266      return FALSE;
1267    }
1268
1269  return TRUE;
1270}
1271
1272
1273/*
1274 * Colormap initialization procedure
1275 */
1276
1277static Bool
1278winCreateColormapShadowDDNL (ColormapPtr pColormap)
1279{
1280  HRESULT		ddrval = DD_OK;
1281  ScreenPtr		pScreen = pColormap->pScreen;
1282  winScreenPriv(pScreen);
1283  winCmapPriv(pColormap);
1284
1285  /* Create a DirectDraw palette */
1286  ddrval = IDirectDraw4_CreatePalette (pScreenPriv->pdd4,
1287				       DDPCAPS_8BIT | DDPCAPS_ALLOW256,
1288				       pCmapPriv->peColors,
1289				       &pCmapPriv->lpDDPalette,
1290				       NULL);
1291  if (FAILED (ddrval))
1292    {
1293      ErrorF ("winCreateColormapShadowDDNL - CreatePalette failed\n");
1294      return FALSE;
1295    }
1296
1297  return TRUE;
1298}
1299
1300
1301/*
1302 * Colormap destruction procedure
1303 */
1304
1305static Bool
1306winDestroyColormapShadowDDNL (ColormapPtr pColormap)
1307{
1308  winScreenPriv(pColormap->pScreen);
1309  winCmapPriv(pColormap);
1310  HRESULT		ddrval = DD_OK;
1311
1312  /*
1313   * Is colormap to be destroyed the default?
1314   *
1315   * Non-default colormaps should have had winUninstallColormap
1316   * called on them before we get here.  The default colormap
1317   * will not have had winUninstallColormap called on it.  Thus,
1318   * we need to handle the default colormap in a special way.
1319   */
1320  if (pColormap->flags & IsDefault)
1321    {
1322#if CYGDEBUG
1323      winDebug ("winDestroyColormapShadowDDNL - Destroying default colormap\n");
1324#endif
1325
1326      /*
1327       * FIXME: Walk the list of all screens, popping the default
1328       * palette out of each screen device context.
1329       */
1330
1331      /* Pop the palette out of the primary surface */
1332      ddrval = IDirectDrawSurface4_SetPalette (pScreenPriv->pddsPrimary4,
1333					       NULL);
1334      if (FAILED (ddrval))
1335	{
1336	  ErrorF ("winDestroyColormapShadowDDNL - Failed freeing the "
1337		  "default colormap DirectDraw palette.\n");
1338	  return FALSE;
1339	}
1340
1341      /* Clear our private installed colormap pointer */
1342      pScreenPriv->pcmapInstalled = NULL;
1343    }
1344
1345  /* Release the palette */
1346  IDirectDrawPalette_Release (pCmapPriv->lpDDPalette);
1347
1348  /* Invalidate the colormap privates */
1349  pCmapPriv->lpDDPalette = NULL;
1350
1351  return TRUE;
1352}
1353
1354
1355/*
1356 * Set pointers to our engine specific functions
1357 */
1358
1359Bool
1360winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen)
1361{
1362  winScreenPriv(pScreen);
1363  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
1364
1365  /* Set our pointers */
1366  pScreenPriv->pwinAllocateFB = winAllocateFBShadowDDNL;
1367  pScreenPriv->pwinFreeFB = winFreeFBShadowDDNL;
1368  pScreenPriv->pwinShadowUpdate = winShadowUpdateDDNL;
1369  pScreenPriv->pwinInitScreen = winInitScreenShadowDDNL;
1370  pScreenPriv->pwinCloseScreen = winCloseScreenShadowDDNL;
1371  pScreenPriv->pwinInitVisuals = winInitVisualsShadowDDNL;
1372  pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDDNL;
1373  if (pScreenInfo->fFullScreen)
1374    pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen;
1375  else
1376    pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
1377  pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
1378  pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDDNL;
1379  pScreenPriv->pwinActivateApp = winActivateAppShadowDDNL;
1380  pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDDNL;
1381  pScreenPriv->pwinRealizeInstalledPalette
1382    = winRealizeInstalledPaletteShadowDDNL;
1383  pScreenPriv->pwinInstallColormap = winInstallColormapShadowDDNL;
1384  pScreenPriv->pwinStoreColors = winStoreColorsShadowDDNL;
1385  pScreenPriv->pwinCreateColormap = winCreateColormapShadowDDNL;
1386  pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDDNL;
1387  pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA;
1388  pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDDNL;
1389  pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDDNL;
1390#ifdef XWIN_MULTIWINDOW
1391  pScreenPriv->pwinFinishCreateWindowsWindow
1392    = winFinishCreateWindowsWindowDDNL;
1393#endif
1394
1395  return TRUE;
1396}
1397