Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
4a248163
Commit
4a248163
authored
Jul 27, 2020
by
Zhiyi Zhang
Committed by
Alexandre Julliard
Jul 30, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winex11.drv: Support automatic display position adjustment.
Signed-off-by:
Zhiyi Zhang
<
zzhang@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
00b64430
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
333 additions
and
84 deletions
+333
-84
monitor.c
dlls/user32/tests/monitor.c
+3
-33
settings.c
dlls/winex11.drv/settings.c
+326
-48
xrandr.c
dlls/winex11.drv/xrandr.c
+4
-3
No files found.
dlls/user32/tests/monitor.c
View file @
4a248163
...
...
@@ -283,29 +283,9 @@ struct device_info
DEVMODEA
original_mode
;
};
static
BOOL
get_primary_adapter
(
CHAR
*
name
)
{
DISPLAY_DEVICEA
dd
;
DWORD
i
;
dd
.
cb
=
sizeof
(
dd
);
for
(
i
=
0
;
EnumDisplayDevicesA
(
NULL
,
i
,
&
dd
,
0
);
++
i
)
{
if
(
dd
.
StateFlags
&
DISPLAY_DEVICE_PRIMARY_DEVICE
)
{
lstrcpyA
(
name
,
dd
.
DeviceName
);
return
TRUE
;
}
}
return
FALSE
;
}
#define expect_dm(a, b, c) _expect_dm(__LINE__, a, b, c)
static
void
_expect_dm
(
INT
line
,
DEVMODEA
expected
,
const
CHAR
*
device
,
DWORD
test
)
{
CHAR
primary_adapter
[
CCHDEVICENAME
];
BOOL
is_primary
;
DEVMODEA
dm
;
BOOL
ret
;
...
...
@@ -315,33 +295,23 @@ static void _expect_dm(INT line, DEVMODEA expected, const CHAR *device, DWORD te
ret
=
EnumDisplaySettingsA
(
device
,
ENUM_CURRENT_SETTINGS
,
&
dm
);
ok_
(
__FILE__
,
line
)(
ret
,
"Device %s test %d EnumDisplaySettingsA failed, error %#x
\n
"
,
device
,
test
,
GetLastError
());
ok
(
get_primary_adapter
(
primary_adapter
),
"Failed to get primary adapter name.
\n
"
);
is_primary
=
!
lstrcmpA
(
primary_adapter
,
device
);
ok_
(
__FILE__
,
line
)((
dm
.
dmFields
&
expected
.
dmFields
)
==
expected
.
dmFields
,
"Device %s test %d expect dmFields to contain %#x, got %#x
\n
"
,
device
,
test
,
expected
.
dmFields
,
dm
.
dmFields
);
/* Wine doesn't support changing color depth yet */
todo_wine_if
(
expected
.
dmBitsPerPel
!=
32
&&
expected
.
dmBitsPerPel
!=
24
)
ok_
(
__FILE__
,
line
)(
dm
.
dmBitsPerPel
==
expected
.
dmBitsPerPel
,
"Device %s test %d expect dmBitsPerPel %d, got %d
\n
"
,
device
,
test
,
expected
.
dmBitsPerPel
,
dm
.
dmBitsPerPel
);
/* Wine currently reports primary monitor settings for non-primary monitors */
todo_wine_if
(
!
is_primary
&&
dm
.
dmPelsWidth
!=
expected
.
dmPelsWidth
)
ok_
(
__FILE__
,
line
)(
dm
.
dmPelsWidth
==
expected
.
dmPelsWidth
,
"Device %s test %d expect dmPelsWidth %d, got %d
\n
"
,
device
,
test
,
expected
.
dmPelsWidth
,
dm
.
dmPelsWidth
);
todo_wine_if
(
!
is_primary
&&
dm
.
dmPelsHeight
!=
expected
.
dmPelsHeight
)
ok_
(
__FILE__
,
line
)(
dm
.
dmPelsHeight
==
expected
.
dmPelsHeight
,
"Device %s test %d expect dmPelsHeight %d, got %d
\n
"
,
device
,
test
,
expected
.
dmPelsHeight
,
dm
.
dmPelsHeight
);
todo_wine_if
(
!
is_primary
&&
dm
.
dmPosition
.
x
!=
expected
.
dmPosition
.
x
)
ok_
(
__FILE__
,
line
)(
dm
.
dmPosition
.
x
==
expected
.
dmPosition
.
x
,
"Device %s test %d expect dmPosition.x %d, got %d
\n
"
,
device
,
test
,
expected
.
dmPosition
.
x
,
dm
.
dmPosition
.
x
);
todo_wine_if
(
!
is_primary
&&
dm
.
dmPosition
.
y
!=
expected
.
dmPosition
.
y
)
ok_
(
__FILE__
,
line
)(
dm
.
dmPosition
.
y
==
expected
.
dmPosition
.
y
,
"Device %s test %d expect dmPosition.y %d, got %d
\n
"
,
device
,
test
,
expected
.
dmPosition
.
y
,
dm
.
dmPosition
.
y
);
todo_wine_if
(
!
is_primary
&&
dm
.
dmDisplayFrequency
!=
expected
.
dmDisplayFrequency
)
ok_
(
__FILE__
,
line
)(
dm
.
dmDisplayFrequency
==
expected
.
dmDisplayFrequency
,
"Device %s test %d expect dmDisplayFrequency %d, got %d
\n
"
,
device
,
test
,
expected
.
dmDisplayFrequency
,
dm
.
dmDisplayFrequency
);
todo_wine_if
(
!
is_primary
&&
dm
.
dmDisplayOrientation
!=
expected
.
dmDisplayOrientation
)
ok_
(
__FILE__
,
line
)(
dm
.
dmDisplayOrientation
==
expected
.
dmDisplayOrientation
,
"Device %s test %d expect dmDisplayOrientation %d, got %d
\n
"
,
device
,
test
,
expected
.
dmDisplayOrientation
,
dm
.
dmDisplayOrientation
);
...
...
@@ -778,7 +748,7 @@ static void test_ChangeDisplaySettingsEx(void)
if
(
res
)
{
/* The secondary adapter should be to the right of the primary adapter */
todo_wine
ok
(
dm2
.
dmPosition
.
x
==
dm
.
dmPosition
.
x
+
dm
.
dmPelsWidth
,
ok
(
dm2
.
dmPosition
.
x
==
dm
.
dmPosition
.
x
+
dm
.
dmPelsWidth
,
"Expected dm2.dmPosition.x %d, got %d.
\n
"
,
dm
.
dmPosition
.
x
+
dm
.
dmPelsWidth
,
dm2
.
dmPosition
.
x
);
ok
(
dm2
.
dmPosition
.
y
==
dm
.
dmPosition
.
y
,
"Expected dm2.dmPosition.y %d, got %d.
\n
"
,
...
...
@@ -795,7 +765,7 @@ static void test_ChangeDisplaySettingsEx(void)
dm2
.
dmSize
=
sizeof
(
dm2
);
res
=
EnumDisplaySettingsA
(
devices
[
1
].
name
,
ENUM_CURRENT_SETTINGS
,
&
dm2
);
ok
(
res
,
"EnumDisplaySettingsA %s failed, error %#x
\n
"
,
devices
[
1
].
name
,
GetLastError
());
todo_wine
ok
((
dm2
.
dmPosition
.
x
==
dm
.
dmPosition
.
x
-
dm2
.
dmPelsWidth
)
,
ok
(
dm2
.
dmPosition
.
x
==
dm
.
dmPosition
.
x
-
dm2
.
dmPelsWidth
,
"Expected dmPosition.x %d, got %d.
\n
"
,
dm
.
dmPosition
.
x
-
dm2
.
dmPelsWidth
,
dm2
.
dmPosition
.
x
);
...
...
@@ -889,7 +859,7 @@ static void test_ChangeDisplaySettingsEx(void)
dm2
.
dmSize
=
sizeof
(
dm2
);
res
=
EnumDisplaySettingsA
(
devices
[
1
].
name
,
ENUM_CURRENT_SETTINGS
,
&
dm2
);
ok
(
res
,
"EnumDisplaySettingsA %s failed, error %#x
\n
"
,
devices
[
1
].
name
,
GetLastError
());
todo_wine
ok
(
dm2
.
dmPosition
.
x
==
dm
.
dmPelsWidth
,
"Expect dmPosition.x %d, got %d
\n
"
,
ok
(
dm2
.
dmPosition
.
x
==
dm
.
dmPelsWidth
,
"Expect dmPosition.x %d, got %d
\n
"
,
dm
.
dmPelsWidth
,
dm2
.
dmPosition
.
x
);
}
else
...
...
dlls/winex11.drv/settings.c
View file @
4a248163
...
...
@@ -36,6 +36,15 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
x11settings
);
struct
x11drv_display_setting
{
ULONG_PTR
id
;
BOOL
placed
;
RECT
new_rect
;
RECT
desired_rect
;
DEVMODEW
desired_mode
;
};
static
struct
x11drv_mode_info
*
dd_modes
=
NULL
;
static
unsigned
int
dd_mode_count
=
0
;
static
unsigned
int
dd_max_modes
=
0
;
...
...
@@ -534,88 +543,357 @@ static DEVMODEW *get_full_mode(ULONG_PTR id, const DEVMODEW *dev_mode)
return
full_mode
;
}
/***********************************************************************
* ChangeDisplaySettingsEx (X11DRV.@)
*
*/
LONG
CDECL
X11DRV_ChangeDisplaySettingsEx
(
LPCWSTR
devname
,
LPDEVMODEW
devmode
,
HWND
hwnd
,
DWORD
flags
,
LPVOID
lpvoid
)
static
LONG
get_display_settings
(
struct
x11drv_display_setting
**
new_displays
,
INT
*
new_display_count
,
const
WCHAR
*
dev_name
,
DEVMODEW
*
dev_mode
)
{
WCHAR
primary_adapter
[
CCHDEVICENAME
];
char
bpp_buffer
[
16
],
freq_buffer
[
18
];
DEVMODEW
default_mode
,
*
full_mode
;
ULONG_PTR
id
;
LONG
ret
;
DWORD
i
;
struct
x11drv_display_setting
*
displays
;
DEVMODEW
registry_mode
,
current_mode
;
INT
display_idx
,
display_count
=
0
;
DISPLAY_DEVICEW
display_device
;
LONG
ret
=
DISP_CHANGE_FAILED
;
display_device
.
cb
=
sizeof
(
display_device
);
for
(
display_idx
=
0
;
EnumDisplayDevicesW
(
NULL
,
display_idx
,
&
display_device
,
0
);
++
display_idx
)
++
display_count
;
displays
=
heap_calloc
(
display_count
,
sizeof
(
*
displays
));
if
(
!
displays
)
goto
done
;
/* Use the new interface if it is available */
if
(
!
handler
.
name
)
goto
old_interface
;
for
(
display_idx
=
0
;
display_idx
<
display_count
;
++
display_idx
)
{
if
(
!
EnumDisplayDevicesW
(
NULL
,
display_idx
,
&
display_device
,
0
))
goto
done
;
if
(
!
get_primary_adapter
(
primary_adapter
))
return
DISP_CHANGE_FAILED
;
if
(
!
handler
.
get_id
(
display_device
.
DeviceName
,
&
displays
[
display_idx
].
id
))
{
ret
=
DISP_CHANGE_BADPARAM
;
goto
done
;
}
if
(
!
devname
&&
!
devmode
)
if
(
!
dev_mode
)
{
registry_mode
.
dmSize
=
sizeof
(
registry_mode
);
if
(
!
EnumDisplaySettingsExW
(
display_device
.
DeviceName
,
ENUM_REGISTRY_SETTINGS
,
&
registry_mode
,
0
))
goto
done
;
displays
[
display_idx
].
desired_mode
=
registry_mode
;
}
else
if
(
!
lstrcmpiW
(
dev_name
,
display_device
.
DeviceName
))
{
displays
[
display_idx
].
desired_mode
=
*
dev_mode
;
if
(
!
(
dev_mode
->
dmFields
&
DM_POSITION
))
{
current_mode
.
dmSize
=
sizeof
(
current_mode
);
if
(
!
EnumDisplaySettingsExW
(
display_device
.
DeviceName
,
ENUM_CURRENT_SETTINGS
,
&
current_mode
,
0
))
goto
done
;
displays
[
display_idx
].
desired_mode
.
dmFields
|=
DM_POSITION
;
displays
[
display_idx
].
desired_mode
.
u1
.
s2
.
dmPosition
=
current_mode
.
u1
.
s2
.
dmPosition
;
}
}
else
{
current_mode
.
dmSize
=
sizeof
(
current_mode
);
if
(
!
EnumDisplaySettingsExW
(
display_device
.
DeviceName
,
ENUM_CURRENT_SETTINGS
,
&
current_mode
,
0
))
goto
done
;
displays
[
display_idx
].
desired_mode
=
current_mode
;
}
SetRect
(
&
displays
[
display_idx
].
desired_rect
,
displays
[
display_idx
].
desired_mode
.
u1
.
s2
.
dmPosition
.
x
,
displays
[
display_idx
].
desired_mode
.
u1
.
s2
.
dmPosition
.
y
,
displays
[
display_idx
].
desired_mode
.
u1
.
s2
.
dmPosition
.
x
+
displays
[
display_idx
].
desired_mode
.
dmPelsWidth
,
displays
[
display_idx
].
desired_mode
.
u1
.
s2
.
dmPosition
.
y
+
displays
[
display_idx
].
desired_mode
.
dmPelsHeight
);
lstrcpyW
(
displays
[
display_idx
].
desired_mode
.
dmDeviceName
,
display_device
.
DeviceName
);
}
*
new_displays
=
displays
;
*
new_display_count
=
display_count
;
return
DISP_CHANGE_SUCCESSFUL
;
done:
heap_free
(
displays
);
return
ret
;
}
static
INT
offset_length
(
POINT
offset
)
{
return
offset
.
x
*
offset
.
x
+
offset
.
y
*
offset
.
y
;
}
/* Check if a rect overlaps with placed display rects */
static
BOOL
overlap_placed_displays
(
const
RECT
*
rect
,
const
struct
x11drv_display_setting
*
displays
,
INT
display_count
)
{
INT
display_idx
;
RECT
intersect
;
for
(
display_idx
=
0
;
display_idx
<
display_count
;
++
display_idx
)
{
default_mode
.
dmSize
=
sizeof
(
default_mode
);
if
(
!
EnumDisplaySettingsExW
(
primary_adapter
,
ENUM_REGISTRY_SETTINGS
,
&
default_mode
,
0
))
if
(
displays
[
display_idx
].
placed
&&
IntersectRect
(
&
intersect
,
&
displays
[
display_idx
].
new_rect
,
rect
))
return
TRUE
;
}
return
FALSE
;
}
/* Get the offset with minimum length to place a display next to the placed displays with no spacing and overlaps */
static
POINT
get_placement_offset
(
const
struct
x11drv_display_setting
*
displays
,
INT
display_count
,
INT
placing_idx
)
{
POINT
points
[
8
],
left_top
,
offset
,
min_offset
=
{
0
,
0
};
INT
display_idx
,
point_idx
,
point_count
,
vertex_idx
;
BOOL
has_placed
=
FALSE
,
first
=
TRUE
;
INT
width
,
height
;
RECT
rect
;
/* If the display to be placed is detached, no offset is needed to place it */
if
(
IsRectEmpty
(
&
displays
[
placing_idx
].
desired_rect
))
return
min_offset
;
/* If there is no placed and attached display, place this display as it is */
for
(
display_idx
=
0
;
display_idx
<
display_count
;
++
display_idx
)
{
if
(
displays
[
display_idx
].
placed
&&
!
IsRectEmpty
(
&
displays
[
display_idx
].
new_rect
))
{
ERR
(
"Default mode not found for %s!
\n
"
,
wine_dbgstr_w
(
primary_adapter
))
;
return
DISP_CHANGE_BADMODE
;
has_placed
=
TRUE
;
break
;
}
}
devname
=
primary_adapter
;
devmode
=
&
default_mode
;
if
(
!
has_placed
)
return
min_offset
;
/* Try to place this display with each of its four vertices at every vertex of the placed
* displays and see which combination has the minimum offset length */
width
=
displays
[
placing_idx
].
desired_rect
.
right
-
displays
[
placing_idx
].
desired_rect
.
left
;
height
=
displays
[
placing_idx
].
desired_rect
.
bottom
-
displays
[
placing_idx
].
desired_rect
.
top
;
for
(
display_idx
=
0
;
display_idx
<
display_count
;
++
display_idx
)
{
if
(
!
displays
[
display_idx
].
placed
||
IsRectEmpty
(
&
displays
[
display_idx
].
new_rect
))
continue
;
/* Get four vertices of the placed display rectangle */
points
[
0
].
x
=
displays
[
display_idx
].
new_rect
.
left
;
points
[
0
].
y
=
displays
[
display_idx
].
new_rect
.
top
;
points
[
1
].
x
=
displays
[
display_idx
].
new_rect
.
left
;
points
[
1
].
y
=
displays
[
display_idx
].
new_rect
.
bottom
;
points
[
2
].
x
=
displays
[
display_idx
].
new_rect
.
right
;
points
[
2
].
y
=
displays
[
display_idx
].
new_rect
.
top
;
points
[
3
].
x
=
displays
[
display_idx
].
new_rect
.
right
;
points
[
3
].
y
=
displays
[
display_idx
].
new_rect
.
bottom
;
point_count
=
4
;
/* Intersected points when moving the display to be placed horizontally */
if
(
displays
[
placing_idx
].
desired_rect
.
bottom
>=
displays
[
display_idx
].
new_rect
.
top
&&
displays
[
placing_idx
].
desired_rect
.
top
<=
displays
[
display_idx
].
new_rect
.
bottom
)
{
points
[
point_count
].
x
=
displays
[
display_idx
].
new_rect
.
left
;
points
[
point_count
++
].
y
=
displays
[
placing_idx
].
desired_rect
.
top
;
points
[
point_count
].
x
=
displays
[
display_idx
].
new_rect
.
right
;
points
[
point_count
++
].
y
=
displays
[
placing_idx
].
desired_rect
.
top
;
}
/* Intersected points when moving the display to be placed vertically */
if
(
displays
[
placing_idx
].
desired_rect
.
left
<=
displays
[
display_idx
].
new_rect
.
right
&&
displays
[
placing_idx
].
desired_rect
.
right
>=
displays
[
display_idx
].
new_rect
.
left
)
{
points
[
point_count
].
x
=
displays
[
placing_idx
].
desired_rect
.
left
;
points
[
point_count
++
].
y
=
displays
[
display_idx
].
new_rect
.
top
;
points
[
point_count
].
x
=
displays
[
placing_idx
].
desired_rect
.
left
;
points
[
point_count
++
].
y
=
displays
[
display_idx
].
new_rect
.
bottom
;
}
/* Try moving each vertex of the display rectangle to each points */
for
(
point_idx
=
0
;
point_idx
<
point_count
;
++
point_idx
)
{
for
(
vertex_idx
=
0
;
vertex_idx
<
4
;
++
vertex_idx
)
{
switch
(
vertex_idx
)
{
/* Move the bottom right vertex to the point */
case
0
:
left_top
.
x
=
points
[
point_idx
].
x
-
width
;
left_top
.
y
=
points
[
point_idx
].
y
-
height
;
break
;
/* Move the bottom left vertex to the point */
case
1
:
left_top
.
x
=
points
[
point_idx
].
x
;
left_top
.
y
=
points
[
point_idx
].
y
-
height
;
break
;
/* Move the top right vertex to the point */
case
2
:
left_top
.
x
=
points
[
point_idx
].
x
-
width
;
left_top
.
y
=
points
[
point_idx
].
y
;
break
;
/* Move the top left vertex to the point */
case
3
:
left_top
.
x
=
points
[
point_idx
].
x
;
left_top
.
y
=
points
[
point_idx
].
y
;
break
;
}
offset
.
x
=
left_top
.
x
-
displays
[
placing_idx
].
desired_rect
.
left
;
offset
.
y
=
left_top
.
y
-
displays
[
placing_idx
].
desired_rect
.
top
;
rect
=
displays
[
placing_idx
].
desired_rect
;
OffsetRect
(
&
rect
,
offset
.
x
,
offset
.
y
);
if
(
!
overlap_placed_displays
(
&
rect
,
displays
,
display_count
))
{
if
(
first
)
{
min_offset
=
offset
;
first
=
FALSE
;
continue
;
}
if
(
offset_length
(
offset
)
<
offset_length
(
min_offset
))
min_offset
=
offset
;
}
}
}
}
if
(
!
handler
.
get_id
(
devname
,
&
id
))
return
min_offset
;
}
static
void
place_all_displays
(
struct
x11drv_display_setting
*
displays
,
INT
display_count
)
{
INT
left_most
=
INT_MAX
,
top_most
=
INT_MAX
;
INT
placing_idx
,
display_idx
;
POINT
min_offset
,
offset
;
/* Place all displays with no extra space between them and no overlapping */
while
(
1
)
{
ERR
(
"Failed to get %s device id.
\n
"
,
wine_dbgstr_w
(
devname
));
return
DISP_CHANGE_BADPARAM
;
/* Place the unplaced display with the minimum offset length first */
placing_idx
=
-
1
;
for
(
display_idx
=
0
;
display_idx
<
display_count
;
++
display_idx
)
{
if
(
displays
[
display_idx
].
placed
)
continue
;
offset
=
get_placement_offset
(
displays
,
display_count
,
display_idx
);
if
(
placing_idx
==
-
1
||
offset_length
(
offset
)
<
offset_length
(
min_offset
))
{
min_offset
=
offset
;
placing_idx
=
display_idx
;
}
}
/* If all displays are placed */
if
(
placing_idx
==
-
1
)
break
;
displays
[
placing_idx
].
new_rect
=
displays
[
placing_idx
].
desired_rect
;
OffsetRect
(
&
displays
[
placing_idx
].
new_rect
,
min_offset
.
x
,
min_offset
.
y
);
displays
[
placing_idx
].
placed
=
TRUE
;
}
if
(
is_detached_mode
(
devmode
)
)
for
(
display_idx
=
0
;
display_idx
<
display_count
;
++
display_idx
)
{
FIXME
(
"Detaching adapters is currently unsupported.
\n
"
);
return
DISP_CHANGE_SUCCESSFUL
;
displays
[
display_idx
].
desired_mode
.
u1
.
s2
.
dmPosition
.
x
=
displays
[
display_idx
].
new_rect
.
left
;
displays
[
display_idx
].
desired_mode
.
u1
.
s2
.
dmPosition
.
y
=
displays
[
display_idx
].
new_rect
.
top
;
left_most
=
min
(
left_most
,
displays
[
display_idx
].
new_rect
.
left
);
top_most
=
min
(
top_most
,
displays
[
display_idx
].
new_rect
.
top
);
}
if
(
!
(
full_mode
=
get_full_mode
(
id
,
devmode
)))
/* Convert virtual screen coordinates to root coordinates */
for
(
display_idx
=
0
;
display_idx
<
display_count
;
++
display_idx
)
{
ERR
(
"Failed to find a valid mode.
\n
"
)
;
return
DISP_CHANGE_BADMODE
;
displays
[
display_idx
].
desired_mode
.
u1
.
s2
.
dmPosition
.
x
-=
left_most
;
displays
[
display_idx
].
desired_mode
.
u1
.
s2
.
dmPosition
.
y
-=
top_most
;
}
}
if
(
flags
&
CDS_UPDATEREGISTRY
&&
!
write_registry_settings
(
devname
,
full_mode
))
static
LONG
apply_display_settings
(
struct
x11drv_display_setting
*
displays
,
INT
display_count
)
{
DEVMODEW
*
full_mode
;
INT
display_idx
;
LONG
ret
;
for
(
display_idx
=
0
;
display_idx
<
display_count
;
++
display_idx
)
{
ERR
(
"Failed to write %s display settings to registry.
\n
"
,
wine_dbgstr_w
(
devname
));
if
(
is_detached_mode
(
&
displays
[
display_idx
].
desired_mode
))
{
FIXME
(
"Detaching %s is currently unsupported.
\n
"
,
wine_dbgstr_w
(
displays
[
display_idx
].
desired_mode
.
dmDeviceName
));
continue
;
}
full_mode
=
get_full_mode
(
displays
[
display_idx
].
id
,
&
displays
[
display_idx
].
desired_mode
);
if
(
!
full_mode
)
return
DISP_CHANGE_BADMODE
;
full_mode
->
dmFields
|=
DM_POSITION
;
full_mode
->
u1
.
s2
.
dmPosition
=
displays
[
display_idx
].
desired_mode
.
u1
.
s2
.
dmPosition
;
TRACE
(
"handler:%s changing %s to position:(%d,%d) resolution:%ux%u frequency:%uHz "
"depth:%ubits orientation:%#x.
\n
"
,
handler
.
name
,
wine_dbgstr_w
(
displays
[
display_idx
].
desired_mode
.
dmDeviceName
),
full_mode
->
u1
.
s2
.
dmPosition
.
x
,
full_mode
->
u1
.
s2
.
dmPosition
.
y
,
full_mode
->
dmPelsWidth
,
full_mode
->
dmPelsHeight
,
full_mode
->
dmDisplayFrequency
,
full_mode
->
dmBitsPerPel
,
full_mode
->
u1
.
s2
.
dmDisplayOrientation
);
ret
=
handler
.
set_current_mode
(
displays
[
display_idx
].
id
,
full_mode
);
heap_free
(
full_mode
);
return
DISP_CHANGE_NOTUPDATED
;
if
(
ret
!=
DISP_CHANGE_SUCCESSFUL
)
return
ret
;
}
if
(
lstrcmpiW
(
primary_adapter
,
devname
))
return
DISP_CHANGE_SUCCESSFUL
;
}
/***********************************************************************
* ChangeDisplaySettingsEx (X11DRV.@)
*
*/
LONG
CDECL
X11DRV_ChangeDisplaySettingsEx
(
LPCWSTR
devname
,
LPDEVMODEW
devmode
,
HWND
hwnd
,
DWORD
flags
,
LPVOID
lpvoid
)
{
struct
x11drv_display_setting
*
displays
;
WCHAR
primary_adapter
[
CCHDEVICENAME
];
char
bpp_buffer
[
16
],
freq_buffer
[
18
];
INT
display_idx
,
display_count
;
DEVMODEW
default_mode
;
LONG
ret
;
DWORD
i
;
/* Use the new interface if it is available */
if
(
!
handler
.
name
)
goto
old_interface
;
ret
=
get_display_settings
(
&
displays
,
&
display_count
,
devname
,
devmode
);
if
(
ret
!=
DISP_CHANGE_SUCCESSFUL
)
return
ret
;
if
(
flags
&
CDS_UPDATEREGISTRY
&&
devname
&&
devmode
)
{
FIXME
(
"Changing non-primary adapter %s settings is currently unsupported.
\n
"
,
wine_dbgstr_w
(
devname
));
heap_free
(
full_mode
);
return
DISP_CHANGE_SUCCESSFUL
;
for
(
display_idx
=
0
;
display_idx
<
display_count
;
++
display_idx
)
{
if
(
!
lstrcmpiW
(
displays
[
display_idx
].
desired_mode
.
dmDeviceName
,
devname
))
{
if
(
!
write_registry_settings
(
devname
,
&
displays
[
display_idx
].
desired_mode
))
{
ERR
(
"Failed to write %s display settings to registry.
\n
"
,
wine_dbgstr_w
(
devname
));
heap_free
(
displays
);
return
DISP_CHANGE_NOTUPDATED
;
}
break
;
}
}
}
if
(
flags
&
(
CDS_TEST
|
CDS_NORESET
))
{
heap_free
(
full_mode
);
heap_free
(
displays
);
return
DISP_CHANGE_SUCCESSFUL
;
}
TRACE
(
"handler:%s device:%s position:(%d,%d) resolution:%ux%u frequency:%uHz depth:%ubits "
"orientation:%#x.
\n
"
,
handler
.
name
,
wine_dbgstr_w
(
devname
),
full_mode
->
u1
.
s2
.
dmPosition
.
x
,
full_mode
->
u1
.
s2
.
dmPosition
.
y
,
full_mode
->
dmPelsWidth
,
full_mode
->
dmPelsHeight
,
full_mode
->
dmDisplayFrequency
,
full_mode
->
dmBitsPerPel
,
full_mode
->
u1
.
s2
.
dmDisplayOrientation
);
place_all_displays
(
displays
,
display_count
);
ret
=
handler
.
set_current_mode
(
id
,
full_mode
);
ret
=
apply_display_settings
(
displays
,
display_count
);
if
(
ret
==
DISP_CHANGE_SUCCESSFUL
)
X11DRV_DisplayDevices_Update
(
TRUE
);
heap_free
(
full_mode
);
heap_free
(
displays
);
return
ret
;
old_interface:
...
...
dlls/winex11.drv/xrandr.c
View file @
4a248163
...
...
@@ -1367,12 +1367,13 @@ static LONG xrandr14_set_current_mode( ULONG_PTR id, DEVMODEW *mode )
goto
done
;
get_screen_size
(
screen_resources
,
&
screen_width
,
&
screen_height
);
screen_width
=
max
(
screen_width
,
crtc_info
->
x
+
mode
->
dmPelsWidth
);
screen_height
=
max
(
screen_height
,
crtc_info
->
y
+
mode
->
dmPelsHeight
);
screen_width
=
max
(
screen_width
,
mode
->
u1
.
s2
.
dmPosition
.
x
+
mode
->
dmPelsWidth
);
screen_height
=
max
(
screen_height
,
mode
->
u1
.
s2
.
dmPosition
.
y
+
mode
->
dmPelsHeight
);
set_screen_size
(
screen_width
,
screen_height
);
status
=
pXRRSetCrtcConfig
(
gdi_display
,
screen_resources
,
crtc
,
CurrentTime
,
crtc_info
->
x
,
crtc_info
->
y
,
rrmode
,
rotation
,
outputs
,
output_count
);
mode
->
u1
.
s2
.
dmPosition
.
x
,
mode
->
u1
.
s2
.
dmPosition
.
y
,
rrmode
,
rotation
,
outputs
,
output_count
);
if
(
status
==
RRSetConfigSuccess
)
ret
=
DISP_CHANGE_SUCCESSFUL
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment