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 * Local function prototypes
42 */
43
44static Bool
45winAllocateFBPrimaryDD (ScreenPtr pScreen);
46
47static Bool
48winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen);
49
50static Bool
51winInitVisualsPrimaryDD (ScreenPtr pScreen);
52
53static Bool
54winAdjustVideoModePrimaryDD (ScreenPtr pScreen);
55
56static Bool
57winActivateAppPrimaryDD (ScreenPtr pScreen);
58
59static Bool
60winHotKeyAltTabPrimaryDD (ScreenPtr pScreen);
61
62
63/*
64 * Create a DirectDraw primary surface
65 */
66
67static Bool
68winAllocateFBPrimaryDD (ScreenPtr pScreen)
69{
70  winScreenPriv(pScreen);
71  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
72  HRESULT		ddrval = DD_OK;
73  DDSURFACEDESC		ddsd;
74  DDSURFACEDESC		*pddsdPrimary = NULL;
75  DDSURFACEDESC		*pddsdOffscreen = NULL;
76  RECT			rcClient;
77
78  ErrorF ("winAllocateFBPrimaryDD\n");
79
80  /* Get client area location in screen coords */
81  GetClientRect (pScreenPriv->hwndScreen, &rcClient);
82  MapWindowPoints (pScreenPriv->hwndScreen,
83		   HWND_DESKTOP,
84		   (LPPOINT)&rcClient, 2);
85
86  /* Create a DirectDraw object, store the address at lpdd */
87  ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL);
88  if (ddrval != DD_OK)
89    FatalError ("winAllocateFBPrimaryDD - Could not start DirectDraw\n");
90
91  /* Get a DirectDraw2 interface pointer */
92  ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd,
93				       &IID_IDirectDraw2,
94				       (LPVOID*) &pScreenPriv->pdd2);
95  if (FAILED (ddrval))
96    {
97      ErrorF ("winAllocateFBShadowDD - Failed DD2 query: %08x\n",
98	      (unsigned int) ddrval);
99      return FALSE;
100    }
101
102
103  ErrorF ("winAllocateFBPrimaryDD - Created and initialized DD\n");
104
105  /* Are we windowed or fullscreen? */
106  if (pScreenInfo->fFullScreen)
107    {
108      /* Full screen mode */
109      ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2,
110						 pScreenPriv->hwndScreen,
111						 DDSCL_FULLSCREEN
112						 | DDSCL_EXCLUSIVE);
113      if (FAILED (ddrval))
114	FatalError ("winAllocateFBPrimaryDD - Could not set "
115		    "cooperative level\n");
116
117      /* Change the video mode to the mode requested */
118      ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2,
119					    pScreenInfo->dwWidth,
120					    pScreenInfo->dwHeight,
121					    pScreenInfo->dwBPP,
122					    pScreenInfo->dwRefreshRate,
123					    0);
124       if (FAILED (ddrval))
125	FatalError ("winAllocateFBPrimaryDD - Could not set "
126		    "full screen display mode\n");
127    }
128  else
129    {
130      /* Windowed mode */
131      ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2,
132						 pScreenPriv->hwndScreen,
133						 DDSCL_NORMAL);
134      if (FAILED (ddrval))
135	FatalError ("winAllocateFBPrimaryDD - Could not set "
136		    "cooperative level\n");
137    }
138
139  /* Describe the primary surface */
140  ZeroMemory (&ddsd, sizeof (ddsd));
141  ddsd.dwSize = sizeof (ddsd);
142  ddsd.dwFlags = DDSD_CAPS;
143  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
144
145  /* Create the primary surface */
146  ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2,
147				       &ddsd,
148				       &pScreenPriv->pddsPrimary,
149				       NULL);
150  if (FAILED (ddrval))
151       FatalError ("winAllocateFBPrimaryDD - Could not create primary "
152		  "surface %08x\n", (unsigned int) ddrval);
153
154  ErrorF ("winAllocateFBPrimaryDD - Created primary\n");
155
156  /* Allocate a DD surface description for our screen privates */
157  pddsdPrimary = pScreenPriv->pddsdPrimary
158    = malloc (sizeof (DDSURFACEDESC));
159  if (pddsdPrimary == NULL)
160    FatalError ("winAllocateFBPrimaryDD - Could not allocate surface "
161		"description memory\n");
162  ZeroMemory (pddsdPrimary, sizeof (*pddsdPrimary));
163  pddsdPrimary->dwSize = sizeof (*pddsdPrimary);
164
165  /* Describe the offscreen surface to be created */
166  /*
167   * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface,
168   * as drawing, locking, and unlocking take forever
169   * with video memory surfaces.  In addition,
170   * video memory is a somewhat scarce resource,
171   * so you shouldn't be allocating video memory when
172   * you have the option of using system memory instead.
173   */
174  ZeroMemory (&ddsd, sizeof (ddsd));
175  ddsd.dwSize = sizeof (ddsd);
176  ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
177  ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
178  ddsd.dwHeight = pScreenInfo->dwHeight;
179  ddsd.dwWidth = pScreenInfo->dwWidth;
180
181  /* Create the shadow surface */
182  ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2,
183				       &ddsd,
184				       &pScreenPriv->pddsOffscreen,
185				       NULL);
186  if (ddrval != DD_OK)
187    FatalError ("winAllocateFBPrimaryDD - Could not create shadow "
188		"surface\n");
189
190  ErrorF ("winAllocateFBPrimaryDD - Created offscreen\n");
191
192  /* Allocate a DD surface description for our screen privates */
193  pddsdOffscreen = pScreenPriv->pddsdOffscreen
194    = malloc (sizeof (DDSURFACEDESC));
195  if (pddsdOffscreen == NULL)
196    FatalError ("winAllocateFBPrimaryDD - Could not allocate surface "
197		"description memory\n");
198  ZeroMemory (pddsdOffscreen, sizeof (*pddsdOffscreen));
199  pddsdOffscreen->dwSize = sizeof (*pddsdOffscreen);
200
201  ErrorF ("winAllocateFBPrimaryDD - Locking primary\n");
202
203  /* Lock the primary surface */
204  ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary,
205				    pScreenInfo->fFullScreen ? NULL:&rcClient,
206				    pddsdPrimary,
207				    DDLOCK_WAIT,
208				    NULL);
209  if (ddrval != DD_OK || pddsdPrimary->lpSurface == NULL)
210    FatalError ("winAllocateFBPrimaryDD - Could not lock "
211		"primary surface\n");
212
213  ErrorF ("winAllocateFBPrimaryDD - Locked primary\n");
214
215  /* We don't know how to deal with anything other than RGB */
216  if (!(pddsdPrimary->ddpfPixelFormat.dwFlags & DDPF_RGB))
217    FatalError ("winAllocateFBPrimaryDD - Color format other than RGB\n");
218
219  /* Grab the pitch from the surface desc */
220  pScreenInfo->dwStride = (pddsdPrimary->u1.lPitch * 8)
221    / pScreenInfo->dwBPP;
222
223  /* Save the pointer to our surface memory */
224  pScreenInfo->pfb = pddsdPrimary->lpSurface;
225
226  /* Grab the color depth and masks from the surface description */
227  pScreenPriv->dwRedMask = pddsdPrimary->ddpfPixelFormat.u2.dwRBitMask;
228  pScreenPriv->dwGreenMask = pddsdPrimary->ddpfPixelFormat.u3.dwGBitMask;
229  pScreenPriv->dwBlueMask = pddsdPrimary->ddpfPixelFormat.u4.dwBBitMask;
230
231  ErrorF ("winAllocateFBPrimaryDD - Returning\n");
232
233  return TRUE;
234}
235
236static void
237winFreeFBPrimaryDD (ScreenPtr pScreen)
238{
239  winScreenPriv(pScreen);
240  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
241
242  /* Free the offscreen surface, if there is one */
243  if (pScreenPriv->pddsOffscreen)
244    {
245      IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, NULL);
246      IDirectDrawSurface2_Release (pScreenPriv->pddsOffscreen);
247      pScreenPriv->pddsOffscreen = NULL;
248    }
249
250  /* Release the primary surface, if there is one */
251  if (pScreenPriv->pddsPrimary)
252    {
253      IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, NULL);
254      IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
255      pScreenPriv->pddsPrimary = NULL;
256    }
257
258  /* Free the DirectDraw object, if there is one */
259  if (pScreenPriv->pdd)
260    {
261      IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd);
262      IDirectDraw2_Release (pScreenPriv->pdd);
263      pScreenPriv->pdd = NULL;
264    }
265
266  /* Invalidate the ScreenInfo's fb pointer */
267  pScreenInfo->pfb = NULL;
268}
269
270static Bool
271winInitScreenPrimaryDD(ScreenPtr pScreen)
272{
273  return winAllocateFBPrimaryDD(pScreen);
274}
275
276/*
277 * Call the wrapped CloseScreen function.
278 *
279 * Free our resources and private structures.
280 */
281
282static Bool
283winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen)
284{
285  winScreenPriv(pScreen);
286  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
287  Bool			fReturn;
288
289  ErrorF ("winCloseScreenPrimaryDD - Freeing screen resources\n");
290
291  /* Flag that the screen is closed */
292  pScreenPriv->fClosed = TRUE;
293  pScreenPriv->fActive = FALSE;
294
295  /* Call the wrapped CloseScreen procedure */
296  WIN_UNWRAP(CloseScreen);
297  fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);
298
299  /* Delete the window property */
300  RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
301
302  winFreeFBPrimaryDD(pScreen);
303
304  /* Delete tray icon, if we have one */
305  if (!pScreenInfo->fNoTrayIcon)
306    winDeleteNotifyIcon (pScreenPriv);
307
308  /* Free the exit confirmation dialog box, if it exists */
309  if (g_hDlgExit != NULL)
310    {
311      DestroyWindow (g_hDlgExit);
312      g_hDlgExit = NULL;
313    }
314
315  /* Kill our window */
316  if (pScreenPriv->hwndScreen)
317    {
318      DestroyWindow (pScreenPriv->hwndScreen);
319      pScreenPriv->hwndScreen = NULL;
320    }
321
322  /* Kill our screeninfo's pointer to the screen */
323  pScreenInfo->pScreen = NULL;
324
325  /* Free the screen privates for this screen */
326  free ((pointer) pScreenPriv);
327
328  return fReturn;
329}
330
331
332/*
333 * Tell mi what sort of visuals we need.
334 *
335 * Generally we only need one visual, as our screen can only
336 * handle one format at a time, I believe.  You may want
337 * to verify that last sentence.
338 */
339
340static Bool
341winInitVisualsPrimaryDD (ScreenPtr pScreen)
342{
343  winScreenPriv(pScreen);
344  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
345  DWORD			dwRedBits, dwGreenBits, dwBlueBits;
346
347  /* Count the number of ones in each color mask */
348  dwRedBits = winCountBits (pScreenPriv->dwRedMask);
349  dwGreenBits = winCountBits (pScreenPriv->dwGreenMask);
350  dwBlueBits = winCountBits (pScreenPriv->dwBlueMask);
351
352  /* Store the maximum number of ones in a color mask as the bitsPerRGB */
353  if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
354    pScreenPriv->dwBitsPerRGB = dwRedBits;
355  else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
356    pScreenPriv->dwBitsPerRGB = dwGreenBits;
357  else
358    pScreenPriv->dwBitsPerRGB = dwBlueBits;
359
360  ErrorF ("winInitVisualsPrimaryDD - Masks: %08x %08x %08x bpRGB: %d\n",
361	  (unsigned int) pScreenPriv->dwRedMask,
362	  (unsigned int) pScreenPriv->dwGreenMask,
363	  (unsigned int) pScreenPriv->dwBlueMask,
364	  (int) pScreenPriv->dwBitsPerRGB);
365
366  /* Create a single visual according to the Windows screen depth */
367  switch (pScreenInfo->dwDepth)
368    {
369    case 24:
370    case 16:
371    case 15:
372      if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
373				     TrueColorMask,
374				     pScreenPriv->dwBitsPerRGB,
375				     TrueColor,
376				     pScreenPriv->dwRedMask,
377				     pScreenPriv->dwGreenMask,
378				     pScreenPriv->dwBlueMask))
379	{
380	  ErrorF ("winInitVisualsPrimaryDD - "
381		  "miSetVisualTypesAndMasks failed\n");
382	  return FALSE;
383	}
384      break;
385
386    case 8:
387#if CYGDEBUG
388      winDebug ("winInitVisuals - Calling miSetVisualTypesAndMasks\n");
389#endif /* CYGDEBUG */
390      if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
391				     PseudoColorMask,
392				     pScreenPriv->dwBitsPerRGB,
393				     PseudoColor,
394				     pScreenPriv->dwRedMask,
395				     pScreenPriv->dwGreenMask,
396				     pScreenPriv->dwBlueMask))
397	{
398	  ErrorF ("winInitVisualsPrimaryDD - "
399		  "miSetVisualTypesAndMasks failed\n");
400	  return FALSE;
401	}
402#if CYGDEBUG
403      winDebug ("winInitVisualsPrimaryDD - Returned from "
404	      "miSetVisualTypesAndMasks\n");
405#endif /* CYGDEBUG */
406      break;
407
408    default:
409      ErrorF ("winInitVisualsPrimaryDD - Unknown screen depth\n");
410      return FALSE;
411    }
412
413  ErrorF ("winInitVisualsPrimaryDD - Returning\n");
414
415  return TRUE;
416}
417
418
419static Bool
420winAdjustVideoModePrimaryDD (ScreenPtr pScreen)
421{
422  winScreenPriv(pScreen);
423  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
424  HDC			hdc = NULL;
425  DWORD			dwBPP;
426
427  /* We're in serious trouble if we can't get a DC */
428  hdc = GetDC (NULL);
429  if (hdc == NULL)
430    {
431      ErrorF ("winAdjustVideoModePrimaryDD - GetDC failed\n");
432      return FALSE;
433    }
434
435  /* Query GDI for current display depth */
436  dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
437
438  /* DirectDraw can only change the depth in fullscreen mode */
439  if (!(pScreenInfo->fFullScreen &&
440        (pScreenInfo->dwBPP != WIN_DEFAULT_BPP)))
441    {
442      /* Otherwise, We'll use GDI's depth */
443      pScreenInfo->dwBPP = dwBPP;
444    }
445
446  /* Release our DC */
447  ReleaseDC (NULL, hdc);
448
449  return TRUE;
450}
451
452
453/*
454 * We need to blit our offscreen fb to
455 * the screen when we are activated, and we need to point
456 * the fb code back to the primary surface memory.
457 */
458
459static Bool
460winActivateAppPrimaryDD (ScreenPtr pScreen)
461{
462  winScreenPriv(pScreen);
463  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
464  RECT			rcSrc, rcClient;
465  HRESULT		ddrval = DD_OK;
466
467  /* Check for errors */
468  if (pScreenPriv == NULL
469      || pScreenPriv->pddsPrimary == NULL
470      || pScreenPriv->pddsOffscreen == NULL)
471    return FALSE;
472
473  /* Check for do-nothing */
474  if (!pScreenPriv->fActive)
475    return TRUE;
476
477  /* We are activating */
478  ddrval = IDirectDrawSurface2_IsLost (pScreenPriv->pddsOffscreen);
479  if (ddrval == DD_OK)
480    {
481      IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen,
482				  NULL);
483      /*
484       * We don't check for an error from Unlock, because it
485       * doesn't matter if the Unlock failed.
486       */
487    }
488
489  /* Restore both surfaces, just cause I like it that way */
490  IDirectDrawSurface2_Restore (pScreenPriv->pddsOffscreen);
491  IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary);
492
493  /* Get client area in screen coords */
494  GetClientRect (pScreenPriv->hwndScreen, &rcClient);
495  MapWindowPoints (pScreenPriv->hwndScreen,
496		   HWND_DESKTOP,
497		   (LPPOINT)&rcClient, 2);
498
499  /* Setup a source rectangle */
500  rcSrc.left = 0;
501  rcSrc.top = 0;
502  rcSrc.right = pScreenInfo->dwWidth;
503  rcSrc.bottom = pScreenInfo->dwHeight;
504
505  ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
506				    &rcClient,
507				    pScreenPriv->pddsOffscreen,
508				    &rcSrc,
509				    DDBLT_WAIT,
510				    NULL);
511  if (ddrval != DD_OK)
512    FatalError ("winActivateAppPrimaryDD () - Failed blitting offscreen "
513		"surface to primary surface %08x\n", (unsigned int) ddrval);
514
515  /* Lock the primary surface */
516  ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary,
517				     &rcClient,
518				     pScreenPriv->pddsdPrimary,
519				     DDLOCK_WAIT,
520				     NULL);
521  if (ddrval != DD_OK
522      || pScreenPriv->pddsdPrimary->lpSurface == NULL)
523    FatalError ("winActivateAppPrimaryDD () - Could not lock "
524		"primary surface\n");
525
526  /* Notify FB of the new memory pointer */
527  winUpdateFBPointer (pScreen,
528		      pScreenPriv->pddsdPrimary->lpSurface);
529
530  /*
531   * Register the Alt-Tab combo as a hotkey so we can copy
532   * the primary framebuffer before the display mode changes
533   */
534  RegisterHotKey (pScreenPriv->hwndScreen, 1, MOD_ALT, 9);
535
536  return TRUE;
537}
538
539
540/*
541 * Handle the Alt+Tab hotkey.
542 *
543 * We need to save the primary fb to an offscreen fb when
544 * we get deactivated, and point the fb code at the offscreen
545 * fb for the duration of the deactivation.
546 */
547
548static Bool
549winHotKeyAltTabPrimaryDD (ScreenPtr pScreen)
550{
551  winScreenPriv(pScreen);
552  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
553  RECT			rcClient, rcSrc;
554  HRESULT		ddrval = DD_OK;
555
556  ErrorF ("\nwinHotKeyAltTabPrimaryDD\n\n");
557
558  /* Alt+Tab was pressed, we will lose focus very soon */
559  pScreenPriv->fActive = FALSE;
560
561  /* Check for error conditions */
562  if (pScreenPriv->pddsPrimary == NULL
563      || pScreenPriv->pddsOffscreen == NULL)
564    return FALSE;
565
566  /* Get client area in screen coords */
567  GetClientRect (pScreenPriv->hwndScreen, &rcClient);
568  MapWindowPoints (pScreenPriv->hwndScreen,
569		   HWND_DESKTOP,
570		   (LPPOINT)&rcClient, 2);
571
572  /* Did we loose the primary surface? */
573  ddrval = IDirectDrawSurface2_IsLost (pScreenPriv->pddsPrimary);
574  if (ddrval == DD_OK)
575    {
576      ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary,
577					   NULL);
578      if (FAILED (ddrval))
579	FatalError ("winHotKeyAltTabPrimaryDD - Failed unlocking primary "
580		    "surface\n");
581    }
582
583  /* Setup a source rectangle */
584  rcSrc.left = 0;
585  rcSrc.top = 0;
586  rcSrc.right = pScreenInfo->dwWidth;
587  rcSrc.bottom = pScreenInfo->dwHeight;
588
589      /* Blit the primary surface to the offscreen surface */
590  ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsOffscreen,
591				    NULL, /* should be rcDest */
592				    pScreenPriv->pddsPrimary,
593				    NULL,
594				    DDBLT_WAIT,
595				    NULL);
596  if (ddrval == DDERR_SURFACELOST)
597    {
598      IDirectDrawSurface2_Restore (pScreenPriv->pddsOffscreen);
599      IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary);
600
601      /* Blit the primary surface to the offscreen surface */
602      ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsOffscreen,
603					NULL,
604					pScreenPriv->pddsPrimary,
605					NULL,
606					DDBLT_WAIT,
607					NULL);
608      if (FAILED (ddrval))
609	FatalError ("winHotKeyAltTabPrimaryDD - Failed blitting primary "
610		    "surface to offscreen surface: %08x\n",
611		    (unsigned int) ddrval);
612    }
613  else
614    {
615      FatalError ("winHotKeyAltTabPrimaryDD - Unknown error from "
616		  "Blt: %08dx\n", (unsigned int) ddrval);
617    }
618
619  /* Lock the offscreen surface */
620  ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsOffscreen,
621				     NULL,
622				     pScreenPriv->pddsdOffscreen,
623				     DDLOCK_WAIT,
624				     NULL);
625  if (ddrval != DD_OK
626      || pScreenPriv->pddsdPrimary->lpSurface == NULL)
627    FatalError ("winHotKeyAltTabPrimaryDD - Could not lock "
628		"offscreen surface\n");
629
630  /* Notify FB of the new memory pointer */
631  winUpdateFBPointer (pScreen,
632		      pScreenPriv->pddsdOffscreen->lpSurface);
633
634  /* Unregister our hotkey */
635  UnregisterHotKey (pScreenPriv->hwndScreen, 1);
636
637  return TRUE;
638}
639
640
641/* Set engine specific functions */
642Bool
643winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen)
644{
645  winScreenPriv(pScreen);
646  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
647
648  /* Set our pointers */
649  pScreenPriv->pwinAllocateFB = winAllocateFBPrimaryDD;
650  pScreenPriv->pwinFreeFB = winFreeFBPrimaryDD;
651  pScreenPriv->pwinShadowUpdate = (winShadowUpdateProcPtr) (void (*)(void))NoopDDA;
652  pScreenPriv->pwinInitScreen = winInitScreenPrimaryDD;
653  pScreenPriv->pwinCloseScreen = winCloseScreenPrimaryDD;
654  pScreenPriv->pwinInitVisuals = winInitVisualsPrimaryDD;
655  pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModePrimaryDD;
656  if (pScreenInfo->fFullScreen)
657    pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen;
658  else
659    pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
660  pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
661  pScreenPriv->pwinBltExposedRegions = (winBltExposedRegionsProcPtr) (void (*)(void))NoopDDA;
662  pScreenPriv->pwinActivateApp = winActivateAppPrimaryDD;
663  pScreenPriv->pwinRedrawScreen = NULL;
664  pScreenPriv->pwinRealizeInstalledPalette = NULL;
665  pScreenPriv->pwinInstallColormap = NULL;
666  pScreenPriv->pwinStoreColors = NULL;
667  pScreenPriv->pwinCreateColormap = NULL;
668  pScreenPriv->pwinDestroyColormap = NULL;
669  pScreenPriv->pwinHotKeyAltTab = winHotKeyAltTabPrimaryDD;
670  pScreenPriv->pwinCreatePrimarySurface = (winCreatePrimarySurfaceProcPtr) (void (*)(void))NoopDDA;
671  pScreenPriv->pwinReleasePrimarySurface = (winReleasePrimarySurfaceProcPtr) (void (*)(void))NoopDDA;
672#ifdef XWIN_MULTIWINDOW
673  pScreenPriv->pwinFinishCreateWindowsWindow =
674    (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA;
675#endif
676
677  return TRUE;
678}
679