diff --git a/dlls/user/tests/monitor.c b/dlls/user/tests/monitor.c index 82831bd268f..157649aa7a3 100644 --- a/dlls/user/tests/monitor.c +++ b/dlls/user/tests/monitor.c @@ -97,9 +97,59 @@ static void test_enumdisplaydevices(void) } } +struct vid_mode +{ + DWORD w, h, bpp, freq, fields; + LONG res; +}; + +static struct vid_mode vid_modes_test[] = { + {640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY, DISP_CHANGE_SUCCESSFUL}, + {640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY, DISP_CHANGE_SUCCESSFUL}, + {640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL , DISP_CHANGE_SUCCESSFUL}, + {640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT , DISP_CHANGE_SUCCESSFUL}, + {640, 480, 0, 0, DM_BITSPERPEL , DISP_CHANGE_SUCCESSFUL}, + {640, 480, 0, 0, DM_DISPLAYFREQUENCY, DISP_CHANGE_SUCCESSFUL}, + + {0, 0, 0, 0, DM_PELSWIDTH, DISP_CHANGE_SUCCESSFUL}, + {0, 0, 0, 0, DM_PELSHEIGHT, DISP_CHANGE_SUCCESSFUL}, + + {640, 480, 0, 0, DM_PELSWIDTH, DISP_CHANGE_BADMODE}, + {640, 480, 0, 0, DM_PELSHEIGHT, DISP_CHANGE_BADMODE}, + { 0, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT, DISP_CHANGE_BADMODE}, + {640, 0, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT, DISP_CHANGE_BADMODE}, + + {0, 0, 0, 10, DM_DISPLAYFREQUENCY, DISP_CHANGE_BADMODE}, +}; +#define vid_modes_cnt (sizeof(vid_modes_test) / sizeof(vid_modes_test[0])) + +static void test_ChangeDisplaySettingsEx(void) +{ + DEVMODE dm; + LONG res; + int i; + + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + + for (i = 0; i < vid_modes_cnt; i++) + { + dm.dmPelsWidth = vid_modes_test[i].w; + dm.dmPelsHeight = vid_modes_test[i].h; + dm.dmBitsPerPel = vid_modes_test[i].bpp; + dm.dmDisplayFrequency = vid_modes_test[i].freq; + dm.dmFields = vid_modes_test[i].fields; + res = ChangeDisplaySettingsEx(NULL, &dm, NULL, CDS_FULLSCREEN, NULL); + ok(res == vid_modes_test[i].res, "Failed to change resolution[%d]: %ld\n", i, res); + } + res = ChangeDisplaySettingsEx(NULL, NULL, NULL, CDS_RESET, NULL); + ok(res == DISP_CHANGE_SUCCESSFUL, "Failed to reset default resolution: %ld\n", res); +} + START_TEST(monitor) { init_function_pointers(); test_enumdisplaydevices(); + test_ChangeDisplaySettingsEx(); } diff --git a/dlls/winex11.drv/settings.c b/dlls/winex11.drv/settings.c index 95e88e61088..49b8a8d5db0 100644 --- a/dlls/winex11.drv/settings.c +++ b/dlls/winex11.drv/settings.c @@ -237,8 +237,9 @@ static const char * _DM_fields(DWORD fields) LONG X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode, HWND hwnd, DWORD flags, LPVOID lpvoid ) { - DWORD i, dwBpp; + DWORD i, dwBpp = 0; DEVMODEW dm; + BOOL def_mode = TRUE; TRACE("(%s,%p,%p,0x%08lx,%p)\n",debugstr_w(devname),devmode,hwnd,flags,lpvoid); TRACE("flags=%s\n",_CDS_flags(flags)); @@ -248,8 +249,15 @@ LONG X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode, TRACE("width=%ld height=%ld bpp=%ld freq=%ld (%s)\n", devmode->dmPelsWidth,devmode->dmPelsHeight, devmode->dmBitsPerPel,devmode->dmDisplayFrequency, handler_name); + + dwBpp = (devmode->dmBitsPerPel == 24) ? 32 : devmode->dmBitsPerPel; + if (devmode->dmFields & DM_BITSPERPEL) def_mode &= !dwBpp; + if (devmode->dmFields & DM_PELSWIDTH) def_mode &= !devmode->dmPelsWidth; + if (devmode->dmFields & DM_PELSHEIGHT) def_mode &= !devmode->dmPelsHeight; + if (devmode->dmFields & DM_DISPLAYFREQUENCY) def_mode &= !devmode->dmDisplayFrequency; } - else + + if (def_mode) { TRACE("Return to original display mode (%s)\n", handler_name); if (!X11DRV_EnumDisplaySettingsEx(devname, dd_mode_default, &dm, 0)) @@ -259,7 +267,10 @@ LONG X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode, } devmode = &dm; } - dwBpp = (devmode->dmBitsPerPel == 24) ? 32 : devmode->dmBitsPerPel; + dwBpp = !dwBpp ? dd_modes[dd_mode_default].dwBPP : dwBpp; + + if ((devmode->dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT)) + return DISP_CHANGE_BADMODE; for (i = 0; i < dd_mode_count; i++) { @@ -278,7 +289,8 @@ LONG X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode, if (devmode->dmPelsHeight != dd_modes[i].dwHeight) continue; } - if ((devmode->dmFields & DM_DISPLAYFREQUENCY) && (dd_modes[i].wRefreshRate != 0)) + if ((devmode->dmFields & DM_DISPLAYFREQUENCY) && (dd_modes[i].wRefreshRate != 0) && + devmode->dmDisplayFrequency != 0) { if (devmode->dmDisplayFrequency != dd_modes[i].wRefreshRate) continue;