1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS DirectX 4 * FILE: dll/directx/ddraw/Ddraw/ddraw_displaymode.c 5 * PURPOSE: IDirectDraw7 Implementation 6 * PROGRAMMER: Maarten Bosma, Magnus Olsen (add seh support) 7 * 8 */ 9 10 11 #include "rosdraw.h" 12 13 HRESULT WINAPI 14 Main_DirectDraw_EnumDisplayModes(LPDDRAWI_DIRECTDRAW_INT This, DWORD dwFlags, 15 LPDDSURFACEDESC pDDSD, LPVOID pContext, LPDDENUMMODESCALLBACK pCallback) 16 { 17 HRESULT ret = DD_OK; 18 INT iMode = 0; 19 DEVMODE DevMode; 20 21 DX_WINDBG_trace(); 22 23 ZeroMemory(&DevMode, sizeof(DEVMODE)); 24 25 _SEH2_TRY 26 { 27 28 if (pDDSD != NULL) 29 { 30 if (pDDSD->dwSize != sizeof(DDSURFACEDESC)) 31 { 32 ret = DDERR_INVALIDPARAMS; 33 } 34 } 35 36 if (IsBadCodePtr((LPVOID)pCallback)) 37 { 38 ret = DDERR_INVALIDPARAMS; 39 } 40 else if ( ret == DD_OK) 41 { 42 43 DevMode.dmSize = sizeof(DEVMODE); 44 45 while (EnumDisplaySettingsEx(NULL, iMode, &DevMode, 0) != FALSE) 46 { 47 DDSURFACEDESC SurfaceDesc; 48 49 ZeroMemory(&SurfaceDesc, sizeof(DDSURFACEDESC)); 50 51 iMode++; 52 53 SurfaceDesc.dwSize = sizeof (DDSURFACEDESC); 54 SurfaceDesc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE; 55 SurfaceDesc.dwHeight = DevMode.dmPelsHeight; 56 SurfaceDesc.dwWidth = DevMode.dmPelsWidth; 57 SurfaceDesc.lPitch = DevMode.dmPelsWidth * DevMode.dmBitsPerPel / 8; 58 SurfaceDesc.dwRefreshRate = DevMode.dmDisplayFrequency; 59 60 SurfaceDesc.ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT); 61 SurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_RGB; 62 // FIXME: get these 63 /* 64 SurfaceDesc.ddpfPixelFormat.dwRBitMask = 65 SurfaceDesc.ddpfPixelFormat.dwGBitMask = 66 SurfaceDesc.ddpfPixelFormat.dwBBitMask = 67 SurfaceDesc.ddpfPixelFormat.dwRGBAlphaBitMask = 68 */ 69 SurfaceDesc.ddpfPixelFormat.dwRGBBitCount = DevMode.dmBitsPerPel; 70 71 // FIXME1: This->lpLcl->lpGbl->dwMonitorFrequency is not set ! 72 if(dwFlags & DDEDM_REFRESHRATES && SurfaceDesc.dwRefreshRate != This->lpLcl->lpGbl->dwMonitorFrequency) 73 { 74 //continue; // FIXME2: what is SurfaceDesc.dwRefreshRate supposed to be set to ? 75 } 76 77 // FIXME: Take case when DDEDM_STANDARDVGAMODES flag is not set in account 78 79 if(pDDSD) 80 { 81 if (pDDSD->dwFlags & DDSD_HEIGHT && pDDSD->dwHeight != SurfaceDesc.dwHeight) 82 continue; 83 84 if (pDDSD->dwFlags & DDSD_WIDTH && pDDSD->dwWidth != SurfaceDesc.dwWidth) 85 continue; 86 87 if (pDDSD->dwFlags & DDSD_PITCH && pDDSD->lPitch != SurfaceDesc.lPitch) 88 continue; 89 90 if (pDDSD->dwFlags & DDSD_REFRESHRATE && pDDSD->dwRefreshRate != SurfaceDesc.dwRefreshRate) 91 continue; 92 93 if (pDDSD->dwFlags & DDSD_PIXELFORMAT && pDDSD->ddpfPixelFormat.dwRGBBitCount != SurfaceDesc.ddpfPixelFormat.dwRGBBitCount) 94 continue; // FIXME: test for the other members of ddpfPixelFormat as well 95 } 96 97 if((*pCallback)(&SurfaceDesc, pContext) == DDENUMRET_CANCEL) 98 break; 99 } 100 } 101 102 } 103 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 104 { 105 } 106 _SEH2_END; 107 108 return ret; 109 } 110 111 HRESULT WINAPI 112 Main_DirectDraw_EnumDisplayModes4(LPDDRAWI_DIRECTDRAW_INT This, DWORD dwFlags, 113 LPDDSURFACEDESC2 pDDSD, LPVOID pContext, LPDDENUMMODESCALLBACK2 pCallback) 114 { 115 HRESULT ret = DD_OK; 116 INT iMode = 0; 117 DEVMODE DevMode; 118 119 DX_WINDBG_trace(); 120 121 ZeroMemory(&DevMode, sizeof(DEVMODE)); 122 123 _SEH2_TRY 124 { 125 126 if (pDDSD != NULL) 127 { 128 if (pDDSD->dwSize != sizeof(DDSURFACEDESC2)) 129 { 130 ret = DDERR_INVALIDPARAMS; 131 } 132 } 133 134 if (IsBadCodePtr((LPVOID)pCallback)) 135 { 136 ret = DDERR_INVALIDPARAMS; 137 } 138 else if ( ret == DD_OK) 139 { 140 141 DevMode.dmSize = sizeof(DEVMODE); 142 143 while (EnumDisplaySettingsEx(NULL, iMode, &DevMode, 0) != FALSE) 144 { 145 DDSURFACEDESC2 SurfaceDesc; 146 147 ZeroMemory(&SurfaceDesc, sizeof(DDSURFACEDESC2)); 148 149 iMode++; 150 151 SurfaceDesc.dwSize = sizeof (DDSURFACEDESC2); 152 SurfaceDesc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE; 153 SurfaceDesc.dwHeight = DevMode.dmPelsHeight; 154 SurfaceDesc.dwWidth = DevMode.dmPelsWidth; 155 SurfaceDesc.lPitch = DevMode.dmPelsWidth * DevMode.dmBitsPerPel / 8; 156 SurfaceDesc.dwRefreshRate = DevMode.dmDisplayFrequency; 157 158 SurfaceDesc.ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT); 159 SurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_RGB; 160 // FIXME: get these 161 /* 162 SurfaceDesc.ddpfPixelFormat.dwRBitMask = 163 SurfaceDesc.ddpfPixelFormat.dwGBitMask = 164 SurfaceDesc.ddpfPixelFormat.dwBBitMask = 165 SurfaceDesc.ddpfPixelFormat.dwRGBAlphaBitMask = 166 */ 167 SurfaceDesc.ddpfPixelFormat.dwRGBBitCount = DevMode.dmBitsPerPel; 168 169 // FIXME1: This->lpLcl->lpGbl->dwMonitorFrequency is not set ! 170 if(dwFlags & DDEDM_REFRESHRATES && SurfaceDesc.dwRefreshRate != This->lpLcl->lpGbl->dwMonitorFrequency) 171 { 172 //continue; // FIXME2: what is SurfaceDesc.dwRefreshRate supposed to be set to ? 173 } 174 175 // FIXME: Take case when DDEDM_STANDARDVGAMODES flag is not set in account 176 177 if(pDDSD) 178 { 179 if (pDDSD->dwFlags & DDSD_HEIGHT && pDDSD->dwHeight != SurfaceDesc.dwHeight) 180 continue; 181 182 if (pDDSD->dwFlags & DDSD_WIDTH && pDDSD->dwWidth != SurfaceDesc.dwWidth) 183 continue; 184 185 if (pDDSD->dwFlags & DDSD_PITCH && pDDSD->lPitch != SurfaceDesc.lPitch) 186 continue; 187 188 if (pDDSD->dwFlags & DDSD_REFRESHRATE && pDDSD->dwRefreshRate != SurfaceDesc.dwRefreshRate) 189 continue; 190 191 if (pDDSD->dwFlags & DDSD_PIXELFORMAT && pDDSD->ddpfPixelFormat.dwRGBBitCount != SurfaceDesc.ddpfPixelFormat.dwRGBBitCount) 192 continue; // FIXME: test for the other members of ddpfPixelFormat as well 193 } 194 195 if((*pCallback)(&SurfaceDesc, pContext) == DDENUMRET_CANCEL) 196 break; 197 } 198 } 199 200 } 201 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 202 { 203 } 204 _SEH2_END; 205 206 return ret; 207 } 208 209 HRESULT WINAPI 210 Main_DirectDraw_SetDisplayMode (LPDDRAWI_DIRECTDRAW_INT This, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) 211 { 212 DX_WINDBG_trace(); 213 214 return Main_DirectDraw_SetDisplayMode2 (This, dwWidth, dwHeight, dwBPP, 0, 0 ); 215 } 216 217 HRESULT WINAPI 218 Main_DirectDraw_SetDisplayMode2 (LPDDRAWI_DIRECTDRAW_INT This, DWORD dwWidth, DWORD dwHeight, 219 DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) 220 { 221 HRESULT ret = DD_OK; 222 DX_WINDBG_trace(); 223 224 _SEH2_TRY 225 { 226 // FIXME: Check primary if surface is locked / busy etc. 227 228 // Check Parameters 229 if(dwFlags != 0) 230 { 231 ret = DDERR_INVALIDPARAMS; 232 } 233 else 234 { 235 if ((!dwHeight || This->lpLcl->lpGbl->vmiData.dwDisplayHeight == dwHeight) && 236 (!dwWidth || This->lpLcl->lpGbl->vmiData.dwDisplayWidth == dwWidth) && 237 (!dwBPP || This->lpLcl->lpGbl->vmiData.ddpfDisplay.dwRGBBitCount == dwBPP) && 238 (!dwRefreshRate || This->lpLcl->lpGbl->dwMonitorFrequency == dwRefreshRate)) 239 { 240 ret = DD_OK; // nothing to do here for us 241 } 242 else 243 { 244 LONG retval; 245 // Here we go 246 DEVMODE DevMode; 247 ZeroMemory(&DevMode, sizeof(DEVMODE)); 248 DevMode.dmSize = sizeof(DEVMODE); 249 250 if (dwHeight) 251 DevMode.dmFields |= DM_PELSHEIGHT; 252 if (dwWidth) 253 DevMode.dmFields |= DM_PELSWIDTH; 254 if (dwBPP) 255 DevMode.dmFields |= DM_BITSPERPEL; 256 if (dwRefreshRate) 257 DevMode.dmFields |= DM_DISPLAYFREQUENCY; 258 259 DevMode.dmPelsHeight = dwHeight; 260 DevMode.dmPelsWidth = dwWidth; 261 DevMode.dmBitsPerPel = dwBPP; 262 DevMode.dmDisplayFrequency = dwRefreshRate; 263 264 DX_WINDBG_trace_res(dwWidth, dwHeight,dwBPP, dwRefreshRate); 265 266 retval = ChangeDisplaySettings(&DevMode, CDS_FULLSCREEN); 267 /* FIXME: Are we supposed to set CDS_SET_PRIMARY as well ? */ 268 269 if(retval == DISP_CHANGE_BADMODE) 270 { 271 /* Note : it seam ms ddraw ignore this and try using the bad mode any case. 272 * tested with Ati HD2400 that only support 16 and 32 Bpp in windows 273 */ 274 DX_STUB_str("Warning ChangeDisplaySettings return DISP_CHANGE_BADMODE, but ddraw.dll ignore it\n"); 275 276 //ret = DDERR_UNSUPPORTED; 277 BOOL ModeChanged; 278 This->lpLcl->lpGbl->hDD = This->lpLcl->hDD; 279 DdReenableDirectDrawObject(This->lpLcl->lpGbl, &ModeChanged); 280 StartDirectDraw((LPDIRECTDRAW)This, 0, TRUE); 281 } 282 else if(retval != DISP_CHANGE_SUCCESSFUL) 283 { 284 ret = DDERR_GENERIC; 285 } 286 else 287 { 288 // Update Interals 289 BOOL ModeChanged; 290 This->lpLcl->lpGbl->hDD = This->lpLcl->hDD; 291 DdReenableDirectDrawObject(This->lpLcl->lpGbl, &ModeChanged); 292 StartDirectDraw((LPDIRECTDRAW)This, 0, TRUE); 293 } 294 } 295 } 296 } 297 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 298 { 299 } 300 _SEH2_END; 301 302 return ret; 303 } 304 305 HRESULT WINAPI 306 Main_DirectDraw_RestoreDisplayMode (LPDDRAWI_DIRECTDRAW_INT This) 307 { 308 DX_WINDBG_trace(); 309 310 _SEH2_TRY 311 { 312 BOOL ModeChanged; 313 314 ChangeDisplaySettings(NULL, 0); 315 316 // Update Interals 317 318 319 This->lpLcl->lpGbl->hDD = This->lpLcl->hDD; 320 DdReenableDirectDrawObject(This->lpLcl->lpGbl, &ModeChanged); 321 StartDirectDraw((LPDIRECTDRAW)This, 0, TRUE); 322 } 323 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 324 { 325 } 326 _SEH2_END; 327 328 329 return DD_OK; 330 } 331 332 HRESULT WINAPI 333 Main_DirectDraw_GetMonitorFrequency (LPDDRAWI_DIRECTDRAW_INT This, LPDWORD lpFreq) 334 { 335 HRESULT retVal = DD_OK; 336 DX_WINDBG_trace(); 337 338 _SEH2_TRY 339 { 340 if(IsBadWritePtr(lpFreq,sizeof(LPDWORD))) 341 { 342 retVal = DDERR_INVALIDPARAMS; 343 } 344 else 345 { 346 if (This->lpLcl->lpGbl->dwMonitorFrequency) 347 { 348 *lpFreq = This->lpLcl->lpGbl->dwMonitorFrequency; 349 } 350 else 351 { 352 retVal = DDERR_UNSUPPORTED; 353 } 354 } 355 } 356 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 357 { 358 retVal = DD_FALSE; 359 } 360 _SEH2_END; 361 362 return retVal; 363 } 364 365 HRESULT WINAPI 366 Main_DirectDraw_GetDisplayMode (LPDDRAWI_DIRECTDRAW_INT This, LPDDSURFACEDESC pDDSD) 367 { 368 HRESULT retVal = DD_OK; 369 DX_WINDBG_trace(); 370 371 _SEH2_TRY 372 { 373 if(IsBadWritePtr(pDDSD,sizeof(LPDDSURFACEDESC))) 374 { 375 retVal = DDERR_INVALIDPARAMS; 376 } 377 else if (pDDSD->dwSize != sizeof(DDSURFACEDESC)) 378 { 379 retVal = DDERR_INVALIDPARAMS; 380 } 381 else 382 { 383 // FIXME: More structure members might need to be filled 384 385 pDDSD->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE; 386 pDDSD->dwHeight = This->lpLcl->lpGbl->vmiData.dwDisplayHeight; 387 pDDSD->dwWidth = This->lpLcl->lpGbl->vmiData.dwDisplayWidth; 388 pDDSD->ddpfPixelFormat = This->lpLcl->lpGbl->vmiData.ddpfDisplay; 389 pDDSD->dwRefreshRate = This->lpLcl->lpGbl->dwMonitorFrequency; 390 pDDSD->lPitch = This->lpLcl->lpGbl->vmiData.lDisplayPitch; 391 } 392 } 393 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 394 { 395 } 396 _SEH2_END; 397 398 return retVal; 399 } 400 401 HRESULT WINAPI 402 Main_DirectDraw_GetDisplayMode4 (LPDDRAWI_DIRECTDRAW_INT This, LPDDSURFACEDESC2 pDDSD) 403 { 404 HRESULT retVal = DD_OK; 405 DX_WINDBG_trace(); 406 407 _SEH2_TRY 408 { 409 if(IsBadWritePtr(pDDSD,sizeof(LPDDSURFACEDESC2))) 410 { 411 retVal = DDERR_INVALIDPARAMS; 412 } 413 else if (pDDSD->dwSize != sizeof(DDSURFACEDESC2)) 414 { 415 retVal = DDERR_INVALIDPARAMS; 416 } 417 else 418 { 419 // FIXME: More structure members might need to be filled 420 421 pDDSD->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE; 422 pDDSD->dwHeight = This->lpLcl->lpGbl->vmiData.dwDisplayHeight; 423 pDDSD->dwWidth = This->lpLcl->lpGbl->vmiData.dwDisplayWidth; 424 pDDSD->ddpfPixelFormat = This->lpLcl->lpGbl->vmiData.ddpfDisplay; 425 pDDSD->dwRefreshRate = This->lpLcl->lpGbl->dwMonitorFrequency; 426 pDDSD->lPitch = This->lpLcl->lpGbl->vmiData.lDisplayPitch; 427 } 428 } 429 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 430 { 431 } 432 _SEH2_END; 433 434 return retVal; 435 } 436