[PATCH 2/2] user32/tests: Add more EnumDisplaySettings tests.
Zhiyi Zhang
zzhang at codeweavers.com
Tue Feb 4 01:54:51 CST 2020
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
dlls/user32/tests/sysparams.c | 282 +++++++++++++++++++++++++++++++---
1 file changed, 258 insertions(+), 24 deletions(-)
diff --git a/dlls/user32/tests/sysparams.c b/dlls/user32/tests/sysparams.c
index 431b87cde1..cf12725a45 100644
--- a/dlls/user32/tests/sysparams.c
+++ b/dlls/user32/tests/sysparams.c
@@ -3083,43 +3083,277 @@ static void test_metrics_for_dpi( int custom_dpi )
}
}
+static BOOL get_primary_adapter_name(CHAR *name)
+{
+ DISPLAY_DEVICEA dd;
+ DWORD adapter;
+
+ dd.cb = sizeof(dd);
+ for (adapter = 0; EnumDisplayDevicesA(NULL, adapter, &dd, 0); ++adapter)
+ {
+ if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
+ {
+ lstrcpyA(name, dd.DeviceName);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static BOOL CALLBACK test_enum_display_settings(HMONITOR hmonitor, HDC hdc, LPRECT rect, LPARAM lparam)
+{
+ CHAR primary_adapter[CCHDEVICENAME];
+ INT width, height;
+ BOOL primary, ret;
+ MONITORINFOEXA mi;
+ DEVMODEA dm;
+
+ memset(&mi, 0, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ ret = GetMonitorInfoA(hmonitor, (MONITORINFO *)&mi);
+ ok(ret, "GetMonitorInfoA failed, error %#x\n", GetLastError());
+
+ memset(&dm, 0, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+ ret = EnumDisplaySettingsA(mi.szDevice, ENUM_CURRENT_SETTINGS, &dm);
+ ok(ret, "EnumDisplaySettingsA failed, error %#x\n", GetLastError());
+
+ todo_wine ok((dm.dmFields & (DM_POSITION | DM_PELSWIDTH | DM_PELSHEIGHT)) == (DM_POSITION | DM_PELSWIDTH | DM_PELSHEIGHT),
+ "Unexpected dmFields %#x.\n", dm.dmFields);
+ /* Wine currently reports primary adapter positions for all adapters, same for other todo_wines in this function */
+ ret = get_primary_adapter_name(primary_adapter);
+ ok(ret, "get_primary_adapter_name failed\n");
+ primary = !lstrcmpA(primary_adapter, mi.szDevice);
+ todo_wine_if(!primary && dm.dmPosition.x != mi.rcMonitor.left)
+ ok(dm.dmPosition.x == mi.rcMonitor.left, "Expect dmPosition.x %d, got %d\n", mi.rcMonitor.left, dm.dmPosition.x);
+ todo_wine_if(!primary && dm.dmPosition.y != mi.rcMonitor.top)
+ ok(dm.dmPosition.y == mi.rcMonitor.top, "Expect dmPosition.y %d, got %d\n", mi.rcMonitor.top, dm.dmPosition.y);
+ width = mi.rcMonitor.right - mi.rcMonitor.left;
+ todo_wine_if(!primary && dm.dmPelsWidth != width)
+ ok(dm.dmPelsWidth == width, "Expect dmPelsWidth %d, got %d\n", width, dm.dmPelsWidth);
+ height = mi.rcMonitor.bottom - mi.rcMonitor.top;
+ todo_wine_if(!primary && dm.dmPelsHeight != height)
+ ok(dm.dmPelsHeight == height, "Expect dmPelsHeight %d, got %d\n", height, dm.dmPelsHeight);
+
+ return TRUE;
+}
+
static void test_EnumDisplaySettings(void)
{
- DEVMODEA devmode;
- DWORD val;
+ static const DWORD mode_fields = DM_DISPLAYORIENTATION | DM_BITSPERPEL |
+ DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY;
+ static const DWORD setting_fields = mode_fields | DM_POSITION;
+ CHAR primary_adapter[CCHDEVICENAME];
+ DPI_AWARENESS_CONTEXT ctx = NULL;
+ DWORD err, val, device, mode;
+ BOOL attached, ret;
+ DISPLAY_DEVICEA dd;
+ DEVMODEA dm, dm2;
+ DEVMODEW dmW;
HDC hdc;
- DWORD num;
- memset(&devmode, 0, sizeof(devmode));
- EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devmode);
+ /* Test invalid device names */
+ memset(&dm, 0, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+ SetLastError(0xdeadbeef);
+ ret = EnumDisplaySettingsA("invalid", ENUM_CURRENT_SETTINGS, &dm);
+ todo_wine ok(!ret, "EnumDisplaySettingsA succeeded\n");
+ ok(GetLastError() == 0xdeadbeef, "Expect error 0xdeadbeef, got %#x\n", GetLastError());
+ todo_wine ok(dm.dmFields == 0, "Expect dmFields unchanged, got %#x\n", dm.dmFields);
+ /* Monitor device names are invalid */
+ memset(&dm, 0, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+ SetLastError(0xdeadbeef);
+ ret = EnumDisplaySettingsA("\\\\.\\DISPLAY1\\Monitor0", ENUM_CURRENT_SETTINGS, &dm);
+ todo_wine ok(!ret, "EnumDisplaySettingsA succeeded\n");
+ ok(GetLastError() == 0xdeadbeef, "Expect error 0xdeadbeef, got %#x\n", GetLastError());
+ todo_wine ok(dm.dmFields == 0, "Expect dmFields unchanged, got %#x\n", dm.dmFields);
+
+ /* Test that passing NULL to device name parameter means to use the primary adapter */
+ memset(&dm, 0, sizeof(dm));
+ memset(&dm2, 0, sizeof(dm2));
+ dm.dmSize = sizeof(dm);
+ dm2.dmSize = sizeof(dm2);
+ ret = get_primary_adapter_name(primary_adapter);
+ ok(ret, "get_primary_adapter_name failed\n");
+ ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dm);
+ ok(ret, "EnumDisplaySettingsA failed, error %#x\n", GetLastError());
+ ret = EnumDisplaySettingsA(primary_adapter, ENUM_CURRENT_SETTINGS, &dm2);
+ ok(ret, "EnumDisplaySettingsA failed, error %#x\n", GetLastError());
+ ok(!memcmp(&dm, &dm2, sizeof(dm)), "Expect NULL device is the primary device.\n");
+
+ /* Test dmSize */
+ /* EnumDisplaySettingsA/W modify dmSize and don't check for insufficient dmSize */
+ memset(&dm, 0, sizeof(dm));
+ ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dm);
+ ok(ret, "EnumDisplaySettingsA failed, error %#x\n", GetLastError());
+ ok(dm.dmSize == FIELD_OFFSET(DEVMODEA, dmICMMethod), "Expect dmSize %u, got %u\n",
+ FIELD_OFFSET(DEVMODEA, dmICMMethod), dm.dmSize);
+ todo_wine ok((dm.dmFields & setting_fields) == setting_fields, "Expect dmFields to contain %#x, got %#x\n",
+ setting_fields, dm.dmFields);
+
+ memset(&dm, 0, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+ ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dm);
+ ok(ret, "EnumDisplaySettingsA failed, error %#x\n", GetLastError());
+ ok(dm.dmSize == FIELD_OFFSET(DEVMODEA, dmICMMethod), "Expect dmSize %u, got %u\n",
+ FIELD_OFFSET(DEVMODEA, dmICMMethod), dm.dmSize);
+ todo_wine ok((dm.dmFields & setting_fields) == setting_fields, "Expect dmFields to contain %#x, got %#x\n",
+ setting_fields, dm.dmFields);
+
+ memset(&dmW, 0, sizeof(dmW));
+ ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &dmW);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x\n", GetLastError());
+ ok(dmW.dmSize == FIELD_OFFSET(DEVMODEW, dmICMMethod), "Expect dmSize %u, got %u\n",
+ FIELD_OFFSET(DEVMODEW, dmICMMethod), dmW.dmSize);
+ todo_wine ok((dmW.dmFields & setting_fields) == setting_fields, "Expect dmFields to contain %#x, got %#x\n",
+ setting_fields, dmW.dmFields);
+
+ memset(&dmW, 0, sizeof(dmW));
+ dmW.dmSize = sizeof(dmW);
+ ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &dmW);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x\n", GetLastError());
+ ok(dmW.dmSize == FIELD_OFFSET(DEVMODEW, dmICMMethod), "Expect dmSize %u, got %u\n",
+ FIELD_OFFSET(DEVMODEW, dmICMMethod), dmW.dmSize);
+ todo_wine ok((dmW.dmFields & setting_fields) == setting_fields, "Expect dmFields to contain %#x, got %#x\n",
+ setting_fields, dmW.dmFields);
+
+ /* EnumDisplaySettingsExA/W need dmSize to be at least FIELD_OFFSET(DEVMODEA/W, dmFields) + 1 to have valid dmFields */
+ /* Crash on Windows when dmSize is zero */
+ if (0)
+ {
+ memset(&dm, 0, sizeof(dm));
+ ret = EnumDisplaySettingsExA(NULL, ENUM_CURRENT_SETTINGS, &dm, 0);
+ ok(!ret, "EnumDisplaySettingsExA succeed\n");
+
+ memset(&dmW, 0, sizeof(dmW));
+ ret = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &dmW, 0);
+ ok(!ret, "EnumDisplaySettingsExA succeed\n");
+ }
+
+ memset(&dm, 0, sizeof(dm));
+ dm.dmSize = FIELD_OFFSET(DEVMODEA, dmFields);
+ ret = EnumDisplaySettingsExA(NULL, ENUM_CURRENT_SETTINGS, &dm, 0);
+ ok(ret, "EnumDisplaySettingsExA failed, error %#x\n", GetLastError());
+ todo_wine ok(dm.dmSize == FIELD_OFFSET(DEVMODEA, dmFields), "Expect dmSize unchanged, got %u\n", dm.dmSize);
+ todo_wine ok(dm.dmFields == 0, "Expect dmFields unchanged, got %#x\n", dm.dmFields);
+
+ memset(&dm, 0, sizeof(dm));
+ dm.dmSize = FIELD_OFFSET(DEVMODEA, dmFields) + 1;
+ ret = EnumDisplaySettingsExA(NULL, ENUM_CURRENT_SETTINGS, &dm, 0);
+ ok(ret, "EnumDisplaySettingsExA failed, error %#x\n", GetLastError());
+ todo_wine ok(dm.dmSize == FIELD_OFFSET(DEVMODEA, dmFields) + 1, "Expect dmSize unchanged, got %u\n", dm.dmSize);
+ todo_wine ok((dm.dmFields & setting_fields) == (DM_POSITION | DM_DISPLAYORIENTATION),
+ "Expect dmFields to contain %#lx, got %#x\n", DM_POSITION | DM_DISPLAYORIENTATION, dm.dmFields);
+ /* Fields beyond dmSize don't get written */
+ todo_wine ok(dm.dmPelsWidth == 0, "Expect dmPelsWidth unwritten\n");
+
+ memset(&dmW, 0, sizeof(dmW));
+ dmW.dmSize = FIELD_OFFSET(DEVMODEW, dmFields);
+ ret = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &dmW, 0);
+ ok(ret, "EnumDisplaySettingsExW failed, error %#x\n", GetLastError());
+ todo_wine ok(dmW.dmSize == FIELD_OFFSET(DEVMODEW, dmFields), "Expect dmSize unchanged, got %u\n", dmW.dmSize);
+ todo_wine ok(dmW.dmFields == 0, "Expect dmFields unchanged, got %#x\n", dmW.dmFields);
+
+ memset(&dmW, 0, sizeof(dmW));
+ dmW.dmSize = FIELD_OFFSET(DEVMODEW, dmFields) + 1;
+ ret = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &dmW, 0);
+ ok(ret, "EnumDisplaySettingsExW failed, error %#x\n", GetLastError());
+ todo_wine ok(dmW.dmSize == FIELD_OFFSET(DEVMODEW, dmFields) + 1, "Expect dmSize unchanged, got %u\n", dmW.dmSize);
+ todo_wine ok((dmW.dmFields & setting_fields) == (DM_POSITION | DM_DISPLAYORIENTATION),
+ "Expect dmFields to contain %#lx, got %#x\n", DM_POSITION | DM_DISPLAYORIENTATION, dmW.dmFields);
+ /* Fields beyond dmSize don't get written */
+ todo_wine ok(dmW.dmPelsWidth == 0, "Expect dmPelsWidth unwritten\n");
+
+ /* Test dmBitsPerPel */
hdc = GetDC(0);
val = GetDeviceCaps(hdc, BITSPIXEL);
- ok(devmode.dmBitsPerPel == val,
- "GetDeviceCaps(BITSPIXEL) returned %d, EnumDisplaySettings returned %d\n",
- val, devmode.dmBitsPerPel);
+
+ memset(&dm, 0, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+ ret = EnumDisplaySettingsExA(NULL, ENUM_CURRENT_SETTINGS, &dm, 0);
+ ok(ret, "EnumDisplaySettingsExA failed, error %#x\n", GetLastError());
+ todo_wine ok((dm.dmFields & setting_fields) == setting_fields, "Expect dmFields to contain %#x, got %#x\n",
+ setting_fields, dm.dmFields);
+ ok(dm.dmBitsPerPel == val, "Expect dmBitsPerPel %d, got %d\n", val, dm.dmBitsPerPel);
val = GetDeviceCaps(hdc, NUMCOLORS);
- if(devmode.dmBitsPerPel <= 8) {
- ok(val == 256, "Screen bpp is %d, NUMCOLORS returned %d\n", devmode.dmBitsPerPel, val);
- } else {
- ok(val == -1, "Screen bpp is %d, NUMCOLORS returned %d\n", devmode.dmBitsPerPel, val);
+ if (dm.dmBitsPerPel <= 8)
+ {
+ ok(val == 256, "Screen bpp is %d, NUMCOLORS returned %d\n", dm.dmBitsPerPel, val);
+ }
+ else
+ {
+ ok(val == -1, "Screen bpp is %d, NUMCOLORS returned %d\n", dm.dmBitsPerPel, val);
}
ReleaseDC(0, hdc);
- num = 1;
- while (1) {
- SetLastError (0xdeadbeef);
- if (!EnumDisplaySettingsA(NULL, num, &devmode)) {
- DWORD le = GetLastError();
- ok(le == ERROR_NO_MORE_FILES ||
- le == ERROR_MOD_NOT_FOUND /* Win8 */ ||
- le == 0xdeadbeef, /* XP, 2003 */
- "Expected ERROR_NO_MORE_FILES, ERROR_MOD_NOT_FOUND or 0xdeadbeef, got %d for %d\n", le, num);
- break;
- }
- num++;
+ /* Test dmPosition, dmPelsWidth and dmPelsHeight */
+ /* Set DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE so that GetMonitorInfo() returns physical pixels */
+ if (pSetThreadDpiAwarenessContext)
+ ctx = pSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
+ EnumDisplayMonitors(NULL, NULL, test_enum_display_settings, 0);
+ if (pSetThreadDpiAwarenessContext && ctx)
+ pSetThreadDpiAwarenessContext(ctx);
+
+ /* Test mode enumeration and other fields */
+ dd.cb = sizeof(dd);
+ for (device = 0; EnumDisplayDevicesA(NULL, device, &dd, 0); ++device)
+ {
+ INT number;
+
+ /* Skip software devices */
+ if (sscanf(dd.DeviceName, "\\\\.\\DISPLAY%d", &number) != 1)
+ continue;
+
+ attached = dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
+
+ memset(&dm, 0, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+ SetLastError(0xdeadbeef);
+ for (mode = ENUM_REGISTRY_SETTINGS; EnumDisplaySettingsA(dd.DeviceName, mode, &dm); ++mode)
+ {
+ if (mode == ENUM_CURRENT_SETTINGS)
+ {
+ todo_wine ok((dm.dmFields & setting_fields) == setting_fields,
+ "Expect dmFields to contain %#x, got %#x\n", setting_fields, dm.dmFields);
+ }
+ else
+ {
+ todo_wine ok((dm.dmFields & mode_fields) == mode_fields, "Expect dmFields to contain %#x, got %#x\n",
+ mode_fields, dm.dmFields);
+ }
+
+ ok(dm.dmDisplayOrientation == DMDO_DEFAULT, "Expect dmDisplayOrientation DMDO_DEFAULT, got %#x\n",
+ dm.dmDisplayOrientation);
+ ok(dm.dmDisplayFlags == 0, "Expect dmDisplayFlags zero\n");
+
+ if (mode == ENUM_CURRENT_SETTINGS && !attached)
+ {
+ todo_wine ok(dm.dmBitsPerPel == 0, "Expect dmBitsPerPel zero, got %u\n", dm.dmBitsPerPel);
+ todo_wine ok(dm.dmPelsWidth == 0, "Expect dmPelsWidth zero, got %u\n", dm.dmPelsWidth);
+ todo_wine ok(dm.dmPelsHeight == 0, "Expect dmPelsHeight zero, got %u\n", dm.dmPelsHeight);
+ todo_wine ok(dm.dmDisplayFrequency == 0, "Expect dmDisplayFrequency zero, got %u\n", dm.dmDisplayFrequency);
+ }
+ else if (mode != ENUM_REGISTRY_SETTINGS)
+ {
+ ok(dm.dmBitsPerPel, "Expect dmBitsPerPel not zero\n");
+ ok(dm.dmPelsWidth, "Expect dmPelsWidth not zero\n");
+ ok(dm.dmPelsHeight, "Expect dmPelsHeight not zero\n");
+ ok(dm.dmDisplayFrequency, "Expect dmDisplayFrequency not zero\n");
+ }
+ }
+
+ ok(mode >= 1, "Expect at least one valid mode gets enumerated.\n");
+
+ err = GetLastError();
+ ok(err == ERROR_NO_MORE_FILES ||
+ err == ERROR_MOD_NOT_FOUND /* Win8 */ ||
+ err == 0xdeadbeef, /* XP, 2003 */
+ "Expected ERROR_NO_MORE_FILES, ERROR_MOD_NOT_FOUND or 0xdeadbeef, got %#x\n", err);
}
}
--
2.20.1
More information about the wine-devel
mailing list