mirror of
https://github.com/wine-mirror/wine
synced 2024-07-01 07:14:31 +00:00
explorer: Restore display settings on process exit.
Restore display settings to the ones in the registry when CDS_FULLSCREEN is used in ChangeDisplaySettings(). Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49674
This commit is contained in:
parent
b3eb55227a
commit
89ad36b1d9
|
@ -291,8 +291,8 @@ struct device_info
|
||||||
DEVMODEA original_mode;
|
DEVMODEA original_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define expect_dm(a, b, c, d) _expect_dm(__LINE__, a, b, c, d)
|
#define expect_dm(a, b, c) _expect_dm(__LINE__, a, b, c)
|
||||||
static void _expect_dm(INT line, const DEVMODEA *expected, const CHAR *device, DWORD test, BOOL todo)
|
static void _expect_dm(INT line, const DEVMODEA *expected, const CHAR *device, DWORD test)
|
||||||
{
|
{
|
||||||
DEVMODEA dm;
|
DEVMODEA dm;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
@ -307,9 +307,9 @@ static void _expect_dm(INT line, const DEVMODEA *expected, const CHAR *device, D
|
||||||
"Device %s test %ld expect dmFields to contain %#lx, got %#lx\n", device, test, expected->dmFields, dm.dmFields);
|
"Device %s test %ld expect dmFields to contain %#lx, got %#lx\n", device, test, expected->dmFields, dm.dmFields);
|
||||||
ok_(__FILE__, line)(!(expected->dmFields & DM_BITSPERPEL) || dm.dmBitsPerPel == expected->dmBitsPerPel,
|
ok_(__FILE__, line)(!(expected->dmFields & DM_BITSPERPEL) || dm.dmBitsPerPel == expected->dmBitsPerPel,
|
||||||
"Device %s test %ld expect dmBitsPerPel %lu, got %lu\n", device, test, expected->dmBitsPerPel, dm.dmBitsPerPel);
|
"Device %s test %ld expect dmBitsPerPel %lu, got %lu\n", device, test, expected->dmBitsPerPel, dm.dmBitsPerPel);
|
||||||
todo_wine_if(todo) ok_(__FILE__, line)(!(expected->dmFields & DM_PELSWIDTH) || dm.dmPelsWidth == expected->dmPelsWidth,
|
ok_(__FILE__, line)(!(expected->dmFields & DM_PELSWIDTH) || dm.dmPelsWidth == expected->dmPelsWidth,
|
||||||
"Device %s test %ld expect dmPelsWidth %lu, got %lu\n", device, test, expected->dmPelsWidth, dm.dmPelsWidth);
|
"Device %s test %ld expect dmPelsWidth %lu, got %lu\n", device, test, expected->dmPelsWidth, dm.dmPelsWidth);
|
||||||
todo_wine_if(todo) ok_(__FILE__, line)(!(expected->dmFields & DM_PELSHEIGHT) || dm.dmPelsHeight == expected->dmPelsHeight,
|
ok_(__FILE__, line)(!(expected->dmFields & DM_PELSHEIGHT) || dm.dmPelsHeight == expected->dmPelsHeight,
|
||||||
"Device %s test %ld expect dmPelsHeight %lu, got %lu\n", device, test, expected->dmPelsHeight, dm.dmPelsHeight);
|
"Device %s test %ld expect dmPelsHeight %lu, got %lu\n", device, test, expected->dmPelsHeight, dm.dmPelsHeight);
|
||||||
ok_(__FILE__, line)(!(expected->dmFields & DM_POSITION) || dm.dmPosition.x == expected->dmPosition.x,
|
ok_(__FILE__, line)(!(expected->dmFields & DM_POSITION) || dm.dmPosition.x == expected->dmPosition.x,
|
||||||
"Device %s test %ld expect dmPosition.x %ld, got %ld\n", device, test, expected->dmPosition.x, dm.dmPosition.x);
|
"Device %s test %ld expect dmPosition.x %ld, got %ld\n", device, test, expected->dmPosition.x, dm.dmPosition.x);
|
||||||
|
@ -325,8 +325,8 @@ static void _expect_dm(INT line, const DEVMODEA *expected, const CHAR *device, D
|
||||||
dm.dmDisplayOrientation);
|
dm.dmDisplayOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define wait_for_dm(a, b, c, d) wait_for_dm_(__LINE__, a, b, c, d)
|
#define wait_for_dm(a, b, c) wait_for_dm_(__LINE__, a, b, c)
|
||||||
static void wait_for_dm_(int line, const char *device, DWORD expected_width, DWORD expected_height, BOOL todo)
|
static void wait_for_dm_(int line, const char *device, DWORD expected_width, DWORD expected_height)
|
||||||
{
|
{
|
||||||
DEVMODEA dm;
|
DEVMODEA dm;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
@ -346,9 +346,9 @@ static void wait_for_dm_(int line, const char *device, DWORD expected_width, DWO
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
todo_wine_if(todo) ok_(__FILE__, line)(dm.dmPelsWidth == expected_width,
|
ok_(__FILE__, line)(dm.dmPelsWidth == expected_width,
|
||||||
"Device %s expect dmPelsWidth %lu, got %lu\n", device, expected_width, dm.dmPelsWidth);
|
"Device %s expect dmPelsWidth %lu, got %lu\n", device, expected_width, dm.dmPelsWidth);
|
||||||
todo_wine_if(todo) ok_(__FILE__, line)(dm.dmPelsHeight == expected_height,
|
ok_(__FILE__, line)(dm.dmPelsHeight == expected_height,
|
||||||
"Device %s expect dmPelsHeight %lu, got %lu\n", device, expected_height, dm.dmPelsHeight);
|
"Device %s expect dmPelsHeight %lu, got %lu\n", device, expected_height, dm.dmPelsHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,7 +729,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
flush_events();
|
flush_events();
|
||||||
expect_dm(&dm3, devices[device].name, test, FALSE);
|
expect_dm(&dm3, devices[device].name, test);
|
||||||
|
|
||||||
/* Change the registry mode to the second mode */
|
/* Change the registry mode to the second mode */
|
||||||
res = ChangeDisplaySettingsExA(devices[device].name, &dm2, NULL, CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
|
res = ChangeDisplaySettingsExA(devices[device].name, &dm2, NULL, CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
|
||||||
|
@ -863,7 +863,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
flush_events();
|
flush_events();
|
||||||
expect_dm(&dm, devices[device].name, mode, FALSE);
|
expect_dm(&dm, devices[device].name, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore settings */
|
/* Restore settings */
|
||||||
|
@ -936,7 +936,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
flush_events();
|
flush_events();
|
||||||
expect_dm(&dm, devices[device].name, 0, FALSE);
|
expect_dm(&dm, devices[device].name, 0);
|
||||||
|
|
||||||
/* Test specifying only position, width and height */
|
/* Test specifying only position, width and height */
|
||||||
memset(&dm, 0, sizeof(dm));
|
memset(&dm, 0, sizeof(dm));
|
||||||
|
@ -981,7 +981,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
ok(dm.dmBitsPerPel, "Expected dmBitsPerPel not zero.\n");
|
ok(dm.dmBitsPerPel, "Expected dmBitsPerPel not zero.\n");
|
||||||
ok(dm.dmDisplayFrequency, "Expected dmDisplayFrequency not zero.\n");
|
ok(dm.dmDisplayFrequency, "Expected dmDisplayFrequency not zero.\n");
|
||||||
|
|
||||||
expect_dm(&dm, devices[device].name, 0, FALSE);
|
expect_dm(&dm, devices[device].name, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test dmPosition */
|
/* Test dmPosition */
|
||||||
|
@ -1053,7 +1053,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
ok(res == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExA %s returned unexpected %ld\n", devices[1].name, res);
|
ok(res == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExA %s returned unexpected %ld\n", devices[1].name, res);
|
||||||
|
|
||||||
dm2.dmPosition.x = dm.dmPosition.x + dm.dmPelsWidth;
|
dm2.dmPosition.x = dm.dmPosition.x + dm.dmPelsWidth;
|
||||||
expect_dm(&dm2, devices[1].name, 0, FALSE);
|
expect_dm(&dm2, devices[1].name, 0);
|
||||||
|
|
||||||
/* Test placing the secondary adapter to all sides of the primary adapter */
|
/* Test placing the secondary adapter to all sides of the primary adapter */
|
||||||
for (test = 0; test < 8; ++test)
|
for (test = 0; test < 8; ++test)
|
||||||
|
@ -1112,7 +1112,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
flush_events();
|
flush_events();
|
||||||
expect_dm(&dm2, devices[1].name, test, FALSE);
|
expect_dm(&dm2, devices[1].name, test);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test automatic position update when other adapters change resolution */
|
/* Test automatic position update when other adapters change resolution */
|
||||||
|
@ -1177,7 +1177,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
ok(res == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExA %s mode %d returned unexpected %ld.\n",
|
ok(res == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExA %s mode %d returned unexpected %ld.\n",
|
||||||
devices[device].name, mode, res);
|
devices[device].name, mode, res);
|
||||||
flush_events();
|
flush_events();
|
||||||
expect_dm(&dm2, devices[device].name, mode, FALSE);
|
expect_dm(&dm2, devices[device].name, mode);
|
||||||
|
|
||||||
/* EnumDisplaySettingsEx without EDS_ROTATEDMODE reports modes with current orientation */
|
/* EnumDisplaySettingsEx without EDS_ROTATEDMODE reports modes with current orientation */
|
||||||
memset(&dm3, 0, sizeof(dm3));
|
memset(&dm3, 0, sizeof(dm3));
|
||||||
|
@ -1258,13 +1258,13 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
|
|
||||||
dm.dmPelsWidth = 640;
|
dm.dmPelsWidth = 640;
|
||||||
dm.dmPelsHeight = 480;
|
dm.dmPelsHeight = 480;
|
||||||
expect_dm(&dm, devices[0].name, 0, FALSE);
|
expect_dm(&dm, devices[0].name, 0);
|
||||||
|
|
||||||
SetEvent(exit_event1);
|
SetEvent(exit_event1);
|
||||||
wait_result = WaitForSingleObject(process1, 5000);
|
wait_result = WaitForSingleObject(process1, 5000);
|
||||||
ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result);
|
ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result);
|
||||||
|
|
||||||
wait_for_dm(devices[0].name, 800, 600, TRUE);
|
wait_for_dm(devices[0].name, 800, 600);
|
||||||
|
|
||||||
CloseHandle(process1);
|
CloseHandle(process1);
|
||||||
CloseHandle(process0);
|
CloseHandle(process0);
|
||||||
|
@ -1278,7 +1278,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
wait_result = WaitForSingleObject(process1, 5000);
|
wait_result = WaitForSingleObject(process1, 5000);
|
||||||
ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result);
|
ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result);
|
||||||
|
|
||||||
wait_for_dm(devices[0].name, 800, 600, TRUE);
|
wait_for_dm(devices[0].name, 800, 600);
|
||||||
|
|
||||||
SetEvent(exit_event0);
|
SetEvent(exit_event0);
|
||||||
wait_result = WaitForSingleObject(process0, 5000);
|
wait_result = WaitForSingleObject(process0, 5000);
|
||||||
|
@ -1300,7 +1300,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
|
|
||||||
dm.dmPelsWidth = 640;
|
dm.dmPelsWidth = 640;
|
||||||
dm.dmPelsHeight = 480;
|
dm.dmPelsHeight = 480;
|
||||||
expect_dm(&dm, devices[0].name, 0, FALSE);
|
expect_dm(&dm, devices[0].name, 0);
|
||||||
|
|
||||||
SetEvent(exit_event1);
|
SetEvent(exit_event1);
|
||||||
wait_result = WaitForSingleObject(process1, 5000);
|
wait_result = WaitForSingleObject(process1, 5000);
|
||||||
|
@ -1310,7 +1310,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
|
|
||||||
dm.dmPelsWidth = 640;
|
dm.dmPelsWidth = 640;
|
||||||
dm.dmPelsHeight = 480;
|
dm.dmPelsHeight = 480;
|
||||||
expect_dm(&dm, devices[0].name, 0, FALSE);
|
expect_dm(&dm, devices[0].name, 0);
|
||||||
|
|
||||||
CloseHandle(process1);
|
CloseHandle(process1);
|
||||||
CloseHandle(process0);
|
CloseHandle(process0);
|
||||||
|
@ -1328,7 +1328,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
|
|
||||||
dm.dmPelsWidth = 640;
|
dm.dmPelsWidth = 640;
|
||||||
dm.dmPelsHeight = 480;
|
dm.dmPelsHeight = 480;
|
||||||
expect_dm(&dm, devices[0].name, 0, FALSE);
|
expect_dm(&dm, devices[0].name, 0);
|
||||||
|
|
||||||
SetEvent(exit_event0);
|
SetEvent(exit_event0);
|
||||||
wait_result = WaitForSingleObject(process0, 5000);
|
wait_result = WaitForSingleObject(process0, 5000);
|
||||||
|
@ -1338,7 +1338,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
|
|
||||||
dm.dmPelsWidth = 640;
|
dm.dmPelsWidth = 640;
|
||||||
dm.dmPelsHeight = 480;
|
dm.dmPelsHeight = 480;
|
||||||
expect_dm(&dm, devices[0].name, 0, FALSE);
|
expect_dm(&dm, devices[0].name, 0);
|
||||||
|
|
||||||
CloseHandle(process1);
|
CloseHandle(process1);
|
||||||
CloseHandle(process0);
|
CloseHandle(process0);
|
||||||
|
@ -1363,8 +1363,8 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
wait_result = WaitForSingleObject(process0, 5000);
|
wait_result = WaitForSingleObject(process0, 5000);
|
||||||
ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result);
|
ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result);
|
||||||
|
|
||||||
wait_for_dm(devices[0].name, 800, 600, TRUE);
|
wait_for_dm(devices[0].name, 800, 600);
|
||||||
wait_for_dm(devices[1].name, 800, 600, TRUE);
|
wait_for_dm(devices[1].name, 800, 600);
|
||||||
|
|
||||||
CloseHandle(process0);
|
CloseHandle(process0);
|
||||||
}
|
}
|
||||||
|
@ -1387,7 +1387,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
|
||||||
broken(res == DISP_CHANGE_FAILED), /* win8 TestBot */
|
broken(res == DISP_CHANGE_FAILED), /* win8 TestBot */
|
||||||
"ChangeDisplaySettingsExA returned unexpected %ld\n", res);
|
"ChangeDisplaySettingsExA returned unexpected %ld\n", res);
|
||||||
for (device = 0; device < device_count; ++device)
|
for (device = 0; device < device_count; ++device)
|
||||||
expect_dm(&devices[device].original_mode, devices[device].name, 0, FALSE);
|
expect_dm(&devices[device].original_mode, devices[device].name, 0);
|
||||||
|
|
||||||
free(devices);
|
free(devices);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3149,9 +3149,13 @@ static BOOL all_detached_settings( const DEVMODEW *displays )
|
||||||
static LONG apply_display_settings( struct source *target, const DEVMODEW *devmode,
|
static LONG apply_display_settings( struct source *target, const DEVMODEW *devmode,
|
||||||
HWND hwnd, DWORD flags, void *lparam )
|
HWND hwnd, DWORD flags, void *lparam )
|
||||||
{
|
{
|
||||||
|
static const WCHAR restorerW[] = {'_','_','w','i','n','e','_','d','i','s','p','l','a','y','_',
|
||||||
|
's','e','t','t','i','n','g','s','_','r','e','s','t','o','r','e','r',0};
|
||||||
|
UNICODE_STRING restoter_str = RTL_CONSTANT_STRING( restorerW );
|
||||||
WCHAR primary_name[CCHDEVICENAME];
|
WCHAR primary_name[CCHDEVICENAME];
|
||||||
struct source *primary, *source;
|
struct source *primary, *source;
|
||||||
DEVMODEW *mode, *displays;
|
DEVMODEW *mode, *displays;
|
||||||
|
HWND restorer_window;
|
||||||
LONG ret;
|
LONG ret;
|
||||||
|
|
||||||
if (!lock_display_devices()) return DISP_CHANGE_FAILED;
|
if (!lock_display_devices()) return DISP_CHANGE_FAILED;
|
||||||
|
@ -3200,6 +3204,15 @@ static LONG apply_display_settings( struct source *target, const DEVMODEW *devmo
|
||||||
free( displays );
|
free( displays );
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
|
|
||||||
|
if ((restorer_window = NtUserFindWindowEx( NULL, NULL, &restoter_str, NULL, 0 )))
|
||||||
|
{
|
||||||
|
if (NtUserGetWindowThread( restorer_window, NULL ) != GetCurrentThreadId())
|
||||||
|
{
|
||||||
|
DWORD fullscreen_process_id = (flags & CDS_FULLSCREEN) ? GetCurrentProcessId() : 0;
|
||||||
|
send_message( restorer_window, WM_USER + 0, 0, fullscreen_process_id );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!update_display_cache( TRUE ))
|
if (!update_display_cache( TRUE ))
|
||||||
WARN( "Failed to update display cache after mode change.\n" );
|
WARN( "Failed to update display cache after mode change.\n" );
|
||||||
|
|
||||||
|
|
|
@ -613,6 +613,18 @@ static void initialize_launchers( HWND hwnd )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wait_named_mutex( const WCHAR *name )
|
||||||
|
{
|
||||||
|
HANDLE mutex;
|
||||||
|
|
||||||
|
mutex = CreateMutexW( NULL, TRUE, name );
|
||||||
|
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
||||||
|
{
|
||||||
|
TRACE( "waiting for mutex %s\n", debugstr_w( name ));
|
||||||
|
WaitForSingleObject( mutex, INFINITE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* wait_clipboard_mutex
|
* wait_clipboard_mutex
|
||||||
*
|
*
|
||||||
|
@ -622,7 +634,6 @@ static BOOL wait_clipboard_mutex(void)
|
||||||
{
|
{
|
||||||
static const WCHAR prefix[] = L"__wine_clipboard_";
|
static const WCHAR prefix[] = L"__wine_clipboard_";
|
||||||
WCHAR buffer[MAX_PATH + ARRAY_SIZE( prefix )];
|
WCHAR buffer[MAX_PATH + ARRAY_SIZE( prefix )];
|
||||||
HANDLE mutex;
|
|
||||||
|
|
||||||
memcpy( buffer, prefix, sizeof(prefix) );
|
memcpy( buffer, prefix, sizeof(prefix) );
|
||||||
if (!GetUserObjectInformationW( GetProcessWindowStation(), UOI_NAME,
|
if (!GetUserObjectInformationW( GetProcessWindowStation(), UOI_NAME,
|
||||||
|
@ -632,12 +643,7 @@ static BOOL wait_clipboard_mutex(void)
|
||||||
ERR( "failed to get winstation name\n" );
|
ERR( "failed to get winstation name\n" );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
mutex = CreateMutexW( NULL, TRUE, buffer );
|
wait_named_mutex( buffer );
|
||||||
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
|
||||||
{
|
|
||||||
TRACE( "waiting for mutex %s\n", debugstr_w( buffer ));
|
|
||||||
WaitForSingleObject( mutex, INFINITE );
|
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,6 +704,87 @@ static DWORD WINAPI clipboard_thread( void *arg )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HANDLE fullscreen_process;
|
||||||
|
|
||||||
|
static LRESULT WINAPI display_settings_restorer_wndproc( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
|
||||||
|
{
|
||||||
|
TRACE( "got msg %04x wp %Ix lp %Ix\n", message, wp, lp );
|
||||||
|
|
||||||
|
switch(message)
|
||||||
|
{
|
||||||
|
case WM_USER + 0:
|
||||||
|
TRACE( "fullscreen process id %Iu.\n", lp );
|
||||||
|
|
||||||
|
if (fullscreen_process)
|
||||||
|
{
|
||||||
|
CloseHandle( fullscreen_process );
|
||||||
|
fullscreen_process = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lp)
|
||||||
|
fullscreen_process = OpenProcess( SYNCHRONIZE, FALSE, lp );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefWindowProcW( hwnd, message, wp, lp );
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD WINAPI display_settings_restorer_thread( void *param )
|
||||||
|
{
|
||||||
|
static const WCHAR *display_settings_restorer_classname = L"__wine_display_settings_restorer";
|
||||||
|
DWORD wait_result;
|
||||||
|
WNDCLASSW class;
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
|
SetThreadDescription( GetCurrentThread(), L"wine_explorer_display_settings_restorer" );
|
||||||
|
|
||||||
|
wait_named_mutex( L"__wine_display_settings_restorer_mutex" );
|
||||||
|
|
||||||
|
memset( &class, 0, sizeof(class) );
|
||||||
|
class.lpfnWndProc = display_settings_restorer_wndproc;
|
||||||
|
class.lpszClassName = display_settings_restorer_classname;
|
||||||
|
|
||||||
|
if (!RegisterClassW( &class ) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
|
||||||
|
{
|
||||||
|
ERR( "could not register display settings restorer window class err %lu\n", GetLastError() );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!CreateWindowW( display_settings_restorer_classname, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, NULL ))
|
||||||
|
{
|
||||||
|
WARN( "failed to create display settings restorer window err %lu\n", GetLastError() );
|
||||||
|
UnregisterClassW( display_settings_restorer_classname, NULL );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (PeekMessageW( &msg, NULL, 0, 0, PM_REMOVE ))
|
||||||
|
{
|
||||||
|
if (msg.message == WM_QUIT)
|
||||||
|
break;
|
||||||
|
DispatchMessageW( &msg );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_result = MsgWaitForMultipleObjects( fullscreen_process ? 1 : 0, &fullscreen_process,
|
||||||
|
FALSE, INFINITE, QS_ALLINPUT );
|
||||||
|
if (wait_result == WAIT_FAILED)
|
||||||
|
break;
|
||||||
|
if (!fullscreen_process || wait_result != WAIT_OBJECT_0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TRACE( "restoring display settings on process exit\n" );
|
||||||
|
|
||||||
|
ChangeDisplaySettingsExW( NULL, NULL, NULL, 0, NULL );
|
||||||
|
|
||||||
|
CloseHandle( fullscreen_process );
|
||||||
|
fullscreen_process = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static WNDPROC desktop_orig_wndproc;
|
static WNDPROC desktop_orig_wndproc;
|
||||||
|
|
||||||
/* window procedure for the desktop window */
|
/* window procedure for the desktop window */
|
||||||
|
@ -970,6 +1057,7 @@ static void initialize_display_settings( unsigned int width, unsigned int height
|
||||||
{
|
{
|
||||||
DISPLAY_DEVICEW device = {.cb = sizeof(DISPLAY_DEVICEW)};
|
DISPLAY_DEVICEW device = {.cb = sizeof(DISPLAY_DEVICEW)};
|
||||||
DWORD i = 0, flags = CDS_GLOBAL | CDS_UPDATEREGISTRY;
|
DWORD i = 0, flags = CDS_GLOBAL | CDS_UPDATEREGISTRY;
|
||||||
|
HANDLE thread;
|
||||||
|
|
||||||
/* Store current display mode in the registry */
|
/* Store current display mode in the registry */
|
||||||
while (EnumDisplayDevicesW( NULL, i++, &device, 0 ))
|
while (EnumDisplayDevicesW( NULL, i++, &device, 0 ))
|
||||||
|
@ -1002,6 +1090,9 @@ static void initialize_display_settings( unsigned int width, unsigned int height
|
||||||
if (ChangeDisplaySettingsExW( NULL, &devmode, 0, flags, NULL ))
|
if (ChangeDisplaySettingsExW( NULL, &devmode, 0, flags, NULL ))
|
||||||
ERR( "Failed to set primary display settings.\n" );
|
ERR( "Failed to set primary display settings.\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread = CreateThread( NULL, 0, display_settings_restorer_thread, NULL, 0, NULL );
|
||||||
|
if (thread) CloseHandle( thread );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_desktop_window_title( HWND hwnd, const WCHAR *name )
|
static void set_desktop_window_title( HWND hwnd, const WCHAR *name )
|
||||||
|
|
Loading…
Reference in New Issue
Block a user