3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS DirectX
5 * FILE: ddraw/ddraw/ddraw_displaymode.c
6 * PURPOSE: IDirectDraw7 Implementation
7 * PROGRAMMER: Maarten Bosma, Magnus Olsen (add seh support)
15 Main_DirectDraw_EnumDisplayModes(LPDDRAWI_DIRECTDRAW_INT This
, DWORD dwFlags
,
16 LPDDSURFACEDESC pDDSD
, LPVOID pContext
, LPDDENUMMODESCALLBACK pCallback
)
24 ZeroMemory(&DevMode
, sizeof(DEVMODE
));
31 if (pDDSD
->dwSize
!= sizeof(DDSURFACEDESC
))
33 ret
= DDERR_INVALIDPARAMS
;
37 if (IsBadCodePtr((LPVOID
)pCallback
))
39 ret
= DDERR_INVALIDPARAMS
;
41 else if ( ret
== DD_OK
)
44 DevMode
.dmSize
= sizeof(DEVMODE
);
46 while (EnumDisplaySettingsEx(NULL
, iMode
, &DevMode
, 0) == TRUE
)
48 DDSURFACEDESC SurfaceDesc
;
50 ZeroMemory(&SurfaceDesc
, sizeof(DDSURFACEDESC
));
54 SurfaceDesc
.dwSize
= sizeof (DDSURFACEDESC
);
55 SurfaceDesc
.dwFlags
= DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_REFRESHRATE
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
56 SurfaceDesc
.dwHeight
= DevMode
.dmPelsHeight
;
57 SurfaceDesc
.dwWidth
= DevMode
.dmPelsWidth
;
58 SurfaceDesc
.lPitch
= DevMode
.dmPelsWidth
* DevMode
.dmBitsPerPel
/ 8;
59 SurfaceDesc
.dwRefreshRate
= DevMode
.dmDisplayFrequency
;
61 SurfaceDesc
.ddpfPixelFormat
.dwSize
= sizeof (DDPIXELFORMAT
);
62 SurfaceDesc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
65 SurfaceDesc.ddpfPixelFormat.dwRBitMask =
66 SurfaceDesc.ddpfPixelFormat.dwGBitMask =
67 SurfaceDesc.ddpfPixelFormat.dwBBitMask =
68 SurfaceDesc.ddpfPixelFormat.dwRGBAlphaBitMask =
70 SurfaceDesc
.ddpfPixelFormat
.dwRGBBitCount
= DevMode
.dmBitsPerPel
;
72 // FIXME1: This->lpLcl->lpGbl->dwMonitorFrequency is not set !
73 if(dwFlags
& DDEDM_REFRESHRATES
&& SurfaceDesc
.dwRefreshRate
!= This
->lpLcl
->lpGbl
->dwMonitorFrequency
)
75 //continue; // FIXME2: what is SurfaceDesc.dwRefreshRate supposed to be set to ?
78 // FIXME: Take case when DDEDM_STANDARDVGAMODES flag is not set in account
82 if(pDDSD
->dwFlags
& DDSD_HEIGHT
&& pDDSD
->dwHeight
!= SurfaceDesc
.dwHeight
)
85 else if(pDDSD
->dwFlags
& DDSD_WIDTH
&& pDDSD
->dwWidth
!= SurfaceDesc
.dwWidth
)
88 else if(pDDSD
->dwFlags
& DDSD_PITCH
&& pDDSD
->lPitch
!= SurfaceDesc
.lPitch
)
91 else if(pDDSD
->dwFlags
& DDSD_REFRESHRATE
&& pDDSD
->dwRefreshRate
!= SurfaceDesc
.dwRefreshRate
)
94 else if(pDDSD
->dwFlags
& DDSD_PIXELFORMAT
&& pDDSD
->ddpfPixelFormat
.dwRGBBitCount
!= SurfaceDesc
.ddpfPixelFormat
.dwRGBBitCount
)
95 continue; // FIXME: test for the other members of ddpfPixelFormat as well
98 if((*pCallback
)(&SurfaceDesc
, pContext
) == DDENUMRET_CANCEL
)
104 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
113 Main_DirectDraw_EnumDisplayModes4(LPDDRAWI_DIRECTDRAW_INT This
, DWORD dwFlags
,
114 LPDDSURFACEDESC2 pDDSD
, LPVOID pContext
, LPDDENUMMODESCALLBACK2 pCallback
)
122 ZeroMemory(&DevMode
, sizeof(DEVMODE
));
129 if (pDDSD
->dwSize
!= sizeof(DDSURFACEDESC2
))
131 ret
= DDERR_INVALIDPARAMS
;
135 if (IsBadCodePtr((LPVOID
)pCallback
))
137 ret
= DDERR_INVALIDPARAMS
;
139 else if ( ret
== DD_OK
)
142 DevMode
.dmSize
= sizeof(DEVMODE
);
144 while (EnumDisplaySettingsEx(NULL
, iMode
, &DevMode
, 0) == TRUE
)
146 DDSURFACEDESC2 SurfaceDesc
;
148 ZeroMemory(&SurfaceDesc
, sizeof(DDSURFACEDESC2
));
152 SurfaceDesc
.dwSize
= sizeof (DDSURFACEDESC2
);
153 SurfaceDesc
.dwFlags
= DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_REFRESHRATE
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
154 SurfaceDesc
.dwHeight
= DevMode
.dmPelsHeight
;
155 SurfaceDesc
.dwWidth
= DevMode
.dmPelsWidth
;
156 SurfaceDesc
.lPitch
= DevMode
.dmPelsWidth
* DevMode
.dmBitsPerPel
/ 8;
157 SurfaceDesc
.dwRefreshRate
= DevMode
.dmDisplayFrequency
;
159 SurfaceDesc
.ddpfPixelFormat
.dwSize
= sizeof (DDPIXELFORMAT
);
160 SurfaceDesc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
163 SurfaceDesc.ddpfPixelFormat.dwRBitMask =
164 SurfaceDesc.ddpfPixelFormat.dwGBitMask =
165 SurfaceDesc.ddpfPixelFormat.dwBBitMask =
166 SurfaceDesc.ddpfPixelFormat.dwRGBAlphaBitMask =
168 SurfaceDesc
.ddpfPixelFormat
.dwRGBBitCount
= DevMode
.dmBitsPerPel
;
170 // FIXME1: This->lpLcl->lpGbl->dwMonitorFrequency is not set !
171 if(dwFlags
& DDEDM_REFRESHRATES
&& SurfaceDesc
.dwRefreshRate
!= This
->lpLcl
->lpGbl
->dwMonitorFrequency
)
173 //continue; // FIXME2: what is SurfaceDesc.dwRefreshRate supposed to be set to ?
176 // FIXME: Take case when DDEDM_STANDARDVGAMODES flag is not set in account
180 if(pDDSD
->dwFlags
& DDSD_HEIGHT
&& pDDSD
->dwHeight
!= SurfaceDesc
.dwHeight
)
183 else if(pDDSD
->dwFlags
& DDSD_WIDTH
&& pDDSD
->dwWidth
!= SurfaceDesc
.dwWidth
)
186 else if(pDDSD
->dwFlags
& DDSD_PITCH
&& pDDSD
->lPitch
!= SurfaceDesc
.lPitch
)
189 else if(pDDSD
->dwFlags
& DDSD_REFRESHRATE
&& pDDSD
->dwRefreshRate
!= SurfaceDesc
.dwRefreshRate
)
192 else if(pDDSD
->dwFlags
& DDSD_PIXELFORMAT
&& pDDSD
->ddpfPixelFormat
.dwRGBBitCount
!= SurfaceDesc
.ddpfPixelFormat
.dwRGBBitCount
)
193 continue; // FIXME: test for the other members of ddpfPixelFormat as well
196 if((*pCallback
)(&SurfaceDesc
, pContext
) == DDENUMRET_CANCEL
)
202 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
211 Main_DirectDraw_SetDisplayMode (LPDDRAWI_DIRECTDRAW_INT This
, DWORD dwWidth
, DWORD dwHeight
, DWORD dwBPP
)
215 return Main_DirectDraw_SetDisplayMode2 (This
, dwWidth
, dwHeight
, dwBPP
, 0, 0 );
219 Main_DirectDraw_SetDisplayMode2 (LPDDRAWI_DIRECTDRAW_INT This
, DWORD dwWidth
, DWORD dwHeight
,
220 DWORD dwBPP
, DWORD dwRefreshRate
, DWORD dwFlags
)
227 // FIXME: Check primary if surface is locked / busy etc.
232 ret
= DDERR_INVALIDPARAMS
;
236 if ((!dwHeight
|| This
->lpLcl
->lpGbl
->vmiData
.dwDisplayHeight
== dwHeight
) &&
237 (!dwWidth
|| This
->lpLcl
->lpGbl
->vmiData
.dwDisplayWidth
== dwWidth
) &&
238 (!dwBPP
|| This
->lpLcl
->lpGbl
->vmiData
.ddpfDisplay
.dwRGBBitCount
== dwBPP
) &&
239 (!dwRefreshRate
|| This
->lpLcl
->lpGbl
->dwMonitorFrequency
== dwRefreshRate
))
241 ret
= DD_OK
; // nothing to do here for us
248 ZeroMemory(&DevMode
, sizeof(DEVMODE
));
249 DevMode
.dmSize
= sizeof(DEVMODE
);
252 DevMode
.dmFields
|= DM_PELSHEIGHT
;
254 DevMode
.dmFields
|= DM_PELSWIDTH
;
256 DevMode
.dmFields
|= DM_BITSPERPEL
;
258 DevMode
.dmFields
|= DM_DISPLAYFREQUENCY
;
260 DevMode
.dmPelsHeight
= dwHeight
;
261 DevMode
.dmPelsWidth
= dwWidth
;
262 DevMode
.dmBitsPerPel
= dwBPP
;
263 DevMode
.dmDisplayFrequency
= dwRefreshRate
;
265 DX_WINDBG_trace_res(dwWidth
, dwHeight
,dwBPP
, dwRefreshRate
);
267 retval
= ChangeDisplaySettings(&DevMode
, CDS_FULLSCREEN
);
268 /* FIXME: Are we supposed to set CDS_SET_PRIMARY as well ? */
270 if(retval
== DISP_CHANGE_BADMODE
)
272 /* Note : it seam ms ddraw ignore this and try using the bad mode any case.
273 * tested with Ati HD2400 that only support 16 and 32 Bpp in windows
275 DX_STUB_str("Warning ChangeDisplaySettings return DISP_CHANGE_BADMODE, but ddraw.dll ignore it\n");
277 //ret = DDERR_UNSUPPORTED;
279 This
->lpLcl
->lpGbl
->hDD
= This
->lpLcl
->hDD
;
280 DdReenableDirectDrawObject(This
->lpLcl
->lpGbl
, &ModeChanged
);
281 StartDirectDraw((LPDIRECTDRAW
)This
, 0, TRUE
);
283 else if(retval
!= DISP_CHANGE_SUCCESSFUL
)
291 This
->lpLcl
->lpGbl
->hDD
= This
->lpLcl
->hDD
;
292 DdReenableDirectDrawObject(This
->lpLcl
->lpGbl
, &ModeChanged
);
293 StartDirectDraw((LPDIRECTDRAW
)This
, 0, TRUE
);
298 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
307 Main_DirectDraw_RestoreDisplayMode (LPDDRAWI_DIRECTDRAW_INT This
)
315 ChangeDisplaySettings(NULL
, 0);
320 This
->lpLcl
->lpGbl
->hDD
= This
->lpLcl
->hDD
;
321 DdReenableDirectDrawObject(This
->lpLcl
->lpGbl
, &ModeChanged
);
322 StartDirectDraw((LPDIRECTDRAW
)This
, 0, TRUE
);
324 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
334 Main_DirectDraw_GetMonitorFrequency (LPDDRAWI_DIRECTDRAW_INT This
, LPDWORD lpFreq
)
336 HRESULT retVal
= DD_OK
;
341 if(IsBadWritePtr(lpFreq
,sizeof(LPDWORD
)))
343 retVal
= DDERR_INVALIDPARAMS
;
347 if (This
->lpLcl
->lpGbl
->dwMonitorFrequency
)
349 *lpFreq
= This
->lpLcl
->lpGbl
->dwMonitorFrequency
;
353 retVal
= DDERR_UNSUPPORTED
;
357 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
367 Main_DirectDraw_GetDisplayMode (LPDDRAWI_DIRECTDRAW_INT This
, LPDDSURFACEDESC pDDSD
)
369 HRESULT retVal
= DD_OK
;
374 if(IsBadWritePtr(pDDSD
,sizeof(LPDDSURFACEDESC
)))
376 retVal
= DDERR_INVALIDPARAMS
;
378 else if (pDDSD
->dwSize
!= sizeof(DDSURFACEDESC
))
380 retVal
= DDERR_INVALIDPARAMS
;
384 // FIXME: More stucture members might need to be filled
386 pDDSD
->dwFlags
|= DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
| DDSD_PITCH
| DDSD_REFRESHRATE
;
387 pDDSD
->dwHeight
= This
->lpLcl
->lpGbl
->vmiData
.dwDisplayHeight
;
388 pDDSD
->dwWidth
= This
->lpLcl
->lpGbl
->vmiData
.dwDisplayWidth
;
389 pDDSD
->ddpfPixelFormat
= This
->lpLcl
->lpGbl
->vmiData
.ddpfDisplay
;
390 pDDSD
->dwRefreshRate
= This
->lpLcl
->lpGbl
->dwMonitorFrequency
;
391 pDDSD
->lPitch
= This
->lpLcl
->lpGbl
->vmiData
.lDisplayPitch
;
394 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
403 Main_DirectDraw_GetDisplayMode4 (LPDDRAWI_DIRECTDRAW_INT This
, LPDDSURFACEDESC2 pDDSD
)
405 HRESULT retVal
= DD_OK
;
410 if(IsBadWritePtr(pDDSD
,sizeof(LPDDSURFACEDESC2
)))
412 retVal
= DDERR_INVALIDPARAMS
;
414 else if (pDDSD
->dwSize
!= sizeof(DDSURFACEDESC2
))
416 retVal
= DDERR_INVALIDPARAMS
;
420 // FIXME: More stucture members might need to be filled
422 pDDSD
->dwFlags
|= DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
| DDSD_PITCH
| DDSD_REFRESHRATE
;
423 pDDSD
->dwHeight
= This
->lpLcl
->lpGbl
->vmiData
.dwDisplayHeight
;
424 pDDSD
->dwWidth
= This
->lpLcl
->lpGbl
->vmiData
.dwDisplayWidth
;
425 pDDSD
->ddpfPixelFormat
= This
->lpLcl
->lpGbl
->vmiData
.ddpfDisplay
;
426 pDDSD
->dwRefreshRate
= This
->lpLcl
->lpGbl
->dwMonitorFrequency
;
427 pDDSD
->lPitch
= This
->lpLcl
->lpGbl
->vmiData
.lDisplayPitch
;
430 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)