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