Fixed display settings and refresh rate selection for exclusive fullscreen mode. Now applies the selected settings to the preferred display instead of the primary display.

This commit is contained in:
glitchbear
2024-11-28 11:14:08 -08:00
committed by teejusb
parent 29ae636255
commit b46f929178
2 changed files with 43 additions and 11 deletions
+36 -4
View File
@@ -349,13 +349,45 @@ static DWORD WINAPI MainExceptionHandler( LPVOID lpParameter )
/* The thread that crashed was the thread that created the main window.
* Hide the window. This will also restore the video mode, if necessary. */
ShowWindow( g_hForegroundWnd, SW_HIDE );
} else {
}
else {
/* A different thread crashed. Simply kill all other windows. We can't
* safely call ShowWindow; the main thread might be deadlocked. */
RageThread::HaltAllThreads( true );
ChangeDisplaySettings( nullptr, 0 );
}
RageThread::HaltAllThreads(true);
auto deviceModeIsValid = [=](const DEVMODE& mode) {
return (mode.dmFields & DM_PELSWIDTH) && (mode.dmFields & DM_PELSHEIGHT)
&& (mode.dmFields & DM_DISPLAYFREQUENCY)
&& (mode.dmBitsPerPel >= 32 || !(mode.dmFields & DM_BITSPERPEL));
};
DEVMODE devmode;
ZeroMemory(&devmode, sizeof(DEVMODE));
devmode.dmSize = sizeof(DEVMODE);
devmode.dmDriverExtra = 0;
DWORD deviceIter = 0;
DISPLAY_DEVICE dd;
ZeroMemory(&dd, sizeof(dd));
dd.cb = sizeof(dd);
/* Since we don't know which display was modified for fullscreen exclusive mode,
* loop through all displays it could have been to restore the video mode. */
while (EnumDisplayDevices(NULL, deviceIter++, &dd, 0))
{
while (EnumDisplaySettingsEx(dd.DeviceName, ENUM_CURRENT_SETTINGS, &devmode, 0))
{
if (deviceModeIsValid(devmode))
{
ChangeDisplaySettingsEx(dd.DeviceName, nullptr, nullptr, 0, nullptr);
}
ZeroMemory(&devmode, sizeof(DEVMODE));
devmode.dmSize = sizeof(DEVMODE);
devmode.dmDriverExtra = 0;
}
}
ZeroMemory(&dd, sizeof(dd));
dd.cb = sizeof(dd);
}
InHere = false;
SetUnhandledExceptionFilter(nullptr);
+7 -7
View File
@@ -87,13 +87,13 @@ static LRESULT CALLBACK GraphicsWindow_WndProc( HWND hWnd, UINT msg, WPARAM wPar
* because that's where most other apps seem to do it. */
if( g_bHasFocus && !bHadFocus )
{
ChangeDisplaySettings( &g_FullScreenDevMode, CDS_FULLSCREEN );
ChangeDisplaySettingsEx( g_CurrentParams.sDisplayId, &g_FullScreenDevMode, nullptr, CDS_FULLSCREEN, nullptr );
ShowWindow( g_hWndMain, SW_SHOWNORMAL );
SetWindowPos( g_hWndMain, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
}
else if( !g_bHasFocus && bHadFocus )
{
ChangeDisplaySettings( nullptr, 0 );
ChangeDisplaySettingsEx(g_CurrentParams.sDisplayId, nullptr, nullptr, 0, nullptr);
}
}
@@ -228,7 +228,7 @@ RString GraphicsWindow::SetScreenMode( const VideoModeParams &p )
if( p.windowed )
{
// We're going windowed. If we were previously fullscreen, reset.
ChangeDisplaySettings( nullptr, 0 );
ChangeDisplaySettingsEx( p.sDisplayId, nullptr, nullptr, 0, nullptr );
return RString();
}
@@ -246,13 +246,13 @@ RString GraphicsWindow::SetScreenMode( const VideoModeParams &p )
DevMode.dmDisplayFrequency = p.rate;
DevMode.dmFields |= DM_DISPLAYFREQUENCY;
}
ChangeDisplaySettings( nullptr, 0 );
ChangeDisplaySettingsEx(p.sDisplayId, nullptr, nullptr, 0, nullptr);
int ret = ChangeDisplaySettings( &DevMode, CDS_FULLSCREEN );
int ret = ChangeDisplaySettingsEx( p.sDisplayId, &DevMode, nullptr, CDS_FULLSCREEN, nullptr );
if( ret != DISP_CHANGE_SUCCESSFUL && (DevMode.dmFields & DM_DISPLAYFREQUENCY) )
{
DevMode.dmFields &= ~DM_DISPLAYFREQUENCY;
ret = ChangeDisplaySettings( &DevMode, CDS_FULLSCREEN );
ret = ChangeDisplaySettingsEx( p.sDisplayId, &DevMode, nullptr, CDS_FULLSCREEN, nullptr );
}
// XXX: append error
@@ -514,7 +514,7 @@ void GraphicsWindow::Shutdown()
* It'd be nice to not do this: Windows will do it when we quit, and if
* we're shutting down OpenGL to try D3D, this will cause extra mode
* switches. However, we need to do this before displaying dialogs. */
ChangeDisplaySettings( nullptr, 0 );
ChangeDisplaySettingsEx( g_CurrentParams.sDisplayId, nullptr, nullptr, 0, nullptr );
AppInstance inst;
UnregisterClass( g_sClassName, inst );