Skip to content

Commit

Permalink
win32u: Support QDC_VIRTUAL_MODE_AWARE in NtUserQueryDisplayConfig().
Browse files Browse the repository at this point in the history
CW-Bug-Id: #24333
  • Loading branch information
Paul Gofman authored and ivyl committed Oct 2, 2024
1 parent 1a1f136 commit 5416bf6
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 25 deletions.
2 changes: 1 addition & 1 deletion dlls/user32/tests/monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -2021,7 +2021,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)
Expand Down
93 changes: 69 additions & 24 deletions dlls/win32u/sysparams.c
Original file line number Diff line number Diff line change
Expand Up @@ -2546,11 +2546,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;
Expand Down Expand Up @@ -2584,12 +2590,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;
}

Expand Down Expand Up @@ -2623,8 +2651,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)
Expand All @@ -2633,16 +2662,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)
Expand Down Expand Up @@ -2681,27 +2716,37 @@ 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.
*/
if (!source_mode_exists( modes, mode_index, adapter_index, &source_mode_index ))
{
set_mode_source_info( &modes[mode_index], gpu_luid, adapter_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, adapter_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)
{
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, adapter_index, source_mode_index, flags );
path_index++;
}

Expand Down

0 comments on commit 5416bf6

Please sign in to comment.