winex11.drv: Support detaching adapters.
Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4a24816313
commit
d13b61b738
|
@ -612,10 +612,10 @@ static void test_ChangeDisplaySettingsEx(void)
|
||||||
dd.cb = sizeof(dd);
|
dd.cb = sizeof(dd);
|
||||||
res = EnumDisplayDevicesA(NULL, devices[device].index, &dd, 0);
|
res = EnumDisplayDevicesA(NULL, devices[device].index, &dd, 0);
|
||||||
ok(res, "EnumDisplayDevicesA %s failed, error %#x\n", devices[device].name, GetLastError());
|
ok(res, "EnumDisplayDevicesA %s failed, error %#x\n", devices[device].name, GetLastError());
|
||||||
todo_wine ok(!(dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP), "Expect device %s detached.\n", devices[device].name);
|
ok(!(dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP), "Expect device %s detached.\n", devices[device].name);
|
||||||
|
|
||||||
count = GetSystemMetrics(SM_CMONITORS);
|
count = GetSystemMetrics(SM_CMONITORS);
|
||||||
todo_wine ok(count == old_count - 1, "Expect monitor count %d, got %d\n", old_count - 1, count);
|
ok(count == old_count - 1, "Expect monitor count %d, got %d\n", old_count - 1, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test changing each adapter to every available mode */
|
/* Test changing each adapter to every available mode */
|
||||||
|
|
|
@ -805,27 +805,33 @@ static void place_all_displays(struct x11drv_display_setting *displays, INT disp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LONG apply_display_settings(struct x11drv_display_setting *displays, INT display_count)
|
static LONG apply_display_settings(struct x11drv_display_setting *displays, INT display_count, BOOL do_attach)
|
||||||
{
|
{
|
||||||
DEVMODEW *full_mode;
|
DEVMODEW *full_mode;
|
||||||
|
BOOL attached_mode;
|
||||||
INT display_idx;
|
INT display_idx;
|
||||||
LONG ret;
|
LONG ret;
|
||||||
|
|
||||||
for (display_idx = 0; display_idx < display_count; ++display_idx)
|
for (display_idx = 0; display_idx < display_count; ++display_idx)
|
||||||
{
|
{
|
||||||
if (is_detached_mode(&displays[display_idx].desired_mode))
|
attached_mode = !is_detached_mode(&displays[display_idx].desired_mode);
|
||||||
{
|
if ((attached_mode && !do_attach) || (!attached_mode && do_attach))
|
||||||
FIXME("Detaching %s is currently unsupported.\n",
|
|
||||||
wine_dbgstr_w(displays[display_idx].desired_mode.dmDeviceName));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
|
if (attached_mode)
|
||||||
|
{
|
||||||
full_mode = get_full_mode(displays[display_idx].id, &displays[display_idx].desired_mode);
|
full_mode = get_full_mode(displays[display_idx].id, &displays[display_idx].desired_mode);
|
||||||
if (!full_mode)
|
if (!full_mode)
|
||||||
return DISP_CHANGE_BADMODE;
|
return DISP_CHANGE_BADMODE;
|
||||||
|
|
||||||
full_mode->dmFields |= DM_POSITION;
|
full_mode->dmFields |= DM_POSITION;
|
||||||
full_mode->u1.s2.dmPosition = displays[display_idx].desired_mode.u1.s2.dmPosition;
|
full_mode->u1.s2.dmPosition = displays[display_idx].desired_mode.u1.s2.dmPosition;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
full_mode = &displays[display_idx].desired_mode;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("handler:%s changing %s to position:(%d,%d) resolution:%ux%u frequency:%uHz "
|
TRACE("handler:%s changing %s to position:(%d,%d) resolution:%ux%u frequency:%uHz "
|
||||||
"depth:%ubits orientation:%#x.\n", handler.name,
|
"depth:%ubits orientation:%#x.\n", handler.name,
|
||||||
wine_dbgstr_w(displays[display_idx].desired_mode.dmDeviceName),
|
wine_dbgstr_w(displays[display_idx].desired_mode.dmDeviceName),
|
||||||
|
@ -834,6 +840,7 @@ static LONG apply_display_settings(struct x11drv_display_setting *displays, INT
|
||||||
full_mode->u1.s2.dmDisplayOrientation);
|
full_mode->u1.s2.dmDisplayOrientation);
|
||||||
|
|
||||||
ret = handler.set_current_mode(displays[display_idx].id, full_mode);
|
ret = handler.set_current_mode(displays[display_idx].id, full_mode);
|
||||||
|
if (attached_mode)
|
||||||
heap_free(full_mode);
|
heap_free(full_mode);
|
||||||
if (ret != DISP_CHANGE_SUCCESSFUL)
|
if (ret != DISP_CHANGE_SUCCESSFUL)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -842,6 +849,19 @@ static LONG apply_display_settings(struct x11drv_display_setting *displays, INT
|
||||||
return DISP_CHANGE_SUCCESSFUL;
|
return DISP_CHANGE_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL all_detached_settings(const struct x11drv_display_setting *displays, INT display_count)
|
||||||
|
{
|
||||||
|
INT display_idx;
|
||||||
|
|
||||||
|
for (display_idx = 0; display_idx < display_count; ++display_idx)
|
||||||
|
{
|
||||||
|
if (!is_detached_mode(&displays[display_idx].desired_mode))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* ChangeDisplaySettingsEx (X11DRV.@)
|
* ChangeDisplaySettingsEx (X11DRV.@)
|
||||||
*
|
*
|
||||||
|
@ -888,9 +908,19 @@ LONG CDECL X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode,
|
||||||
return DISP_CHANGE_SUCCESSFUL;
|
return DISP_CHANGE_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (all_detached_settings(displays, display_count))
|
||||||
|
{
|
||||||
|
WARN("Detaching all displays is not permitted.\n");
|
||||||
|
heap_free(displays);
|
||||||
|
return DISP_CHANGE_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
place_all_displays(displays, display_count);
|
place_all_displays(displays, display_count);
|
||||||
|
|
||||||
ret = apply_display_settings(displays, display_count);
|
/* Detach displays first to free up CRTCs */
|
||||||
|
ret = apply_display_settings(displays, display_count, FALSE);
|
||||||
|
if (ret == DISP_CHANGE_SUCCESSFUL)
|
||||||
|
ret = apply_display_settings(displays, display_count, TRUE);
|
||||||
if (ret == DISP_CHANGE_SUCCESSFUL)
|
if (ret == DISP_CHANGE_SUCCESSFUL)
|
||||||
X11DRV_DisplayDevices_Update(TRUE);
|
X11DRV_DisplayDevices_Update(TRUE);
|
||||||
heap_free(displays);
|
heap_free(displays);
|
||||||
|
|
|
@ -1306,6 +1306,27 @@ static LONG xrandr14_set_current_mode( ULONG_PTR id, DEVMODEW *mode )
|
||||||
if (!output_info || output_info->connection != RR_Connected)
|
if (!output_info || output_info->connection != RR_Connected)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
if (is_detached_mode(mode))
|
||||||
|
{
|
||||||
|
/* Already detached */
|
||||||
|
if (!output_info->crtc)
|
||||||
|
{
|
||||||
|
ret = DISP_CHANGE_SUCCESSFUL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execute detach operation */
|
||||||
|
status = pXRRSetCrtcConfig( gdi_display, screen_resources, output_info->crtc,
|
||||||
|
CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0 );
|
||||||
|
if (status == RRSetConfigSuccess)
|
||||||
|
{
|
||||||
|
get_screen_size( screen_resources, &screen_width, &screen_height );
|
||||||
|
set_screen_size( screen_width, screen_height );
|
||||||
|
ret = DISP_CHANGE_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* Attached */
|
/* Attached */
|
||||||
if (output_info->crtc)
|
if (output_info->crtc)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue