1 /* DirectDraw driver for User-based primary surfaces
3 * Copyright 2000-2001 TransGaming Technologies Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "wine/debug.h"
27 #include "ddraw_private.h"
28 #include "ddraw/main.h"
29 #include "ddraw/user.h"
30 #include "dclipper/main.h"
31 #include "dpalette/main.h"
32 #include "dsurface/main.h"
33 #include "dsurface/dib.h"
34 #include "dsurface/user.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
38 static ICOM_VTABLE(IDirectDraw7) User_DirectDraw_VTable;
40 static const DDDEVICEIDENTIFIER2 user_device =
44 { { 0x00010001, 0x00010001 } },
46 /* fe38440c-8969-4283-bc73-749e7bc3c2eb */
47 {0xfe38440c,0x8969,0x428e, {0x73,0xbc,0x74,0x9e,0x7b,0xc3,0xc2,0xeb}},
51 static const DDPIXELFORMAT pixelformats[] =
54 { sizeof(DDPIXELFORMAT), DDPF_RGB|DDPF_PALETTEINDEXED8, 0, { 8 } },
56 { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 16 }, { 0x7C00 }, { 0x3E0 },
59 { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 16 }, { 0xF800 }, { 0x7E0 },
62 { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 24 }, { 0xFF0000 },
63 { 0x00FF00 }, { 0x0000FF } },
65 { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 32 }, { 0xFF0000 },
66 { 0x00FF00 }, { 0x0000FF } }
69 HRESULT User_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
70 IUnknown* pUnkOuter, BOOL ex);
71 HRESULT User_DirectDraw_Initialize(IDirectDrawImpl*, const GUID*);
73 static const ddraw_driver user_driver =
77 User_DirectDraw_Create,
78 User_DirectDraw_Initialize
81 BOOL DDRAW_User_Init(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
83 if (fdwReason == DLL_PROCESS_ATTACH)
84 DDRAW_register_driver(&user_driver);
89 /* If you change this function, you probably want to change the enumeration
90 * code in EnumDisplayModes. */
92 IsValidDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP,
93 DWORD dwRefreshRate, DWORD dwFlags)
95 if (dwWidth > GetSystemMetrics(SM_CXSCREEN)
96 || dwHeight > GetSystemMetrics(SM_CYSCREEN))
115 static const DDPIXELFORMAT* pixelformat_for_depth(DWORD depth)
119 case 8: return pixelformats + 0;
120 case 15: return pixelformats + 1;
121 case 16: return pixelformats + 2;
122 case 24: return pixelformats + 3;
123 case 32: return pixelformats + 4;
124 default: return NULL;
128 /* Not called from the vtable. */
129 HRESULT User_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
135 TRACE("(%p,%d)\n",This,ex);
137 hr = Main_DirectDraw_Construct(This, ex);
138 if (FAILED(hr)) return hr;
140 This->final_release = User_DirectDraw_final_release;
142 This->create_primary = User_DirectDraw_create_primary;
143 This->create_backbuffer = User_DirectDraw_create_backbuffer;
145 hDC = CreateDCA("DISPLAY", NULL, NULL, NULL);
146 depth = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
149 This->width = GetSystemMetrics(SM_CXSCREEN);
150 This->height = GetSystemMetrics(SM_CYSCREEN);
151 This->pitch = DDRAW_width_bpp_to_pitch(This->width, depth);
152 This->pixelformat = *pixelformat_for_depth(depth);
154 This->orig_width = This->width;
155 This->orig_height = This->height;
156 This->orig_pitch = This->pitch;
157 This->orig_pixelformat = This->pixelformat;
159 ICOM_INIT_INTERFACE(This, IDirectDraw7, User_DirectDraw_VTable);
162 #define BLIT_CAPS (DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL \
163 | DDCAPS_BLTSTRETCH | DDCAPS_CANBLTSYSMEM | DDCAPS_CANCLIP \
164 | DDCAPS_CANCLIPSTRETCHED | DDCAPS_COLORKEY \
165 | DDCAPS_COLORKEYHWASSIST)
166 #define CKEY_CAPS (DDCKEYCAPS_DESTBLT | DDCKEYCAPS_SRCBLT)
167 #define FX_CAPS (DDFXCAPS_BLTALPHA | DDFXCAPS_BLTMIRRORLEFTRIGHT \
168 | DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTROTATION90 \
169 | DDFXCAPS_BLTSHRINKX | DDFXCAPS_BLTSHRINKXN \
170 | DDFXCAPS_BLTSHRINKY | DDFXCAPS_BLTSHRINKXN \
171 | DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHXN \
172 | DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHYN)
173 This->caps.dwCaps |= DDCAPS_GDI | DDCAPS_PALETTE | BLIT_CAPS /* Hack for D3D code */ | DDCAPS_3D;
174 This->caps.dwCaps2 |= DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED |
175 DDCAPS2_PRIMARYGAMMA | DDCAPS2_WIDESURFACES;
176 This->caps.dwCKeyCaps |= CKEY_CAPS;
177 This->caps.dwFXCaps |= FX_CAPS;
178 This->caps.dwPalCaps |= DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE;
179 This->caps.dwVidMemTotal = 16*1024*1024;
180 This->caps.dwVidMemFree = 16*1024*1024;
181 This->caps.dwSVBCaps |= BLIT_CAPS;
182 This->caps.dwSVBCKeyCaps |= CKEY_CAPS;
183 This->caps.dwSVBFXCaps |= FX_CAPS;
184 This->caps.dwVSBCaps |= BLIT_CAPS;
185 This->caps.dwVSBCKeyCaps |= CKEY_CAPS;
186 This->caps.dwVSBFXCaps |= FX_CAPS;
187 This->caps.dwSSBCaps |= BLIT_CAPS;
188 This->caps.dwSSBCKeyCaps |= CKEY_CAPS;
189 This->caps.dwSSBFXCaps |= FX_CAPS;
190 This->caps.ddsCaps.dwCaps |= DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER |
191 DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER |
192 DDSCAPS_OFFSCREENPLAIN | DDSCAPS_PALETTE |
193 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
194 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE | /* Hacks for D3D code */
195 DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
196 This->caps.ddsOldCaps.dwCaps = This->caps.ddsCaps.dwCaps;
204 /* This function is called from DirectDrawCreate(Ex) on the most-derived
205 * class to start construction.
206 * Not called from the vtable. */
207 HRESULT User_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
208 IUnknown* pUnkOuter, BOOL ex)
211 IDirectDrawImpl* This;
213 assert(pUnkOuter == NULL);
215 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
216 sizeof(IDirectDrawImpl) + sizeof(User_DirectDrawImpl));
217 if (This == NULL) return E_OUTOFMEMORY;
219 /* Note that this relation does *not* hold true if the DD object was
220 * CoCreateInstanced then Initialized. */
221 This->private = (User_DirectDrawImpl *)(This+1);
223 /* Initialize the DDCAPS structure */
224 This->caps.dwSize = sizeof(This->caps);
226 hr = User_DirectDraw_Construct(This, ex);
228 HeapFree(GetProcessHeap(), 0, This);
230 *pIface = ICOM_INTERFACE(This, IDirectDraw7);
235 /* This function is called from Uninit_DirectDraw_Initialize on the
236 * most-derived-class to start initialization.
237 * Not called from the vtable. */
238 HRESULT User_DirectDraw_Initialize(IDirectDrawImpl *This, const GUID* guid)
241 This->private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
242 sizeof(User_DirectDrawImpl));
243 if (This->private == NULL) return E_OUTOFMEMORY;
245 /* Initialize the DDCAPS structure */
246 This->caps.dwSize = sizeof(This->caps);
248 hr = User_DirectDraw_Construct(This, TRUE); /* XXX ex? */
251 HeapFree(GetProcessHeap(), 0, This->private);
258 /* Called from an internal function pointer. */
259 void User_DirectDraw_final_release(IDirectDrawImpl *This)
261 Main_DirectDraw_final_release(This);
264 /* Compact: generic */
265 /* CreateClipper: generic */
266 /* CreatePalette: generic (with callback) */
267 /* CreateSurface: generic (with callbacks) */
270 User_DirectDraw_create_primary(IDirectDrawImpl* This,
271 const DDSURFACEDESC2* pDDSD,
272 LPDIRECTDRAWSURFACE7* ppSurf,
275 return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
279 User_DirectDraw_create_backbuffer(IDirectDrawImpl* This,
280 const DDSURFACEDESC2* pDDSD,
281 LPDIRECTDRAWSURFACE7* ppSurf,
283 IDirectDrawSurfaceImpl* primary)
285 return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
288 /* DuplicateSurface: generic */
290 /* Derived from Xlib_IDirectDraw2Impl_EnumDisplayModes.
291 * Very fake: just enumerate some arbitrary modes.
293 * The screen sizes are plausible-looking screen sizes and will be limited
294 * by (virtual) screen size.
296 * The depths are whatever DIBsections support on the client side.
297 * Should they be limited by screen depth?
300 User_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
301 LPDDSURFACEDESC2 pDDSD, LPVOID context,
302 LPDDENUMMODESCALLBACK2 callback)
310 static const struct mode modes[] =
312 { 512, 384 }, { 640, 400 }, { 640, 480 }, { 800, 600 }, { 1024, 768 },
313 { 1152, 864 }, { 1280, 1024 }, { 1600, 1200 }
316 static const int num_modes = sizeof(modes)/sizeof(modes[0]);
318 static const int num_pixelformats
319 = sizeof(pixelformats)/sizeof(pixelformats[0]);
321 DDSURFACEDESC2 callback_sd;
323 int max_width, max_height;
326 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",iface,dwFlags,pDDSD,context,callback);
328 /* Unfortunately this is the virtual screen size, not physical. */
329 max_width = GetSystemMetrics(SM_CXSCREEN);
330 max_height = GetSystemMetrics(SM_CYSCREEN);
332 ZeroMemory(&callback_sd, sizeof(callback_sd));
333 callback_sd.dwSize = sizeof(callback_sd);
335 callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS
338 if (dwFlags & DDEDM_REFRESHRATES)
339 callback_sd.dwFlags |= DDSD_REFRESHRATE;
341 callback_sd.u2.dwRefreshRate = 60.0;
343 for (i = 0; i < num_modes; i++)
345 if (modes[i].width > max_width || modes[i].height > max_height)
348 callback_sd.dwHeight = modes[i].height;
349 callback_sd.dwWidth = modes[i].width;
351 TRACE("- mode: %ldx%ld\n", callback_sd.dwWidth, callback_sd.dwHeight);
352 for (j = 0; j < num_pixelformats; j++)
354 callback_sd.u1.lPitch
355 = DDRAW_width_bpp_to_pitch(modes[i].width,
356 pixelformats[j].u1.dwRGBBitCount);
358 callback_sd.u4.ddpfPixelFormat = pixelformats[j];
360 callback_sd.ddsCaps.dwCaps = 0;
361 if (pixelformats[j].dwFlags & DDPF_PALETTEINDEXED8) /* ick */
362 callback_sd.ddsCaps.dwCaps |= DDSCAPS_PALETTE;
364 assert(IsValidDisplayMode(callback_sd.dwWidth,
365 callback_sd.dwHeight,
366 callback_sd.u4.ddpfPixelFormat.u1.dwRGBBitCount,
369 TRACE(" - %2ld bpp, R=%08lx G=%08lx B=%08lx\n",
370 callback_sd.u4.ddpfPixelFormat.u1.dwRGBBitCount,
371 callback_sd.u4.ddpfPixelFormat.u2.dwRBitMask,
372 callback_sd.u4.ddpfPixelFormat.u3.dwGBitMask,
373 callback_sd.u4.ddpfPixelFormat.u4.dwBBitMask);
374 if (callback(&callback_sd, context) == DDENUMRET_CANCEL)
382 /* EnumSurfaces: generic */
383 /* FlipToGDISurface: ??? */
387 User_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
390 /* Based on my guesses for what is appropriate with some clues from the
391 * NVidia driver. Not everything is actually implemented yet.
392 * NV has but we don't: Overlays, Video Ports, DDCAPS_READSCANLINE,
393 * DDCAPS2_CERTIFIED (heh), DDSCAPS2_NONLOCALVIDMEM, DDSCAPS2_COPYFOURCC.
394 * It actually has no FX alpha caps.
395 * Oddly, it doesn't list DDPCAPS_PRIMARYSURFACE.
396 * And the HEL caps make little sense.
398 #define BLIT_CAPS (DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL \
399 | DDCAPS_BLTSTRETCH | DDCAPS_CANBLTSYSMEM | DDCAPS_CANCLIP \
400 | DDCAPS_CANCLIPSTRETCHED | DDCAPS_COLORKEY \
401 | DDCAPS_COLORKEYHWASSIST)
403 #define CKEY_CAPS (DDCKEYCAPS_DESTBLT | DDCKEYCAPS_SRCBLT)
405 #define FX_CAPS (DDFXCAPS_BLTALPHA | DDFXCAPS_BLTMIRRORLEFTRIGHT \
406 | DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTROTATION90 \
407 | DDFXCAPS_BLTSHRINKX | DDFXCAPS_BLTSHRINKXN \
408 | DDFXCAPS_BLTSHRINKY | DDFXCAPS_BLTSHRINKXN \
409 | DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHXN \
410 | DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHYN)
413 #define ROPS { SRCCOPY, SRCPAINT, SRCAND, SRCINVERT, SRCERASE, NOTSRCCOPY, \
414 NOTSRCERASE, MERGEPAINT, BLACKNESS, WHITENESS, }
419 static const DDCAPS caps =
421 DDCAPS_3D | DDCAPS_GDI | DDCAPS_PALETTE | BLIT_CAPS,
422 DDCAPS2_CANMANAGETEXTURE | DDCAPS2_CANRENDERWINDOWED | DDCAPS2_CERTIFIED
423 | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_PRIMARYGAMMA
424 | DDCAPS2_WIDESURFACES,
427 0, /* dwFXAlphaCaps */
428 DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE,
430 0, /* ? dwAlphaBitConstBitDepths */
431 0, /* ? dwAlphaBitPixelPitDepths */
432 0, /* ? dwAlphaBltSurfaceBitDepths */
433 0, /* ? dwAlphaOverlayConstBitDepths */
434 0, /* ? dwAlphaOverlayPixelBitDepths */
435 0, /* ? dwAlphaOverlaySurfaceBitDepths */
436 DDBD_16, /* ? dwZBufferBitDepths */
437 16*1024*1024, /* dwVidMemTotal */
438 16*1024*1024, /* dwVidMemFree */
439 0, /* dwMaxVisibleOverlays */
440 0, /* dwCurrVisibleOverlays */
441 0, /* dwNumFourCCCodes */
442 0, /* dwAlignBoundarySrc */
443 0, /* dwAlignSizeSrc */
444 0, /* dwAlignBoundaryDest */
445 0, /* dwAlignSizeDest */
446 0, /* dwAlignStrideAlign */
447 ROPS, /* XXX dwRops[DD_ROP_SPACE] */
448 { 0, }, /* XXX ddsOldCaps */
449 1000, /* dwMinOverlayStretch */
450 1000, /* dwMaxOverlayStretch */
451 1000, /* dwMinLiveVideoStretch */
452 1000, /* dwMaxLiveVideoStretch */
453 1000, /* dwMinHwCodecStretch */
454 1000, /* dwMaxHwCodecStretch */
455 0, 0, 0, /* dwReserved1, 2, 3 */
456 BLIT_CAPS, /* dwSVBCaps */
457 CKEY_CAPS, /* dwSVBCKeyCaps */
458 FX_CAPS, /* dwSVBFXCaps */
459 ROPS, /* dwSVBRops */
460 BLIT_CAPS, /* dwVSBCaps */
461 CKEY_CAPS, /* dwVSBCKeyCaps */
462 FX_CAPS, /* dwVSBFXCaps */
463 ROPS, /* dwVSBRops */
464 BLIT_CAPS, /* dwSSBCaps */
465 CKEY_CAPS, /* dwSSBCKeyCaps */
466 FX_CAPS, /* dwSSBFXCaps */
467 ROPS, /* dwSSBRops */
468 0, /* dwMaxVideoPorts */
469 0, /* dwCurrVideoPorts */
470 0, /* ? dwSVBCaps2 */
471 BLIT_CAPS, /* ? dwNLVBCaps */
472 0, /* ? dwNLVBCaps2 */
473 CKEY_CAPS, /* dwNLVBCKeyCaps */
474 FX_CAPS, /* dwNLVBFXCaps */
475 ROPS, /* dwNLVBRops */
477 DDSCAPS_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_FLIP
478 | DDSCAPS_FRONTBUFFER | DDSCAPS_MIPMAP | DDSCAPS_OFFSCREENPLAIN
479 | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY
480 | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE
493 ICOM_THIS(IDirectDrawImpl, iface);
495 TRACE("(%p)->(%p,%p)\n",This,pDriverCaps,pHELCaps);
497 if (pDriverCaps != NULL)
498 DD_STRUCT_COPY_BYSIZE(pDriverCaps,&caps);
500 if (pHELCaps != NULL)
501 DD_STRUCT_COPY_BYSIZE(pHELCaps,&caps);
508 User_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
509 LPDDDEVICEIDENTIFIER2 pDDDI,
512 TRACE("(%p)->(%p,%08lx)\n",iface,pDDDI,dwFlags);
513 *pDDDI = user_device;
517 /* GetDisplayMode: generic */
518 /* GetFourCCCodes: generic */
519 /* GetGDISurface: ??? */
520 /* GetMonitorFrequency: generic */
521 /* GetScanLine: generic */
522 /* GetSurfaceFromDC: generic */
523 /* GetVerticalBlankStatus: generic */
524 /* Initialize: generic */
525 /* RestoreAllSurfaces: generic */
526 /* RestoreDisplayMode: generic */
527 /* SetCooperativeLevel: ??? */
530 User_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
531 DWORD dwHeight, DWORD dwBPP,
532 DWORD dwRefreshRate, DWORD dwFlags)
534 ICOM_THIS(IDirectDrawImpl, iface);
536 const DDPIXELFORMAT* pixelformat;
539 TRACE("(%p)->(%ldx%ldx%ld,%ld Hz,%08lx)\n",This,dwWidth,dwHeight,dwBPP,dwRefreshRate,dwFlags);
540 if (!IsValidDisplayMode(dwWidth, dwHeight, dwBPP, dwRefreshRate, dwFlags))
541 return DDERR_INVALIDMODE;
543 pixelformat = pixelformat_for_depth(dwBPP);
544 if (pixelformat == NULL)
547 return DDERR_GENERIC;
550 pitch = DDRAW_width_bpp_to_pitch(dwWidth, dwBPP);
552 return Main_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, pitch,
553 dwRefreshRate, dwFlags, pixelformat);
556 /* StartModeTest: ??? */
557 /* TestCooperativeLevel: generic? */
558 /* WaitForVerticalBlank: ??? */
560 static ICOM_VTABLE(IDirectDraw7) User_DirectDraw_VTable =
562 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
563 Main_DirectDraw_QueryInterface,
564 Main_DirectDraw_AddRef,
565 Main_DirectDraw_Release,
566 Main_DirectDraw_Compact,
567 Main_DirectDraw_CreateClipper,
568 Main_DirectDraw_CreatePalette,
569 Main_DirectDraw_CreateSurface,
570 Main_DirectDraw_DuplicateSurface,
571 User_DirectDraw_EnumDisplayModes,
572 Main_DirectDraw_EnumSurfaces,
573 Main_DirectDraw_FlipToGDISurface,
574 Main_DirectDraw_GetCaps,
575 Main_DirectDraw_GetDisplayMode,
576 Main_DirectDraw_GetFourCCCodes,
577 Main_DirectDraw_GetGDISurface,
578 Main_DirectDraw_GetMonitorFrequency,
579 Main_DirectDraw_GetScanLine,
580 Main_DirectDraw_GetVerticalBlankStatus,
581 Main_DirectDraw_Initialize,
582 Main_DirectDraw_RestoreDisplayMode,
583 Main_DirectDraw_SetCooperativeLevel,
584 User_DirectDraw_SetDisplayMode,
585 Main_DirectDraw_WaitForVerticalBlank,
586 Main_DirectDraw_GetAvailableVidMem,
587 Main_DirectDraw_GetSurfaceFromDC,
588 Main_DirectDraw_RestoreAllSurfaces,
589 Main_DirectDraw_TestCooperativeLevel,
590 User_DirectDraw_GetDeviceIdentifier,
591 Main_DirectDraw_StartModeTest,
592 Main_DirectDraw_EvaluateMode