msxml: Allow the element implementation to be aggregatable.
[wine/multimedia.git] / dlls / ddraw / ddraw_user.c
blobddf3d6c40d523af85099fff9e46c4f335bf0f940
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "config.h"
22 #include <assert.h>
23 #include <stdarg.h>
24 #include <string.h>
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wingdi.h"
32 #include "winuser.h"
33 #include "ddraw.h"
34 #include "ddraw_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
39 static const IDirectDraw7Vtbl User_DirectDraw_VTable;
41 static const DDDEVICEIDENTIFIER2 user_device =
43 "display",
44 "User (and GDI)",
45 { { 0x00010001, 0x00010001 } },
46 0, 0, 0, 0,
47 /* fe38440c-8969-4283-bc73-749e7bc3c2eb */
48 {0xfe38440c,0x8969,0x428e, {0x73,0xbc,0x74,0x9e,0x7b,0xc3,0xc2,0xeb}},
52 static const DDPIXELFORMAT pixelformats[] =
54 /* 8bpp paletted */
55 { sizeof(DDPIXELFORMAT), DDPF_RGB|DDPF_PALETTEINDEXED8, 0, { 8 } },
56 /* 15bpp 5/5/5 */
57 { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 16 }, { 0x7C00 }, { 0x3E0 },
58 { 0x1F } },
59 /* 16bpp 5/6/5 */
60 { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 16 }, { 0xF800 }, { 0x7E0 },
61 { 0x1F } },
62 /* 24bpp 8/8/8 */
63 { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 24 }, { 0xFF0000 },
64 { 0x00FF00 }, { 0x0000FF } },
65 /* 32bpp 8/8/8 */
66 { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 32 }, { 0xFF0000 },
67 { 0x00FF00 }, { 0x0000FF } }
70 HRESULT User_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
71 IUnknown* pUnkOuter, BOOL ex);
72 HRESULT User_DirectDraw_Initialize(IDirectDrawImpl*, const GUID*);
74 static const ddraw_driver user_driver =
76 &user_device,
77 10,
78 User_DirectDraw_Create,
79 User_DirectDraw_Initialize
82 BOOL DDRAW_User_Init(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
84 if (fdwReason == DLL_PROCESS_ATTACH)
85 DDRAW_register_driver(&user_driver);
87 return TRUE;
90 static const DDPIXELFORMAT* pixelformat_for_depth(DWORD depth)
92 switch (depth)
94 case 8: return pixelformats + 0;
95 case 15: return pixelformats + 1;
96 case 16: return pixelformats + 2;
97 case 24: return pixelformats + 3;
98 case 32: return pixelformats + 4;
99 default: return NULL;
103 /* Not called from the vtable. */
104 HRESULT User_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
106 HRESULT hr;
107 DWORD depth;
108 HDC hDC;
110 TRACE("(%p,%d)\n",This,ex);
112 hr = Main_DirectDraw_Construct(This, ex);
113 if (FAILED(hr)) return hr;
115 This->final_release = User_DirectDraw_final_release;
117 This->create_primary = User_DirectDraw_create_primary;
118 This->create_backbuffer = User_DirectDraw_create_backbuffer;
120 hDC = CreateDCA("DISPLAY", NULL, NULL, NULL);
121 depth = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
122 DeleteDC(hDC);
124 This->width = GetSystemMetrics(SM_CXSCREEN);
125 This->height = GetSystemMetrics(SM_CYSCREEN);
126 This->pitch = DDRAW_width_bpp_to_pitch(This->width, depth);
127 This->pixelformat = *pixelformat_for_depth(depth);
129 This->orig_width = This->width;
130 This->orig_height = This->height;
131 This->orig_pitch = This->pitch;
132 This->orig_pixelformat = This->pixelformat;
134 ICOM_INIT_INTERFACE(This, IDirectDraw7, User_DirectDraw_VTable);
136 /* capabilities */
137 #define BLIT_CAPS (DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL \
138 | DDCAPS_BLTSTRETCH | DDCAPS_CANBLTSYSMEM | DDCAPS_CANCLIP \
139 | DDCAPS_CANCLIPSTRETCHED | DDCAPS_COLORKEY \
140 | DDCAPS_COLORKEYHWASSIST | DDCAPS_OVERLAY | DDCAPS_OVERLAYSTRETCH)
141 #define CKEY_CAPS (DDCKEYCAPS_DESTBLT | DDCKEYCAPS_SRCBLT)
142 #define FX_CAPS (DDFXCAPS_BLTALPHA | DDFXCAPS_BLTMIRRORLEFTRIGHT \
143 | DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTROTATION90 \
144 | DDFXCAPS_BLTSHRINKX | DDFXCAPS_BLTSHRINKXN \
145 | DDFXCAPS_BLTSHRINKY | DDFXCAPS_BLTSHRINKXN \
146 | DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHXN \
147 | DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHYN)
148 This->caps.dwCaps |= DDCAPS_GDI | DDCAPS_PALETTE | BLIT_CAPS;
149 if( opengl_initialized )
151 /* Hack for D3D code */
152 This->caps.dwCaps |= DDCAPS_3D;
154 This->caps.dwCaps2 |= DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED |
155 DDCAPS2_PRIMARYGAMMA | DDCAPS2_WIDESURFACES;
156 This->caps.dwCKeyCaps |= CKEY_CAPS;
157 This->caps.dwFXCaps |= FX_CAPS;
158 This->caps.dwPalCaps |= DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE;
159 This->caps.dwVidMemTotal = 16*1024*1024;
160 This->caps.dwVidMemFree = 16*1024*1024;
161 This->caps.dwSVBCaps |= BLIT_CAPS;
162 This->caps.dwSVBCKeyCaps |= CKEY_CAPS;
163 This->caps.dwSVBFXCaps |= FX_CAPS;
164 This->caps.dwVSBCaps |= BLIT_CAPS;
165 This->caps.dwVSBCKeyCaps |= CKEY_CAPS;
166 This->caps.dwVSBFXCaps |= FX_CAPS;
167 This->caps.dwSSBCaps |= BLIT_CAPS;
168 This->caps.dwSSBCKeyCaps |= CKEY_CAPS;
169 This->caps.dwSSBFXCaps |= FX_CAPS;
170 This->caps.ddsCaps.dwCaps |= DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER |
171 DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER |
172 DDSCAPS_OFFSCREENPLAIN | DDSCAPS_PALETTE |
173 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
174 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
175 if( opengl_initialized )
177 /* Hacks for D3D code */
178 This->caps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
181 This->caps.ddsOldCaps.dwCaps = This->caps.ddsCaps.dwCaps;
182 #undef BLIT_CAPS
183 #undef CKEY_CAPS
184 #undef FX_CAPS
186 return S_OK;
189 /* This function is called from DirectDrawCreate(Ex) on the most-derived
190 * class to start construction.
191 * Not called from the vtable. */
192 HRESULT User_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
193 IUnknown* pUnkOuter, BOOL ex)
195 HRESULT hr;
196 IDirectDrawImpl* This;
198 assert(pUnkOuter == NULL);
200 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
201 sizeof(IDirectDrawImpl) + sizeof(User_DirectDrawImpl));
202 if (This == NULL) return E_OUTOFMEMORY;
204 /* Note that this relation does *not* hold true if the DD object was
205 * CoCreateInstanced then Initialized. */
206 This->private = (User_DirectDrawImpl *)(This+1);
208 /* Initialize the DDCAPS structure */
209 This->caps.dwSize = sizeof(This->caps);
211 hr = User_DirectDraw_Construct(This, ex);
212 if (FAILED(hr))
213 HeapFree(GetProcessHeap(), 0, This);
214 else
215 *pIface = ICOM_INTERFACE(This, IDirectDraw7);
217 return hr;
220 /* This function is called from Uninit_DirectDraw_Initialize on the
221 * most-derived-class to start initialization.
222 * Not called from the vtable. */
223 HRESULT User_DirectDraw_Initialize(IDirectDrawImpl *This, const GUID* guid)
225 HRESULT hr;
226 This->private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
227 sizeof(User_DirectDrawImpl));
228 if (This->private == NULL) return E_OUTOFMEMORY;
230 /* Initialize the DDCAPS structure */
231 This->caps.dwSize = sizeof(This->caps);
233 hr = User_DirectDraw_Construct(This, TRUE); /* XXX ex? */
234 if (FAILED(hr))
236 HeapFree(GetProcessHeap(), 0, This->private);
237 return hr;
240 return DD_OK;
243 /* Called from an internal function pointer. */
244 void User_DirectDraw_final_release(IDirectDrawImpl *This)
246 Main_DirectDraw_final_release(This);
249 /* Compact: generic */
250 /* CreateClipper: generic */
251 /* CreatePalette: generic (with callback) */
252 /* CreateSurface: generic (with callbacks) */
254 HRESULT
255 User_DirectDraw_create_primary(IDirectDrawImpl* This,
256 const DDSURFACEDESC2* pDDSD,
257 LPDIRECTDRAWSURFACE7* ppSurf,
258 IUnknown* pUnkOuter)
260 return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
263 HRESULT
264 User_DirectDraw_create_backbuffer(IDirectDrawImpl* This,
265 const DDSURFACEDESC2* pDDSD,
266 LPDIRECTDRAWSURFACE7* ppSurf,
267 IUnknown* pUnkOuter,
268 IDirectDrawSurfaceImpl* primary)
270 return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
273 /* DuplicateSurface: generic */
275 /* Originally derived from Xlib_IDirectDraw2Impl_EnumDisplayModes.
277 * The depths are whatever DIBsections support on the client side.
278 * Should they be limited by screen depth?
280 HRESULT WINAPI
281 User_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
282 LPDDSURFACEDESC2 pDDSD, LPVOID context,
283 LPDDENUMMODESCALLBACK2 callback)
285 DDSURFACEDESC2 callback_sd;
286 DEVMODEW DevModeW;
287 const DDPIXELFORMAT* pixelformat;
289 int i;
291 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",iface,dwFlags,pDDSD,context,callback);
293 if (pDDSD && TRACE_ON(ddraw))
295 TRACE("Enumerate modes matching:\n");
296 DDRAW_dump_surface_desc(pDDSD);
299 ZeroMemory(&callback_sd, sizeof(callback_sd));
300 callback_sd.dwSize = sizeof(callback_sd);
302 callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS
303 | DDSD_PITCH;
305 if (dwFlags & DDEDM_REFRESHRATES)
306 callback_sd.dwFlags |= DDSD_REFRESHRATE;
308 callback_sd.u2.dwRefreshRate = 60.0;
310 for (i = 0; EnumDisplaySettingsExW(NULL, i, &DevModeW, 0); i++)
312 if (pDDSD)
314 if ((pDDSD->dwFlags & DDSD_WIDTH) && (pDDSD->dwWidth != DevModeW.dmPelsWidth))
315 continue;
316 if ((pDDSD->dwFlags & DDSD_HEIGHT) && (pDDSD->dwHeight != DevModeW.dmPelsHeight))
317 continue;
318 if ((pDDSD->dwFlags & DDSD_PIXELFORMAT) && (pDDSD->u4.ddpfPixelFormat.dwFlags & DDPF_RGB) &&
319 (pDDSD->u4.ddpfPixelFormat.u1.dwRGBBitCount != DevModeW.dmBitsPerPel))
320 continue;
323 callback_sd.dwHeight = DevModeW.dmPelsHeight;
324 callback_sd.dwWidth = DevModeW.dmPelsWidth;
325 if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
327 callback_sd.u2.dwRefreshRate = DevModeW.dmDisplayFrequency;
330 TRACE("- mode: %ldx%ld\n", callback_sd.dwWidth, callback_sd.dwHeight);
332 pixelformat = pixelformat_for_depth(DevModeW.dmBitsPerPel);
333 callback_sd.u1.lPitch
334 = DDRAW_width_bpp_to_pitch(DevModeW.dmPelsWidth,
335 pixelformat->u1.dwRGBBitCount);
337 callback_sd.u4.ddpfPixelFormat = *pixelformat;
339 callback_sd.ddsCaps.dwCaps = 0;
340 if (pixelformat->dwFlags & DDPF_PALETTEINDEXED8) /* ick */
341 callback_sd.ddsCaps.dwCaps |= DDSCAPS_PALETTE;
343 TRACE(" - %2ld bpp, R=%08lx G=%08lx B=%08lx\n",
344 callback_sd.u4.ddpfPixelFormat.u1.dwRGBBitCount,
345 callback_sd.u4.ddpfPixelFormat.u2.dwRBitMask,
346 callback_sd.u4.ddpfPixelFormat.u3.dwGBitMask,
347 callback_sd.u4.ddpfPixelFormat.u4.dwBBitMask);
348 if (callback(&callback_sd, context) == DDENUMRET_CANCEL)
349 return DD_OK;
352 return DD_OK;
355 /* EnumSurfaces: generic */
356 /* FlipToGDISurface: ??? */
358 #if 0
359 HRESULT WINAPI
360 User_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
361 LPDDCAPS pHELCaps)
363 /* Based on my guesses for what is appropriate with some clues from the
364 * NVidia driver. Not everything is actually implemented yet.
365 * NV has but we don't: Overlays, Video Ports, DDCAPS_READSCANLINE,
366 * DDCAPS2_CERTIFIED (heh), DDSCAPS2_NONLOCALVIDMEM, DDSCAPS2_COPYFOURCC.
367 * It actually has no FX alpha caps.
368 * Oddly, it doesn't list DDPCAPS_PRIMARYSURFACE.
369 * And the HEL caps make little sense.
371 #define BLIT_CAPS (DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL \
372 | DDCAPS_BLTSTRETCH | DDCAPS_CANBLTSYSMEM | DDCAPS_CANCLIP \
373 | DDCAPS_CANCLIPSTRETCHED | DDCAPS_COLORKEY \
374 | DDCAPS_COLORKEYHWASSIST | DDCAPS_OVERLAY | DDCAPS_OVERLAYSTRETCH)
376 #define CKEY_CAPS (DDCKEYCAPS_DESTBLT | DDCKEYCAPS_SRCBLT)
378 #define FX_CAPS (DDFXCAPS_BLTALPHA | DDFXCAPS_BLTMIRRORLEFTRIGHT \
379 | DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTROTATION90 \
380 | DDFXCAPS_BLTSHRINKX | DDFXCAPS_BLTSHRINKXN \
381 | DDFXCAPS_BLTSHRINKY | DDFXCAPS_BLTSHRINKXN \
382 | DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHXN \
383 | DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHYN)
385 #if 0
386 #define ROPS { SRCCOPY, SRCPAINT, SRCAND, SRCINVERT, SRCERASE, NOTSRCCOPY, \
387 NOTSRCERASE, MERGEPAINT, BLACKNESS, WHITENESS, }
388 #else
389 #define ROPS { 0, }
390 #endif
392 static const DDCAPS caps =
393 { sizeof(DDCAPS),
394 DDCAPS_3D | DDCAPS_GDI | DDCAPS_PALETTE | BLIT_CAPS,
395 DDCAPS2_CANMANAGETEXTURE | DDCAPS2_CANRENDERWINDOWED | DDCAPS2_CERTIFIED
396 | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_PRIMARYGAMMA
397 | DDCAPS2_WIDESURFACES,
398 CKEY_CAPS,
399 FX_CAPS,
400 0, /* dwFXAlphaCaps */
401 DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE,
402 0, /* dwSVCaps */
403 0, /* ? dwAlphaBitConstBitDepths */
404 0, /* ? dwAlphaBitPixelPitDepths */
405 0, /* ? dwAlphaBltSurfaceBitDepths */
406 0, /* ? dwAlphaOverlayConstBitDepths */
407 0, /* ? dwAlphaOverlayPixelBitDepths */
408 0, /* ? dwAlphaOverlaySurfaceBitDepths */
409 DDBD_16, /* ? dwZBufferBitDepths */
410 16*1024*1024, /* dwVidMemTotal */
411 16*1024*1024, /* dwVidMemFree */
412 0, /* dwMaxVisibleOverlays */
413 0, /* dwCurrVisibleOverlays */
414 0, /* dwNumFourCCCodes */
415 0, /* dwAlignBoundarySrc */
416 0, /* dwAlignSizeSrc */
417 0, /* dwAlignBoundaryDest */
418 0, /* dwAlignSizeDest */
419 0, /* dwAlignStrideAlign */
420 ROPS, /* XXX dwRops[DD_ROP_SPACE] */
421 { 0, }, /* XXX ddsOldCaps */
422 1000, /* dwMinOverlayStretch */
423 1000, /* dwMaxOverlayStretch */
424 1000, /* dwMinLiveVideoStretch */
425 1000, /* dwMaxLiveVideoStretch */
426 1000, /* dwMinHwCodecStretch */
427 1000, /* dwMaxHwCodecStretch */
428 0, 0, 0, /* dwReserved1, 2, 3 */
429 BLIT_CAPS, /* dwSVBCaps */
430 CKEY_CAPS, /* dwSVBCKeyCaps */
431 FX_CAPS, /* dwSVBFXCaps */
432 ROPS, /* dwSVBRops */
433 BLIT_CAPS, /* dwVSBCaps */
434 CKEY_CAPS, /* dwVSBCKeyCaps */
435 FX_CAPS, /* dwVSBFXCaps */
436 ROPS, /* dwVSBRops */
437 BLIT_CAPS, /* dwSSBCaps */
438 CKEY_CAPS, /* dwSSBCKeyCaps */
439 FX_CAPS, /* dwSSBFXCaps */
440 ROPS, /* dwSSBRops */
441 0, /* dwMaxVideoPorts */
442 0, /* dwCurrVideoPorts */
443 0, /* ? dwSVBCaps2 */
444 BLIT_CAPS, /* ? dwNLVBCaps */
445 0, /* ? dwNLVBCaps2 */
446 CKEY_CAPS, /* dwNLVBCKeyCaps */
447 FX_CAPS, /* dwNLVBFXCaps */
448 ROPS, /* dwNLVBRops */
449 { /* ddsCaps */
450 DDSCAPS_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_FLIP
451 | DDSCAPS_FRONTBUFFER | DDSCAPS_MIPMAP | DDSCAPS_OFFSCREENPLAIN
452 | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY
453 | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE
454 | DDSCAPS_ZBUFFER,
455 DDSCAPS2_CUBEMAP,
461 #undef BLIT_CAPS
462 #undef CKEY_CAPS
463 #undef FX_CAPS
464 #undef ROPS
466 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
468 TRACE("(%p)->(%p,%p)\n",This,pDriverCaps,pHELCaps);
470 if (pDriverCaps != NULL)
471 DD_STRUCT_COPY_BYSIZE(pDriverCaps,&caps);
473 if (pHELCaps != NULL)
474 DD_STRUCT_COPY_BYSIZE(pHELCaps,&caps);
476 return DD_OK;
478 #endif
480 HRESULT WINAPI
481 User_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
482 LPDDDEVICEIDENTIFIER2 pDDDI,
483 DWORD dwFlags)
485 TRACE("(%p)->(%p,%08lx)\n",iface,pDDDI,dwFlags);
486 *pDDDI = user_device;
487 return DD_OK;
490 /* GetDisplayMode: generic */
491 /* GetFourCCCodes: generic */
492 /* GetGDISurface: ??? */
493 /* GetMonitorFrequency: generic */
494 /* GetScanLine: generic */
495 /* GetSurfaceFromDC: generic */
496 /* GetVerticalBlankStatus: generic */
497 /* Initialize: generic */
498 /* RestoreAllSurfaces: generic */
499 /* RestoreDisplayMode: generic */
500 /* SetCooperativeLevel: ??? */
502 HRESULT WINAPI
503 User_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
504 DWORD dwHeight, DWORD dwBPP,
505 DWORD dwRefreshRate, DWORD dwFlags)
507 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
509 const DDPIXELFORMAT* pixelformat;
510 DEVMODEW devmode;
511 LONG pitch;
513 TRACE("(%p)->(%ldx%ldx%ld,%ld Hz,%08lx)\n",This,dwWidth,dwHeight,dwBPP,dwRefreshRate,dwFlags);
514 devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
515 devmode.dmBitsPerPel = dwBPP;
516 devmode.dmPelsWidth = dwWidth;
517 devmode.dmPelsHeight = dwHeight;
518 /* '0' means default frequency */
519 if (dwRefreshRate != 0)
521 devmode.dmFields |= DM_DISPLAYFREQUENCY;
522 devmode.dmDisplayFrequency = dwRefreshRate;
524 if (ChangeDisplaySettingsExW(NULL, &devmode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL)
525 return DDERR_INVALIDMODE;
527 pixelformat = pixelformat_for_depth(dwBPP);
528 if (pixelformat == NULL)
530 assert(0);
531 return DDERR_GENERIC;
534 pitch = DDRAW_width_bpp_to_pitch(dwWidth, dwBPP);
535 return Main_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, pitch,
536 dwRefreshRate, dwFlags, pixelformat);
539 /* StartModeTest: ??? */
540 /* TestCooperativeLevel: generic? */
541 /* WaitForVerticalBlank: ??? */
543 static const IDirectDraw7Vtbl User_DirectDraw_VTable =
545 Main_DirectDraw_QueryInterface,
546 Main_DirectDraw_AddRef,
547 Main_DirectDraw_Release,
548 Main_DirectDraw_Compact,
549 Main_DirectDraw_CreateClipper,
550 Main_DirectDraw_CreatePalette,
551 Main_DirectDraw_CreateSurface,
552 Main_DirectDraw_DuplicateSurface,
553 User_DirectDraw_EnumDisplayModes,
554 Main_DirectDraw_EnumSurfaces,
555 Main_DirectDraw_FlipToGDISurface,
556 Main_DirectDraw_GetCaps,
557 Main_DirectDraw_GetDisplayMode,
558 Main_DirectDraw_GetFourCCCodes,
559 Main_DirectDraw_GetGDISurface,
560 Main_DirectDraw_GetMonitorFrequency,
561 Main_DirectDraw_GetScanLine,
562 Main_DirectDraw_GetVerticalBlankStatus,
563 Main_DirectDraw_Initialize,
564 Main_DirectDraw_RestoreDisplayMode,
565 Main_DirectDraw_SetCooperativeLevel,
566 User_DirectDraw_SetDisplayMode,
567 Main_DirectDraw_WaitForVerticalBlank,
568 Main_DirectDraw_GetAvailableVidMem,
569 Main_DirectDraw_GetSurfaceFromDC,
570 Main_DirectDraw_RestoreAllSurfaces,
571 Main_DirectDraw_TestCooperativeLevel,
572 User_DirectDraw_GetDeviceIdentifier,
573 Main_DirectDraw_StartModeTest,
574 Main_DirectDraw_EvaluateMode