-- v3: win32u: Support QDC_VIRTUAL_MODE_AWARE in NtUserQueryDisplayConfig(). win32u: Support QDC_VIRTUAL_MODE_AWARE in NtUserGetDisplayConfigBufferSizes(). user32/tests: Add tests for QueryDisplayConfig( QDC_VIRTUAL_MODE_AWARE ).
From: Paul Gofman pgofman@codeweavers.com
--- dlls/user32/tests/monitor.c | 172 ++++++++++++++++++++++++++++-------- 1 file changed, 133 insertions(+), 39 deletions(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index 39381c3418c..f79ccab91be 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -1694,6 +1694,12 @@ static void test_GetDisplayConfigBufferSizes(void) ok(paths > 0 && modes > 0, "got %u, %u\n", paths, modes); else ok(ret == ERROR_NOT_SUPPORTED, "got %ld\n", ret); + + paths = modes = 0; + ret = pGetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS | QDC_VIRTUAL_MODE_AWARE, &paths, &modes); + todo_wine ok(!ret || broken(ret == ERROR_INVALID_PARAMETER || ret == ERROR_NOT_SUPPORTED) /* before Win10 */, "got %ld\n", ret); + if (!ret) + ok(paths > 0 && modes > 0, "got %u, %u\n", paths, modes); }
static BOOL CALLBACK test_EnumDisplayMonitors_normal_cb(HMONITOR monitor, HDC hdc, LPRECT rect, @@ -1970,12 +1976,13 @@ static void check_preferred_mode(const DISPLAYCONFIG_TARGET_PREFERRED_MODE *mode static void test_QueryDisplayConfig_result(UINT32 flags, UINT32 paths, const DISPLAYCONFIG_PATH_INFO *pi, UINT32 modes, const DISPLAYCONFIG_MODE_INFO *mi) { - UINT32 i; + UINT32 i, src_mode_idx, tgt_mode_idx; LONG ret; DISPLAYCONFIG_SOURCE_DEVICE_NAME source_name; DISPLAYCONFIG_TARGET_DEVICE_NAME target_name; DISPLAYCONFIG_TARGET_PREFERRED_MODE preferred_mode; DISPLAYCONFIG_ADAPTER_NAME adapter_name; + const DISPLAYCONFIG_DESKTOP_IMAGE_INFO *di;
for (i = 0; i < paths; i++) { @@ -2028,65 +2035,141 @@ static void test_QueryDisplayConfig_result(UINT32 flags, }
/* Check corresponding modes */ - if (pi[i].sourceInfo.modeInfoIdx == DISPLAYCONFIG_PATH_MODE_IDX_INVALID) + if (flags & QDC_VIRTUAL_MODE_AWARE) { - skip("Path doesn't contain source modeInfoIdx\n"); - continue; + src_mode_idx = pi[i].sourceInfo.sourceModeInfoIdx; + if (src_mode_idx == DISPLAYCONFIG_PATH_SOURCE_MODE_IDX_INVALID) + { + ok(pi[i].sourceInfo.cloneGroupId != DISPLAYCONFIG_PATH_CLONE_GROUP_INVALID, "got cloneGroupId %#x.\n", + pi[i].sourceInfo.cloneGroupId); + skip("Path doesn't contain source modeInfoIdx\n"); + continue; + } + ok(pi[i].sourceInfo.cloneGroupId == DISPLAYCONFIG_PATH_CLONE_GROUP_INVALID, "got cloneGroupId %#x.\n", + pi[i].sourceInfo.cloneGroupId); + } + else + { + src_mode_idx = pi[i].sourceInfo.modeInfoIdx; + if (src_mode_idx == DISPLAYCONFIG_PATH_MODE_IDX_INVALID) + { + skip("Path doesn't contain source modeInfoIdx\n"); + continue; + } } - ok(pi[i].sourceInfo.modeInfoIdx < modes, "Expected index <%d, got %d\n", modes, pi[i].sourceInfo.modeInfoIdx); - if (pi[i].sourceInfo.modeInfoIdx >= modes) + ok(src_mode_idx < modes, "Expected index <%d, got %d\n", modes, src_mode_idx); + if (src_mode_idx >= modes) continue;
- ok(mi[pi[i].sourceInfo.modeInfoIdx].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE, "Expected infoType %d, got %d\n", - DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE, mi[pi[i].sourceInfo.modeInfoIdx].infoType); - ok(pi[i].sourceInfo.id == mi[pi[i].sourceInfo.modeInfoIdx].id, "Expected id %u, got %u\n", - pi[i].sourceInfo.id, mi[pi[i].sourceInfo.modeInfoIdx].id); - ok(pi[i].sourceInfo.adapterId.HighPart == mi[pi[i].sourceInfo.modeInfoIdx].adapterId.HighPart && - pi[i].sourceInfo.adapterId.LowPart == mi[pi[i].sourceInfo.modeInfoIdx].adapterId.LowPart, + ok(mi[src_mode_idx].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE, "Expected infoType %d, got %d\n", + DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE, mi[src_mode_idx].infoType); + ok(pi[i].sourceInfo.id == mi[src_mode_idx].id, "Expected id %u, got %u\n", + pi[i].sourceInfo.id, mi[src_mode_idx].id); + ok(pi[i].sourceInfo.adapterId.HighPart == mi[src_mode_idx].adapterId.HighPart && + pi[i].sourceInfo.adapterId.LowPart == mi[src_mode_idx].adapterId.LowPart, "Expected LUID %08lx:%08lx, got %08lx:%08lx\n", pi[i].sourceInfo.adapterId.HighPart, pi[i].sourceInfo.adapterId.LowPart, - mi[pi[i].sourceInfo.modeInfoIdx].adapterId.HighPart, mi[pi[i].sourceInfo.modeInfoIdx].adapterId.LowPart); - ok(mi[pi[i].sourceInfo.modeInfoIdx].sourceMode.width > 0 && mi[pi[i].sourceInfo.modeInfoIdx].sourceMode.height > 0, + mi[src_mode_idx].adapterId.HighPart, mi[src_mode_idx].adapterId.LowPart); + ok(mi[src_mode_idx].sourceMode.width > 0 && mi[src_mode_idx].sourceMode.height > 0, "Expected non-zero height/width, got %ux%u\n", - mi[pi[i].sourceInfo.modeInfoIdx].sourceMode.width, mi[pi[i].sourceInfo.modeInfoIdx].sourceMode.height); + mi[src_mode_idx].sourceMode.width, mi[src_mode_idx].sourceMode.height);
- if (pi[i].targetInfo.modeInfoIdx == DISPLAYCONFIG_PATH_MODE_IDX_INVALID) + if (flags & QDC_VIRTUAL_MODE_AWARE) { - skip("Path doesn't contain target modeInfoIdx\n"); - continue; + tgt_mode_idx = pi[i].targetInfo.targetModeInfoIdx; + if (tgt_mode_idx == DISPLAYCONFIG_PATH_TARGET_MODE_IDX_INVALID) + { + skip("Path doesn't contain target modeInfoIdx\n"); + continue; + } + } + else + { + tgt_mode_idx = pi[i].targetInfo.modeInfoIdx; + if (tgt_mode_idx == DISPLAYCONFIG_PATH_MODE_IDX_INVALID) + { + skip("Path doesn't contain target modeInfoIdx\n"); + continue; + } } - ok(pi[i].targetInfo.modeInfoIdx < modes, "Expected index <%d, got %d\n", modes, pi[i].targetInfo.modeInfoIdx); - if (pi[i].targetInfo.modeInfoIdx >= modes) + ok(tgt_mode_idx < modes, "Expected index <%d, got %d\n", modes, tgt_mode_idx); + if (tgt_mode_idx >= modes) continue;
- ok(mi[pi[i].targetInfo.modeInfoIdx].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_TARGET, "Expected infoType %d, got %d\n", - DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE, mi[pi[i].targetInfo.modeInfoIdx].infoType); - ok(pi[i].targetInfo.id == mi[pi[i].targetInfo.modeInfoIdx].id, "Expected id %u, got %u\n", - pi[i].targetInfo.id, mi[pi[i].targetInfo.modeInfoIdx].id); - ok(pi[i].targetInfo.adapterId.HighPart == mi[pi[i].targetInfo.modeInfoIdx].adapterId.HighPart && - pi[i].targetInfo.adapterId.LowPart == mi[pi[i].targetInfo.modeInfoIdx].adapterId.LowPart, + ok(mi[tgt_mode_idx].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_TARGET, "Expected infoType %d, got %d\n", + DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE, mi[tgt_mode_idx].infoType); + ok(pi[i].targetInfo.id == mi[tgt_mode_idx].id, "Expected id %u, got %u\n", + pi[i].targetInfo.id, mi[tgt_mode_idx].id); + ok(pi[i].targetInfo.adapterId.HighPart == mi[tgt_mode_idx].adapterId.HighPart && + pi[i].targetInfo.adapterId.LowPart == mi[tgt_mode_idx].adapterId.LowPart, "Expected LUID %08lx:%08lx, got %08lx:%08lx\n", pi[i].targetInfo.adapterId.HighPart, pi[i].targetInfo.adapterId.LowPart, - mi[pi[i].targetInfo.modeInfoIdx].adapterId.HighPart, mi[pi[i].targetInfo.modeInfoIdx].adapterId.LowPart); - ok(mi[pi[i].targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo.activeSize.cx > 0 && - mi[pi[i].targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo.activeSize.cy > 0, + mi[tgt_mode_idx].adapterId.HighPart, mi[tgt_mode_idx].adapterId.LowPart); + ok(mi[tgt_mode_idx].targetMode.targetVideoSignalInfo.activeSize.cx > 0 && + mi[tgt_mode_idx].targetMode.targetVideoSignalInfo.activeSize.cy > 0, "Expected non-zero height/width, got %ux%u\n", - mi[pi[i].targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo.activeSize.cx, - mi[pi[i].targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo.activeSize.cy); + mi[tgt_mode_idx].targetMode.targetVideoSignalInfo.activeSize.cx, + mi[tgt_mode_idx].targetMode.targetVideoSignalInfo.activeSize.cy);
if (flags == QDC_DATABASE_CURRENT) - ok(mi[pi[i].targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo.totalSize.cx == 0 && - mi[pi[i].targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo.totalSize.cy == 0, + ok(mi[tgt_mode_idx].targetMode.targetVideoSignalInfo.totalSize.cx == 0 && + mi[tgt_mode_idx].targetMode.targetVideoSignalInfo.totalSize.cy == 0, "Expected zero height/width, got %ux%u\n", - mi[pi[i].targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo.totalSize.cx, - mi[pi[i].targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo.totalSize.cy); + mi[tgt_mode_idx].targetMode.targetVideoSignalInfo.totalSize.cx, + mi[tgt_mode_idx].targetMode.targetVideoSignalInfo.totalSize.cy); else - ok(mi[pi[i].targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo.totalSize.cx > 0 && - mi[pi[i].targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo.totalSize.cy > 0, + ok(mi[tgt_mode_idx].targetMode.targetVideoSignalInfo.totalSize.cx > 0 && + mi[tgt_mode_idx].targetMode.targetVideoSignalInfo.totalSize.cy > 0, "Expected non-zero height/width, got %ux%u\n", - mi[pi[i].targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo.totalSize.cx, - mi[pi[i].targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo.totalSize.cy); + mi[tgt_mode_idx].targetMode.targetVideoSignalInfo.totalSize.cx, + mi[tgt_mode_idx].targetMode.targetVideoSignalInfo.totalSize.cy); + if (flags & QDC_VIRTUAL_MODE_AWARE) + { + tgt_mode_idx = pi[i].targetInfo.desktopModeInfoIdx; + if (tgt_mode_idx == DISPLAYCONFIG_PATH_DESKTOP_IMAGE_IDX_INVALID) + { + ok(!(pi[i].flags & DISPLAYCONFIG_PATH_SUPPORT_VIRTUAL_MODE), "got path flags %#x.\n", pi[i].flags); + skip("Path doesn't contain target desktopModeInfoIdx.\n"); + continue; + } + ok(pi[i].flags & DISPLAYCONFIG_PATH_SUPPORT_VIRTUAL_MODE, "got path flags %#x.\n", pi[i].flags); + } + else + { + continue; + } + + ok(mi[tgt_mode_idx].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_DESKTOP_IMAGE, "Expected infoType %d, got %d\n", + DISPLAYCONFIG_MODE_INFO_TYPE_DESKTOP_IMAGE, mi[tgt_mode_idx].infoType); + ok(pi[i].targetInfo.id == mi[tgt_mode_idx].id, "Expected id %u, got %u\n", + pi[i].targetInfo.id, mi[tgt_mode_idx].id); + ok(pi[i].targetInfo.adapterId.HighPart == mi[tgt_mode_idx].adapterId.HighPart && + pi[i].targetInfo.adapterId.LowPart == mi[tgt_mode_idx].adapterId.LowPart, + "Expected LUID %08lx:%08lx, got %08lx:%08lx\n", + pi[i].targetInfo.adapterId.HighPart, pi[i].targetInfo.adapterId.LowPart, + mi[tgt_mode_idx].adapterId.HighPart, mi[tgt_mode_idx].adapterId.LowPart); + di = &mi[tgt_mode_idx].desktopImageInfo; + ok(!di->DesktopImageRegion.left && !di->DesktopImageRegion.top, + "Expected zero left/top, got %lux%lu\n", + di->DesktopImageRegion.left, + di->DesktopImageRegion.top); + ok(di->DesktopImageRegion.right > 0 && di->DesktopImageRegion.bottom > 0, + "Expected non-zero height/width, got %lux%lu\n", + di->DesktopImageRegion.right, + di->DesktopImageRegion.bottom); + ok(!di->DesktopImageClip.left && !di->DesktopImageClip.top, + "Expected zero left/top, got %lux%lu\n", + di->DesktopImageClip.left, + di->DesktopImageClip.top); + ok(di->DesktopImageClip.right > 0 && di->DesktopImageClip.bottom > 0, + "Expected non-zero height/width, got %lux%lu\n", + di->DesktopImageClip.right, + di->DesktopImageClip.bottom); + ok(di->PathSourceSize.x > 0 && di->PathSourceSize.y > 0, + "Expected non-zero x/y, got %lux%lu\n", + di->PathSourceSize.x, + di->PathSourceSize.y); } }
@@ -2185,6 +2268,17 @@ static void test_QueryDisplayConfig(void) ok(topologyid != 0xFF, "expected topologyid to be set, got %d\n", topologyid); if (!ret && paths > 0 && modes > 0) test_QueryDisplayConfig_result(QDC_DATABASE_CURRENT, paths, pi, modes, mi); + + paths = ARRAY_SIZE(pi); + modes = ARRAY_SIZE(mi); + memset(pi, 0xFF, sizeof(pi)); + memset(mi, 0xFF, sizeof(mi)); + ret = pQueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS | QDC_VIRTUAL_MODE_AWARE, &paths, pi, &modes, mi, NULL); + todo_wine ok(!ret || broken(ret == ERROR_INVALID_PARAMETER) /* before Win10 */, "got %ld\n", ret); + if (!ret) + ok(paths > 0 && modes > 0, "got %u, %u\n", paths, modes); + if (!ret && paths > 0 && modes > 0) + test_QueryDisplayConfig_result(QDC_ONLY_ACTIVE_PATHS | QDC_VIRTUAL_MODE_AWARE, paths, pi, modes, mi); }
static void test_DisplayConfigGetDeviceInfo(void)
From: Paul Gofman pgofman@codeweavers.com
--- dlls/user32/tests/monitor.c | 2 +- dlls/win32u/sysparams.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index f79ccab91be..bb8ab1ec4b7 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -1697,7 +1697,7 @@ static void test_GetDisplayConfigBufferSizes(void)
paths = modes = 0; ret = pGetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS | QDC_VIRTUAL_MODE_AWARE, &paths, &modes); - todo_wine ok(!ret || broken(ret == ERROR_INVALID_PARAMETER || ret == ERROR_NOT_SUPPORTED) /* before Win10 */, "got %ld\n", ret); + ok(!ret || broken(ret == ERROR_INVALID_PARAMETER || ret == ERROR_NOT_SUPPORTED) /* before Win10 */, "got %ld\n", ret); if (!ret) ok(paths > 0 && modes > 0, "got %u, %u\n", paths, modes); } diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 30fe1c1e834..74b913c2294 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -88,6 +88,8 @@ static const char guid_devinterface_display_adapterA[] = "{5B45201D-F2F2-4F3B-85 static const char guid_display_device_arrivalA[] = "{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}"; static const char guid_devinterface_monitorA[] = "{E6F07B5F-EE97-4A90-B076-33F57BF4EAA7}";
+static const UINT32 qdc_retrieve_flags_mask = QDC_ALL_PATHS | QDC_ONLY_ACTIVE_PATHS | QDC_DATABASE_CURRENT; + #define NEXT_DEVMODEW(mode) ((DEVMODEW *)((char *)((mode) + 1) + (mode)->dmDriverExtra))
struct gpu @@ -2618,7 +2620,7 @@ LONG WINAPI NtUserGetDisplayConfigBufferSizes( UINT32 flags, UINT32 *num_path_in
*num_path_info = 0;
- switch (flags) + switch (flags & qdc_retrieve_flags_mask) { case QDC_ALL_PATHS: case QDC_ONLY_ACTIVE_PATHS: @@ -2628,8 +2630,14 @@ LONG WINAPI NtUserGetDisplayConfigBufferSizes( UINT32 flags, UINT32 *num_path_in return ERROR_INVALID_PARAMETER; }
+ if ((flags & ~(qdc_retrieve_flags_mask | QDC_VIRTUAL_MODE_AWARE))) + { + FIXME( "unsupported flags %#x.\n", flags ); + return ERROR_INVALID_PARAMETER; + } + /* FIXME: semi-stub */ - if (flags != QDC_ONLY_ACTIVE_PATHS) + if ((flags & qdc_retrieve_flags_mask) != QDC_ONLY_ACTIVE_PATHS) FIXME( "only returning active paths\n" );
if (lock_display_devices()) @@ -2644,6 +2652,8 @@ LONG WINAPI NtUserGetDisplayConfigBufferSizes( UINT32 flags, UINT32 *num_path_in
*num_path_info = count; *num_mode_info = count * 2; + if (flags & QDC_VIRTUAL_MODE_AWARE) + *num_mode_info += count; TRACE( "returning %u paths %u modes\n", *num_path_info, *num_mode_info ); return ERROR_SUCCESS; }
From: Paul Gofman pgofman@codeweavers.com
--- dlls/user32/tests/monitor.c | 2 +- dlls/win32u/sysparams.c | 94 +++++++++++++++++++++++++++---------- 2 files changed, 71 insertions(+), 25 deletions(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index bb8ab1ec4b7..bdd9a838189 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -2274,7 +2274,7 @@ static void test_QueryDisplayConfig(void) memset(pi, 0xFF, sizeof(pi)); memset(mi, 0xFF, sizeof(mi)); ret = pQueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS | QDC_VIRTUAL_MODE_AWARE, &paths, pi, &modes, mi, NULL); - todo_wine ok(!ret || broken(ret == ERROR_INVALID_PARAMETER) /* before Win10 */, "got %ld\n", ret); + ok(!ret || broken(ret == ERROR_INVALID_PARAMETER) /* before Win10 */, "got %ld\n", ret); if (!ret) ok(paths > 0 && modes > 0, "got %u, %u\n", paths, modes); if (!ret && paths > 0 && modes > 0) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 74b913c2294..dd7ea295ee9 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2717,11 +2717,17 @@ static void set_mode_target_info( DISPLAYCONFIG_MODE_INFO *info, const LUID *gpu }
static void set_path_target_info( DISPLAYCONFIG_PATH_TARGET_INFO *info, const LUID *gpu_luid, - UINT32 target_id, UINT32 mode_index, const DEVMODEW *devmode ) + UINT32 target_id, UINT32 mode_index, UINT32 desktop_mode_index, + UINT32 flags, const DEVMODEW *devmode ) { info->adapterId = *gpu_luid; info->id = target_id; - info->modeInfoIdx = mode_index; + if (flags & QDC_VIRTUAL_MODE_AWARE) + { + info->targetModeInfoIdx = mode_index; + info->desktopModeInfoIdx = desktop_mode_index; + } + else info->modeInfoIdx = mode_index; info->outputTechnology = DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL; info->rotation = get_dc_rotation( devmode ); info->scaling = DISPLAYCONFIG_SCALING_IDENTITY; @@ -2755,12 +2761,34 @@ static void set_mode_source_info( DISPLAYCONFIG_MODE_INFO *info, const LUID *gpu } }
+static void set_mode_desktop_info( DISPLAYCONFIG_MODE_INFO *info, const LUID *gpu_luid, UINT32 target_id, + const DISPLAYCONFIG_SOURCE_MODE *source_mode ) +{ + DISPLAYCONFIG_DESKTOP_IMAGE_INFO *mode = &info->desktopImageInfo; + + info->infoType = DISPLAYCONFIG_MODE_INFO_TYPE_DESKTOP_IMAGE; + info->adapterId = *gpu_luid; + info->id = target_id; + mode->PathSourceSize.x = source_mode->width; + mode->PathSourceSize.y = source_mode->height; + mode->DesktopImageRegion.left = 0; + mode->DesktopImageRegion.top = 0; + mode->DesktopImageRegion.right = source_mode->width; + mode->DesktopImageRegion.bottom = source_mode->height; + mode->DesktopImageClip = mode->DesktopImageRegion; +} + static void set_path_source_info( DISPLAYCONFIG_PATH_SOURCE_INFO *info, const LUID *gpu_luid, - UINT32 source_id, UINT32 mode_index ) + UINT32 source_id, UINT32 mode_index, UINT32 flags ) { info->adapterId = *gpu_luid; info->id = source_id; - info->modeInfoIdx = mode_index; + if (flags & QDC_VIRTUAL_MODE_AWARE) + { + info->sourceModeInfoIdx = mode_index; + info->cloneGroupId = DISPLAYCONFIG_PATH_CLONE_GROUP_INVALID; + } + else info->modeInfoIdx = mode_index; info->statusFlags = DISPLAYCONFIG_SOURCE_IN_USE; }
@@ -2794,8 +2822,9 @@ LONG WINAPI NtUserQueryDisplayConfig( UINT32 flags, UINT32 *paths_count, DISPLAY const LUID *gpu_luid; DEVMODEW devmode; struct monitor *monitor; + DWORD retrieve_flags = flags & qdc_retrieve_flags_mask;
- FIXME( "flags %#x, paths_count %p, paths %p, modes_count %p, modes %p, topology_id %p semi-stub\n", + TRACE( "flags %#x, paths_count %p, paths %p, modes_count %p, modes %p, topology_id %p.\n", flags, paths_count, paths, modes_count, modes, topology_id );
if (!paths_count || !modes_count) @@ -2804,16 +2833,22 @@ LONG WINAPI NtUserQueryDisplayConfig( UINT32 flags, UINT32 *paths_count, DISPLAY if (!*paths_count || !*modes_count) return ERROR_INVALID_PARAMETER;
- if (flags != QDC_ALL_PATHS && - flags != QDC_ONLY_ACTIVE_PATHS && - flags != QDC_DATABASE_CURRENT) + if (retrieve_flags != QDC_ALL_PATHS && + retrieve_flags != QDC_ONLY_ACTIVE_PATHS && + retrieve_flags != QDC_DATABASE_CURRENT) return ERROR_INVALID_PARAMETER;
- if (((flags == QDC_DATABASE_CURRENT) && !topology_id) || - ((flags != QDC_DATABASE_CURRENT) && topology_id)) + if (((retrieve_flags == QDC_DATABASE_CURRENT) && !topology_id) || + ((retrieve_flags != QDC_DATABASE_CURRENT) && topology_id)) return ERROR_INVALID_PARAMETER;
- if (flags != QDC_ONLY_ACTIVE_PATHS) + if ((flags & ~(qdc_retrieve_flags_mask | QDC_VIRTUAL_MODE_AWARE))) + { + FIXME( "unsupported flags %#x.\n", flags ); + return ERROR_INVALID_PARAMETER; + } + + if (retrieve_flags != QDC_ONLY_ACTIVE_PATHS) FIXME( "only returning active paths\n" );
if (topology_id) @@ -2849,17 +2884,6 @@ LONG WINAPI NtUserQueryDisplayConfig( UINT32 flags, UINT32 *paths_count, DISPLAY goto done; }
- paths[path_index].flags = DISPLAYCONFIG_PATH_ACTIVE; - set_mode_target_info( &modes[mode_index], gpu_luid, output_id, flags, &devmode ); - set_path_target_info( &paths[path_index].targetInfo, gpu_luid, output_id, mode_index, &devmode ); - - mode_index++; - if (mode_index == *modes_count) - { - ret = ERROR_INSUFFICIENT_BUFFER; - goto done; - } - /* Multiple targets can be driven by the same source, ensure a mode * hasn't already been added for this source. */ @@ -2867,9 +2891,31 @@ LONG WINAPI NtUserQueryDisplayConfig( UINT32 flags, UINT32 *paths_count, DISPLAY { set_mode_source_info( &modes[mode_index], gpu_luid, source_index, &devmode ); source_mode_index = mode_index; - mode_index++; + if (++mode_index == *modes_count) + { + ret = ERROR_INSUFFICIENT_BUFFER; + goto done; + } } - set_path_source_info( &paths[path_index].sourceInfo, gpu_luid, source_index, source_mode_index ); + + paths[path_index].flags = DISPLAYCONFIG_PATH_ACTIVE; + set_mode_target_info( &modes[mode_index], gpu_luid, output_id, flags, &devmode ); + if (flags & QDC_VIRTUAL_MODE_AWARE) + { + paths[path_index].flags |= DISPLAYCONFIG_PATH_SUPPORT_VIRTUAL_MODE; + if (++mode_index == *modes_count) + { + ret = ERROR_INSUFFICIENT_BUFFER; + goto done; + } + set_mode_desktop_info( &modes[mode_index], gpu_luid, output_id, &modes[source_mode_index].sourceMode ); + set_path_target_info( &paths[path_index].targetInfo, gpu_luid, output_id, mode_index - 1, mode_index, + flags, &devmode ); + } + else set_path_target_info( &paths[path_index].targetInfo, gpu_luid, output_id, mode_index, ~0u, flags, &devmode ); + ++mode_index; + + set_path_source_info( &paths[path_index].sourceInfo, gpu_luid, source_index, source_mode_index, flags ); path_index++; }
On Tue Oct 8 09:32:48 2024 +0000, Zhiyi Zhang wrote:
I don't see tests for mode->DesktopImageRegion.left and mode->DesktopImageRegion.right. Is assigning 0 correct for multi-monitor systems?
Yes, DesktopImageRegion.left / top is 0 here with two monitors too (as well as DesktopImageClip). I've added that to the test.
v2: - Test DesktopImageRegion / DesktopImageClip left / top being zero.
Zhiyi Zhang (@zhiyi) commented about dlls/user32/tests/monitor.c:
skip("Path doesn't contain target desktopModeInfoIdx.\n");
continue;
}
ok(pi[i].flags & DISPLAYCONFIG_PATH_SUPPORT_VIRTUAL_MODE, "got path flags %#x.\n", pi[i].flags);
}
else
{
continue;
}
ok(mi[tgt_mode_idx].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_DESKTOP_IMAGE, "Expected infoType %d, got %d\n",
DISPLAYCONFIG_MODE_INFO_TYPE_DESKTOP_IMAGE, mi[tgt_mode_idx].infoType);
ok(pi[i].targetInfo.id == mi[tgt_mode_idx].id, "Expected id %u, got %u\n",
pi[i].targetInfo.id, mi[tgt_mode_idx].id);
ok(pi[i].targetInfo.adapterId.HighPart == mi[tgt_mode_idx].adapterId.HighPart &&
pi[i].targetInfo.adapterId.LowPart == mi[tgt_mode_idx].adapterId.LowPart,
Let's align this line with 8 spaces like others.