Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
9b766959
Commit
9b766959
authored
Jun 20, 2023
by
Rémi Bernon
Committed by
Alexandre Julliard
Jun 21, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
win32u: Move virtual desktop display settings logic from winex11.
parent
08fd8ad0
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
258 additions
and
344 deletions
+258
-344
sysparams.c
dlls/win32u/sysparams.c
+241
-12
win32u_private.h
dlls/win32u/win32u_private.h
+1
-0
winstation.c
dlls/win32u/winstation.c
+2
-0
desktop.c
dlls/winex11.drv/desktop.c
+5
-295
display.c
dlls/winex11.drv/display.c
+9
-36
x11drv.h
dlls/winex11.drv/x11drv.h
+0
-1
No files found.
dlls/win32u/sysparams.c
View file @
9b766959
...
...
@@ -603,7 +603,11 @@ static BOOL adapter_get_current_settings( const struct adapter *adapter, DEVMODE
HKEY
hkey
;
BOOL
ret
;
if
((
ret
=
user_driver
->
pGetCurrentDisplaySettings
(
adapter
->
dev
.
device_name
,
is_primary
,
mode
)))
return
TRUE
;
/* use the default implementation in virtual desktop mode */
if
(
is_virtual_desktop
())
ret
=
FALSE
;
else
ret
=
user_driver
->
pGetCurrentDisplaySettings
(
adapter
->
dev
.
device_name
,
is_primary
,
mode
);
if
(
ret
)
return
TRUE
;
/* default implementation: read current display settings from the registry. */
...
...
@@ -1144,6 +1148,11 @@ struct device_manager_ctx
WCHAR
gpu_guid
[
64
];
LUID
gpu_luid
;
HKEY
adapter_key
;
/* for the virtual desktop settings */
BOOL
is_primary
;
UINT
primary_bpp
;
UINT
primary_width
;
UINT
primary_height
;
};
static
void
link_device
(
const
WCHAR
*
instance
,
const
WCHAR
*
class
)
...
...
@@ -1594,19 +1603,30 @@ static const struct gdi_device_manager device_manager =
add_mode
,
};
static
void
re
lease
_display_manager_ctx
(
struct
device_manager_ctx
*
ctx
)
static
void
re
set
_display_manager_ctx
(
struct
device_manager_ctx
*
ctx
)
{
if
(
ctx
->
mutex
)
{
pthread_mutex_unlock
(
&
display_lock
);
release_display_device_init_mutex
(
ctx
->
mutex
);
}
HANDLE
mutex
=
ctx
->
mutex
;
if
(
ctx
->
adapter_key
)
{
NtClose
(
ctx
->
adapter_key
);
last_query_display_time
=
0
;
}
if
(
ctx
->
gpu_count
)
cleanup_devices
();
memset
(
ctx
,
0
,
sizeof
(
*
ctx
)
);
if
((
ctx
->
mutex
=
mutex
))
prepare_devices
();
}
static
void
release_display_manager_ctx
(
struct
device_manager_ctx
*
ctx
)
{
if
(
ctx
->
mutex
)
{
pthread_mutex_unlock
(
&
display_lock
);
release_display_device_init_mutex
(
ctx
->
mutex
);
ctx
->
mutex
=
0
;
}
reset_display_manager_ctx
(
ctx
);
}
static
void
clear_display_devices
(
void
)
...
...
@@ -1781,12 +1801,203 @@ static BOOL update_display_devices( const struct gdi_device_manager *manager, BO
return
default_update_display_devices
(
manager
,
force
,
ctx
);
}
static
BOOL
update_display_cache
(
BOOL
force
)
/* parse the desktop size specification */
static
BOOL
parse_size
(
const
WCHAR
*
size
,
unsigned
int
*
width
,
unsigned
int
*
height
)
{
WCHAR
*
end
;
*
width
=
wcstoul
(
size
,
&
end
,
10
);
if
(
end
==
size
)
return
FALSE
;
if
(
*
end
!=
'x'
)
return
FALSE
;
size
=
end
+
1
;
*
height
=
wcstoul
(
size
,
&
end
,
10
);
return
!*
end
;
}
/* retrieve the default desktop size from the registry */
static
BOOL
get_default_desktop_size
(
unsigned
int
*
width
,
unsigned
int
*
height
)
{
static
const
WCHAR
defaultW
[]
=
{
'D'
,
'e'
,
'f'
,
'a'
,
'u'
,
'l'
,
't'
,
0
};
WCHAR
buffer
[
4096
];
KEY_VALUE_PARTIAL_INFORMATION
*
value
=
(
void
*
)
buffer
;
DWORD
size
;
HKEY
hkey
;
/* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
if
(
!
(
hkey
=
reg_open_hkcu_key
(
"Software
\\
Wine
\\
Explorer
\\
Desktops"
)))
return
FALSE
;
size
=
query_reg_value
(
hkey
,
defaultW
,
value
,
sizeof
(
buffer
)
);
NtClose
(
hkey
);
if
(
!
size
||
value
->
Type
!=
REG_SZ
)
return
FALSE
;
if
(
!
parse_size
(
(
const
WCHAR
*
)
value
->
Data
,
width
,
height
))
return
FALSE
;
return
TRUE
;
}
static
void
desktop_add_gpu
(
const
struct
gdi_gpu
*
gpu
,
void
*
param
)
{
}
static
void
desktop_add_adapter
(
const
struct
gdi_adapter
*
adapter
,
void
*
param
)
{
struct
device_manager_ctx
*
ctx
=
param
;
ctx
->
is_primary
=
!!
(
adapter
->
state_flags
&
DISPLAY_DEVICE_PRIMARY_DEVICE
);
}
static
void
desktop_add_monitor
(
const
struct
gdi_monitor
*
monitor
,
void
*
param
)
{
}
static
void
desktop_add_mode
(
const
DEVMODEW
*
mode
,
BOOL
current
,
void
*
param
)
{
struct
device_manager_ctx
*
ctx
=
param
;
if
(
ctx
->
is_primary
&&
current
)
{
ctx
->
primary_bpp
=
mode
->
dmBitsPerPel
;
ctx
->
primary_width
=
mode
->
dmPelsWidth
;
ctx
->
primary_height
=
mode
->
dmPelsHeight
;
}
}
static
const
struct
gdi_device_manager
desktop_device_manager
=
{
desktop_add_gpu
,
desktop_add_adapter
,
desktop_add_monitor
,
desktop_add_mode
,
};
static
BOOL
desktop_update_display_devices
(
BOOL
force
,
struct
device_manager_ctx
*
ctx
)
{
static
const
struct
gdi_gpu
gpu
;
static
const
struct
gdi_adapter
adapter
=
{
.
state_flags
=
DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
|
DISPLAY_DEVICE_PRIMARY_DEVICE
|
DISPLAY_DEVICE_VGA_COMPATIBLE
,
};
struct
gdi_monitor
monitor
=
{
.
state_flags
=
DISPLAY_DEVICE_ACTIVE
|
DISPLAY_DEVICE_ATTACHED
,
};
static
struct
screen_size
{
unsigned
int
width
;
unsigned
int
height
;
}
screen_sizes
[]
=
{
/* 4:3 */
{
320
,
240
},
{
400
,
300
},
{
512
,
384
},
{
640
,
480
},
{
768
,
576
},
{
800
,
600
},
{
1024
,
768
},
{
1152
,
864
},
{
1280
,
960
},
{
1400
,
1050
},
{
1600
,
1200
},
{
2048
,
1536
},
/* 5:4 */
{
1280
,
1024
},
{
2560
,
2048
},
/* 16:9 */
{
1280
,
720
},
{
1366
,
768
},
{
1600
,
900
},
{
1920
,
1080
},
{
2560
,
1440
},
{
3840
,
2160
},
/* 16:10 */
{
320
,
200
},
{
640
,
400
},
{
1280
,
800
},
{
1440
,
900
},
{
1680
,
1050
},
{
1920
,
1200
},
{
2560
,
1600
}
};
struct
device_manager_ctx
desktop_ctx
=
{
0
};
UINT
screen_width
,
screen_height
,
max_width
,
max_height
;
unsigned
int
depths
[]
=
{
8
,
16
,
0
};
DEVMODEW
current
,
mode
=
{
.
dmFields
=
DM_DISPLAYORIENTATION
|
DM_BITSPERPEL
|
DM_PELSWIDTH
|
DM_PELSHEIGHT
|
DM_DISPLAYFLAGS
|
DM_DISPLAYFREQUENCY
,
.
dmDisplayFrequency
=
60
,
};
UINT
i
,
j
;
if
(
!
force
)
return
TRUE
;
/* in virtual desktop mode, read the device list from the user driver but expose virtual devices */
if
(
!
update_display_devices
(
&
desktop_device_manager
,
TRUE
,
&
desktop_ctx
))
return
FALSE
;
max_width
=
desktop_ctx
.
primary_width
;
max_height
=
desktop_ctx
.
primary_height
;
depths
[
ARRAY_SIZE
(
depths
)
-
1
]
=
desktop_ctx
.
primary_bpp
;
if
(
!
get_default_desktop_size
(
&
screen_width
,
&
screen_height
))
{
screen_width
=
max_width
;
screen_height
=
max_height
;
}
add_gpu
(
&
gpu
,
ctx
);
add_adapter
(
&
adapter
,
ctx
);
if
(
!
read_adapter_mode
(
ctx
->
adapter_key
,
ENUM_CURRENT_SETTINGS
,
&
current
))
{
current
=
mode
;
current
.
dmFields
|=
DM_POSITION
;
current
.
dmBitsPerPel
=
desktop_ctx
.
primary_bpp
;
current
.
dmPelsWidth
=
screen_width
;
current
.
dmPelsHeight
=
screen_height
;
}
monitor
.
rc_monitor
.
right
=
current
.
dmPelsWidth
;
monitor
.
rc_monitor
.
bottom
=
current
.
dmPelsHeight
;
monitor
.
rc_work
.
right
=
current
.
dmPelsWidth
;
monitor
.
rc_work
.
bottom
=
current
.
dmPelsHeight
;
add_monitor
(
&
monitor
,
ctx
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
depths
);
++
i
)
{
mode
.
dmBitsPerPel
=
depths
[
i
];
for
(
j
=
0
;
j
<
ARRAY_SIZE
(
screen_sizes
);
++
j
)
{
mode
.
dmPelsWidth
=
screen_sizes
[
j
].
width
;
mode
.
dmPelsHeight
=
screen_sizes
[
j
].
height
;
if
(
mode
.
dmPelsWidth
>
max_width
||
mode
.
dmPelsHeight
>
max_height
)
continue
;
if
(
mode
.
dmPelsWidth
==
max_width
&&
mode
.
dmPelsHeight
==
max_height
)
continue
;
if
(
mode
.
dmPelsWidth
==
screen_width
&&
mode
.
dmPelsHeight
==
screen_height
)
continue
;
if
(
is_same_devmode
(
&
mode
,
&
current
))
add_mode
(
&
current
,
TRUE
,
ctx
);
else
add_mode
(
&
mode
,
FALSE
,
ctx
);
}
mode
.
dmPelsWidth
=
screen_width
;
mode
.
dmPelsHeight
=
screen_height
;
if
(
is_same_devmode
(
&
mode
,
&
current
))
add_mode
(
&
current
,
TRUE
,
ctx
);
else
add_mode
(
&
mode
,
FALSE
,
ctx
);
if
(
max_width
!=
screen_width
||
max_height
!=
screen_height
)
{
mode
.
dmPelsWidth
=
max_width
;
mode
.
dmPelsHeight
=
max_height
;
if
(
is_same_devmode
(
&
mode
,
&
current
))
add_mode
(
&
current
,
TRUE
,
ctx
);
else
add_mode
(
&
mode
,
FALSE
,
ctx
);
}
}
return
TRUE
;
}
BOOL
update_display_cache
(
BOOL
force
)
{
HWINSTA
winstation
=
NtUserGetProcessWindowStation
();
struct
device_manager_ctx
ctx
=
{
0
};
BOOL
was_virtual_desktop
,
ret
;
USEROBJECTFLAGS
flags
;
BOOL
ret
;
/* services do not have any adapters, only a virtual monitor */
if
(
NtUserGetObjectInformation
(
winstation
,
UOI_FLAGS
,
&
flags
,
sizeof
(
flags
),
NULL
)
...
...
@@ -1799,7 +2010,16 @@ static BOOL update_display_cache( BOOL force )
return
TRUE
;
}
ret
=
update_display_devices
(
&
device_manager
,
force
,
&
ctx
);
if
((
was_virtual_desktop
=
is_virtual_desktop
()))
ret
=
TRUE
;
else
ret
=
update_display_devices
(
&
device_manager
,
force
,
&
ctx
);
/* as update_display_devices calls the user driver, it starts explorer and may change the virtual desktop state */
if
(
ret
&&
is_virtual_desktop
())
{
reset_display_manager_ctx
(
&
ctx
);
ret
=
desktop_update_display_devices
(
force
||
!
was_virtual_desktop
,
&
ctx
);
}
release_display_manager_ctx
(
&
ctx
);
if
(
!
ret
)
WARN
(
"Failed to update display devices
\n
"
);
...
...
@@ -2909,7 +3129,11 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod
if
(
!
(
primary
=
find_adapter_device_by_id
(
0
)))
primary_name
[
0
]
=
0
;
else
wcscpy
(
primary_name
,
primary
->
device_name
);
if
((
ret
=
user_driver
->
pChangeDisplaySettings
(
displays
,
primary_name
,
hwnd
,
flags
,
lparam
))
==
E_NOTIMPL
)
/* use the default implementation in virtual desktop mode */
if
(
is_virtual_desktop
())
ret
=
E_NOTIMPL
;
else
ret
=
user_driver
->
pChangeDisplaySettings
(
displays
,
primary_name
,
hwnd
,
flags
,
lparam
);
if
(
ret
==
E_NOTIMPL
)
{
/* default implementation: write current display settings to the registry. */
mode
=
displays
;
...
...
@@ -3081,7 +3305,12 @@ INT get_display_depth( UNICODE_STRING *name )
}
is_primary
=
!!
(
device
->
state_flags
&
DISPLAY_DEVICE_PRIMARY_DEVICE
);
if
((
depth
=
user_driver
->
pGetDisplayDepth
(
device
->
device_name
,
is_primary
))
<
0
)
/* use the default implementation in virtual desktop mode */
if
(
is_virtual_desktop
())
depth
=
-
1
;
else
depth
=
user_driver
->
pGetDisplayDepth
(
device
->
device_name
,
is_primary
);
if
(
depth
<
0
)
{
struct
adapter
*
adapter
=
CONTAINING_RECORD
(
device
,
struct
adapter
,
dev
);
DEVMODEW
current_mode
=
{.
dmSize
=
sizeof
(
DEVMODEW
)};
...
...
dlls/win32u/win32u_private.h
View file @
9b766959
...
...
@@ -182,6 +182,7 @@ extern RECT rect_thread_to_win_dpi( HWND hwnd, RECT rect ) DECLSPEC_HIDDEN;
extern
HMONITOR
monitor_from_point
(
POINT
pt
,
UINT
flags
,
UINT
dpi
)
DECLSPEC_HIDDEN
;
extern
HMONITOR
monitor_from_rect
(
const
RECT
*
rect
,
UINT
flags
,
UINT
dpi
)
DECLSPEC_HIDDEN
;
extern
HMONITOR
monitor_from_window
(
HWND
hwnd
,
UINT
flags
,
UINT
dpi
)
DECLSPEC_HIDDEN
;
extern
BOOL
update_display_cache
(
BOOL
force
)
DECLSPEC_HIDDEN
;
extern
void
user_lock
(
void
)
DECLSPEC_HIDDEN
;
extern
void
user_unlock
(
void
)
DECLSPEC_HIDDEN
;
extern
void
user_check_not_lock
(
void
)
DECLSPEC_HIDDEN
;
...
...
dlls/win32u/winstation.c
View file @
9b766959
...
...
@@ -183,6 +183,8 @@ HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *dev
return
0
;
}
/* force update display cache to use virtual desktop display settings */
if
(
flags
&
DF_WINE_CREATE_DESKTOP
)
update_display_cache
(
TRUE
);
return
ret
;
}
...
...
dlls/winex11.drv/desktop.c
View file @
9b766959
...
...
@@ -38,279 +38,17 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
x11drv
);
static
unsigned
int
max_width
;
static
unsigned
int
max_height
;
static
unsigned
int
desktop_width
;
static
unsigned
int
desktop_height
;
static
struct
screen_size
{
unsigned
int
width
;
unsigned
int
height
;
}
screen_sizes
[]
=
{
/* 4:3 */
{
320
,
240
},
{
400
,
300
},
{
512
,
384
},
{
640
,
480
},
{
768
,
576
},
{
800
,
600
},
{
1024
,
768
},
{
1152
,
864
},
{
1280
,
960
},
{
1400
,
1050
},
{
1600
,
1200
},
{
2048
,
1536
},
/* 5:4 */
{
1280
,
1024
},
{
2560
,
2048
},
/* 16:9 */
{
1280
,
720
},
{
1366
,
768
},
{
1600
,
900
},
{
1920
,
1080
},
{
2560
,
1440
},
{
3840
,
2160
},
/* 16:10 */
{
320
,
200
},
{
640
,
400
},
{
1280
,
800
},
{
1440
,
900
},
{
1680
,
1050
},
{
1920
,
1200
},
{
2560
,
1600
}
};
static
RECT
host_primary_rect
;
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
/* parse the desktop size specification */
static
BOOL
parse_size
(
const
WCHAR
*
size
,
unsigned
int
*
width
,
unsigned
int
*
height
)
{
WCHAR
*
end
;
*
width
=
wcstoul
(
size
,
&
end
,
10
);
if
(
end
==
size
)
return
FALSE
;
if
(
*
end
!=
'x'
)
return
FALSE
;
size
=
end
+
1
;
*
height
=
wcstoul
(
size
,
&
end
,
10
);
return
!*
end
;
}
/* retrieve the default desktop size from the registry */
static
BOOL
get_default_desktop_size
(
unsigned
int
*
width
,
unsigned
int
*
height
)
{
static
const
WCHAR
defaultW
[]
=
{
'D'
,
'e'
,
'f'
,
'a'
,
'u'
,
'l'
,
't'
,
0
};
WCHAR
buffer
[
4096
];
KEY_VALUE_PARTIAL_INFORMATION
*
value
=
(
void
*
)
buffer
;
DWORD
size
;
HKEY
hkey
;
/* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
if
(
!
(
hkey
=
open_hkcu_key
(
"Software
\\
Wine
\\
Explorer
\\
Desktops"
)))
return
FALSE
;
size
=
query_reg_value
(
hkey
,
defaultW
,
value
,
sizeof
(
buffer
)
);
NtClose
(
hkey
);
if
(
!
size
||
value
->
Type
!=
REG_SZ
)
return
FALSE
;
if
(
!
parse_size
(
(
const
WCHAR
*
)
value
->
Data
,
width
,
height
))
return
FALSE
;
return
TRUE
;
}
/* Return TRUE if Wine is currently in virtual desktop mode */
BOOL
is_virtual_desktop
(
void
)
{
return
root_window
!=
DefaultRootWindow
(
gdi_display
);
}
/* Virtual desktop display settings handler */
static
BOOL
X11DRV_desktop_get_id
(
const
WCHAR
*
device_name
,
BOOL
is_primary
,
x11drv_settings_id
*
id
)
{
if
(
!
is_primary
)
return
FALSE
;
id
->
id
=
0
;
return
TRUE
;
}
static
void
add_desktop_mode
(
DEVMODEW
*
mode
,
DWORD
depth
,
DWORD
width
,
DWORD
height
)
{
mode
->
dmSize
=
sizeof
(
*
mode
);
mode
->
dmFields
=
DM_DISPLAYORIENTATION
|
DM_BITSPERPEL
|
DM_PELSWIDTH
|
DM_PELSHEIGHT
|
DM_DISPLAYFLAGS
|
DM_DISPLAYFREQUENCY
;
mode
->
u1
.
s2
.
dmDisplayOrientation
=
DMDO_DEFAULT
;
mode
->
dmBitsPerPel
=
depth
;
mode
->
dmPelsWidth
=
width
;
mode
->
dmPelsHeight
=
height
;
mode
->
u2
.
dmDisplayFlags
=
0
;
mode
->
dmDisplayFrequency
=
60
;
}
static
BOOL
X11DRV_desktop_get_modes
(
x11drv_settings_id
id
,
DWORD
flags
,
DEVMODEW
**
new_modes
,
UINT
*
mode_count
)
{
UINT
depth_idx
,
size_idx
,
mode_idx
=
0
;
UINT
screen_width
,
screen_height
;
DEVMODEW
*
modes
;
if
(
!
get_default_desktop_size
(
&
screen_width
,
&
screen_height
))
{
screen_width
=
max_width
;
screen_height
=
max_height
;
}
/* Allocate memory for modes in different color depths */
if
(
!
(
modes
=
calloc
(
(
ARRAY_SIZE
(
screen_sizes
)
+
2
)
*
DEPTH_COUNT
,
sizeof
(
*
modes
)))
)
{
RtlSetLastWin32Error
(
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
for
(
depth_idx
=
0
;
depth_idx
<
DEPTH_COUNT
;
++
depth_idx
)
{
for
(
size_idx
=
0
;
size_idx
<
ARRAY_SIZE
(
screen_sizes
);
++
size_idx
)
{
if
(
screen_sizes
[
size_idx
].
width
>
max_width
||
screen_sizes
[
size_idx
].
height
>
max_height
)
continue
;
if
(
screen_sizes
[
size_idx
].
width
==
max_width
&&
screen_sizes
[
size_idx
].
height
==
max_height
)
continue
;
if
(
screen_sizes
[
size_idx
].
width
==
screen_width
&&
screen_sizes
[
size_idx
].
height
==
screen_height
)
continue
;
add_desktop_mode
(
&
modes
[
mode_idx
++
],
depths
[
depth_idx
],
screen_sizes
[
size_idx
].
width
,
screen_sizes
[
size_idx
].
height
);
}
add_desktop_mode
(
&
modes
[
mode_idx
++
],
depths
[
depth_idx
],
screen_width
,
screen_height
);
if
(
max_width
!=
screen_width
||
max_height
!=
screen_height
)
add_desktop_mode
(
&
modes
[
mode_idx
++
],
depths
[
depth_idx
],
max_width
,
max_height
);
}
*
new_modes
=
modes
;
*
mode_count
=
mode_idx
;
return
TRUE
;
}
static
void
X11DRV_desktop_free_modes
(
DEVMODEW
*
modes
)
{
free
(
modes
);
}
static
BOOL
X11DRV_desktop_get_current_mode
(
x11drv_settings_id
id
,
DEVMODEW
*
mode
)
{
RECT
primary_rect
=
NtUserGetPrimaryMonitorRect
();
mode
->
dmFields
=
DM_DISPLAYORIENTATION
|
DM_BITSPERPEL
|
DM_PELSWIDTH
|
DM_PELSHEIGHT
|
DM_DISPLAYFLAGS
|
DM_DISPLAYFREQUENCY
|
DM_POSITION
;
mode
->
u1
.
s2
.
dmDisplayOrientation
=
DMDO_DEFAULT
;
mode
->
dmBitsPerPel
=
screen_bpp
;
mode
->
dmPelsWidth
=
primary_rect
.
right
-
primary_rect
.
left
;
mode
->
dmPelsHeight
=
primary_rect
.
bottom
-
primary_rect
.
top
;
mode
->
u2
.
dmDisplayFlags
=
0
;
mode
->
dmDisplayFrequency
=
60
;
mode
->
u1
.
s2
.
dmPosition
.
x
=
0
;
mode
->
u1
.
s2
.
dmPosition
.
y
=
0
;
return
TRUE
;
}
static
LONG
X11DRV_desktop_set_current_mode
(
x11drv_settings_id
id
,
const
DEVMODEW
*
mode
)
{
if
(
mode
->
dmFields
&
DM_BITSPERPEL
&&
mode
->
dmBitsPerPel
!=
screen_bpp
)
WARN
(
"Cannot change screen color depth from %dbits to %dbits!
\n
"
,
screen_bpp
,
(
int
)
mode
->
dmBitsPerPel
);
desktop_width
=
mode
->
dmPelsWidth
;
desktop_height
=
mode
->
dmPelsHeight
;
return
DISP_CHANGE_SUCCESSFUL
;
}
static
void
query_desktop_work_area
(
RECT
*
rc_work
)
{
static
const
WCHAR
trayW
[]
=
{
'S'
,
'h'
,
'e'
,
'l'
,
'l'
,
'_'
,
'T'
,
'r'
,
'a'
,
'y'
,
'W'
,
'n'
,
'd'
,
0
};
UNICODE_STRING
str
=
RTL_CONSTANT_STRING
(
trayW
);
RECT
rect
;
HWND
hwnd
=
NtUserFindWindowEx
(
0
,
0
,
&
str
,
NULL
,
0
);
if
(
!
hwnd
||
!
NtUserIsWindowVisible
(
hwnd
))
return
;
if
(
!
NtUserGetWindowRect
(
hwnd
,
&
rect
))
return
;
if
(
rect
.
top
)
rc_work
->
bottom
=
rect
.
top
;
else
rc_work
->
top
=
rect
.
bottom
;
TRACE
(
"found tray %p %s work area %s
\n
"
,
hwnd
,
wine_dbgstr_rect
(
&
rect
),
wine_dbgstr_rect
(
rc_work
)
);
}
static
BOOL
X11DRV_desktop_get_gpus
(
struct
gdi_gpu
**
new_gpus
,
int
*
count
)
{
static
const
WCHAR
wine_adapterW
[]
=
{
'W'
,
'i'
,
'n'
,
'e'
,
' '
,
'A'
,
'd'
,
'a'
,
'p'
,
't'
,
'e'
,
'r'
,
0
};
struct
gdi_gpu
*
gpu
;
gpu
=
calloc
(
1
,
sizeof
(
*
gpu
)
);
if
(
!
gpu
)
return
FALSE
;
if
(
!
get_host_primary_gpu
(
gpu
))
{
WARN
(
"Failed to get host primary gpu.
\n
"
);
lstrcpyW
(
gpu
->
name
,
wine_adapterW
);
}
*
new_gpus
=
gpu
;
*
count
=
1
;
return
TRUE
;
}
static
void
X11DRV_desktop_free_gpus
(
struct
gdi_gpu
*
gpus
)
{
free
(
gpus
);
}
/* TODO: Support multi-head virtual desktop */
static
BOOL
X11DRV_desktop_get_adapters
(
ULONG_PTR
gpu_id
,
struct
gdi_adapter
**
new_adapters
,
int
*
count
)
{
struct
gdi_adapter
*
adapter
;
adapter
=
calloc
(
1
,
sizeof
(
*
adapter
)
);
if
(
!
adapter
)
return
FALSE
;
adapter
->
state_flags
=
DISPLAY_DEVICE_PRIMARY_DEVICE
;
if
(
desktop_width
&&
desktop_height
)
adapter
->
state_flags
|=
DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
;
*
new_adapters
=
adapter
;
*
count
=
1
;
return
TRUE
;
}
static
void
X11DRV_desktop_free_adapters
(
struct
gdi_adapter
*
adapters
)
{
free
(
adapters
);
}
static
BOOL
X11DRV_desktop_get_monitors
(
ULONG_PTR
adapter_id
,
struct
gdi_monitor
**
new_monitors
,
int
*
count
)
{
struct
gdi_monitor
*
monitor
;
monitor
=
calloc
(
1
,
sizeof
(
*
monitor
)
);
if
(
!
monitor
)
return
FALSE
;
SetRect
(
&
monitor
->
rc_monitor
,
0
,
0
,
desktop_width
,
desktop_height
);
SetRect
(
&
monitor
->
rc_work
,
0
,
0
,
desktop_width
,
desktop_height
);
query_desktop_work_area
(
&
monitor
->
rc_work
);
monitor
->
state_flags
=
DISPLAY_DEVICE_ATTACHED
;
monitor
->
edid_len
=
0
;
monitor
->
edid
=
NULL
;
if
(
desktop_width
&&
desktop_height
)
monitor
->
state_flags
|=
DISPLAY_DEVICE_ACTIVE
;
*
new_monitors
=
monitor
;
*
count
=
1
;
return
TRUE
;
}
static
void
X11DRV_desktop_free_monitors
(
struct
gdi_monitor
*
monitors
,
int
count
)
{
free
(
monitors
);
}
/***********************************************************************
* X11DRV_init_desktop
*
...
...
@@ -318,39 +56,11 @@ static void X11DRV_desktop_free_monitors( struct gdi_monitor *monitors, int coun
*/
void
X11DRV_init_desktop
(
Window
win
,
unsigned
int
width
,
unsigned
int
height
)
{
RECT
primary_rect
=
get_host_primary_monitor_rect
();
struct
x11drv_settings_handler
settings_handler
;
host_primary_rect
=
get_host_primary_monitor_rect
();
root_window
=
win
;
managed_mode
=
FALSE
;
/* no managed windows in desktop mode */
desktop_width
=
width
;
desktop_height
=
height
;
max_width
=
primary_rect
.
right
;
max_height
=
primary_rect
.
bottom
;
/* Initialize virtual desktop display settings handler */
settings_handler
.
name
=
"Virtual Desktop"
;
settings_handler
.
priority
=
1000
;
settings_handler
.
get_id
=
X11DRV_desktop_get_id
;
settings_handler
.
get_modes
=
X11DRV_desktop_get_modes
;
settings_handler
.
free_modes
=
X11DRV_desktop_free_modes
;
settings_handler
.
get_current_mode
=
X11DRV_desktop_get_current_mode
;
settings_handler
.
set_current_mode
=
X11DRV_desktop_set_current_mode
;
X11DRV_Settings_SetHandler
(
&
settings_handler
);
/* Initialize virtual desktop mode display device handler */
desktop_handler
.
name
=
"Virtual Desktop"
;
desktop_handler
.
get_gpus
=
X11DRV_desktop_get_gpus
;
desktop_handler
.
get_adapters
=
X11DRV_desktop_get_adapters
;
desktop_handler
.
get_monitors
=
X11DRV_desktop_get_monitors
;
desktop_handler
.
free_gpus
=
X11DRV_desktop_free_gpus
;
desktop_handler
.
free_adapters
=
X11DRV_desktop_free_adapters
;
desktop_handler
.
free_monitors
=
X11DRV_desktop_free_monitors
;
desktop_handler
.
register_event_handlers
=
NULL
;
TRACE
(
"Display device functions are now handled by: Virtual Desktop
\n
"
);
}
/***********************************************************************
* X11DRV_CreateDesktop
*
...
...
@@ -388,8 +98,8 @@ BOOL X11DRV_CreateDesktop( const WCHAR *name, UINT width, UINT height )
BOOL
is_desktop_fullscreen
(
void
)
{
RECT
primary_rect
=
NtUserGetPrimaryMonitorRect
();
return
(
primary_rect
.
right
-
primary_rect
.
left
==
max_width
&&
primary_rect
.
bottom
-
primary_rect
.
top
==
max_height
);
return
(
primary_rect
.
right
-
primary_rect
.
left
==
host_primary_rect
.
right
-
host_primary_rect
.
left
&&
primary_rect
.
bottom
-
primary_rect
.
top
==
host_primary_rect
.
bottom
-
host_primary_rect
.
top
);
}
static
void
update_desktop_fullscreen
(
unsigned
int
width
,
unsigned
int
height
)
...
...
@@ -406,7 +116,7 @@ static void update_desktop_fullscreen( unsigned int width, unsigned int height)
xev
.
xclient
.
display
=
display
;
xev
.
xclient
.
send_event
=
True
;
xev
.
xclient
.
format
=
32
;
if
(
width
==
max_width
&&
height
==
max_height
)
if
(
width
==
host_primary_rect
.
right
-
host_primary_rect
.
left
&&
height
==
host_primary_rect
.
bottom
-
host_primary_rect
.
top
)
xev
.
xclient
.
data
.
l
[
0
]
=
_NET_WM_STATE_ADD
;
else
xev
.
xclient
.
data
.
l
[
0
]
=
_NET_WM_STATE_REMOVE
;
...
...
dlls/winex11.drv/display.c
View file @
9b766959
...
...
@@ -29,7 +29,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
x11drv
);
static
struct
x11drv_display_device_handler
host_handler
;
struct
x11drv_display_device_handler
desktop_handler
;
static
struct
x11drv_settings_handler
settings_handler
;
#define NEXT_DEVMODEW(mode) ((DEVMODEW *)((char *)((mode) + 1) + (mode)->dmDriverExtra))
...
...
@@ -414,21 +413,6 @@ RECT get_host_primary_monitor_rect(void)
return
rect
;
}
BOOL
get_host_primary_gpu
(
struct
gdi_gpu
*
gpu
)
{
struct
gdi_gpu
*
gpus
;
INT
gpu_count
;
if
(
host_handler
.
get_gpus
(
&
gpus
,
&
gpu_count
)
&&
gpu_count
)
{
*
gpu
=
gpus
[
0
];
host_handler
.
free_gpus
(
gpus
);
return
TRUE
;
}
return
FALSE
;
}
RECT
get_work_area
(
const
RECT
*
monitor_rect
)
{
Atom
type
;
...
...
@@ -499,10 +483,7 @@ void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler
void
X11DRV_DisplayDevices_RegisterEventHandlers
(
void
)
{
struct
x11drv_display_device_handler
*
handler
=
is_virtual_desktop
()
?
&
desktop_handler
:
&
host_handler
;
if
(
handler
->
register_event_handlers
)
handler
->
register_event_handlers
();
if
(
host_handler
.
register_event_handlers
)
host_handler
.
register_event_handlers
();
}
/* Report whether a display device handler supports detecting dynamic device changes */
...
...
@@ -534,7 +515,6 @@ static const char *debugstr_devmodew( const DEVMODEW *devmode )
BOOL
X11DRV_UpdateDisplayDevices
(
const
struct
gdi_device_manager
*
device_manager
,
BOOL
force
,
void
*
param
)
{
struct
x11drv_display_device_handler
*
handler
;
struct
gdi_adapter
*
adapters
;
struct
gdi_monitor
*
monitors
;
struct
gdi_gpu
*
gpus
;
...
...
@@ -542,17 +522,14 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage
INT
gpu
,
adapter
,
monitor
;
DEVMODEW
*
modes
,
*
mode
;
UINT
mode_count
;
BOOL
virtual_desktop
;
if
(
!
force
&&
!
force_display_devices_refresh
)
return
TRUE
;
force_display_devices_refresh
=
FALSE
;
virtual_desktop
=
is_virtual_desktop
();
handler
=
virtual_desktop
?
&
desktop_handler
:
&
host_handler
;
TRACE
(
"via %s
\n
"
,
wine_dbgstr_a
(
handler
->
name
)
);
TRACE
(
"via %s
\n
"
,
debugstr_a
(
host_handler
.
name
)
);
/* Initialize GPUs */
if
(
!
h
andler
->
get_gpus
(
&
gpus
,
&
gpu_count
))
return
FALSE
;
if
(
!
h
ost_handler
.
get_gpus
(
&
gpus
,
&
gpu_count
))
return
FALSE
;
TRACE
(
"GPU count: %d
\n
"
,
gpu_count
);
for
(
gpu
=
0
;
gpu
<
gpu_count
;
gpu
++
)
...
...
@@ -560,7 +537,7 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage
device_manager
->
add_gpu
(
&
gpus
[
gpu
],
param
);
/* Initialize adapters */
if
(
!
h
andler
->
get_adapters
(
gpus
[
gpu
].
id
,
&
adapters
,
&
adapter_count
))
break
;
if
(
!
h
ost_handler
.
get_adapters
(
gpus
[
gpu
].
id
,
&
adapters
,
&
adapter_count
))
break
;
TRACE
(
"GPU: %#lx %s, adapter count: %d
\n
"
,
gpus
[
gpu
].
id
,
wine_dbgstr_w
(
gpus
[
gpu
].
name
),
adapter_count
);
for
(
adapter
=
0
;
adapter
<
adapter_count
;
adapter
++
)
...
...
@@ -573,25 +550,21 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage
device_manager
->
add_adapter
(
&
adapters
[
adapter
],
param
);
if
(
!
h
andler
->
get_monitors
(
adapters
[
adapter
].
id
,
&
monitors
,
&
monitor_count
))
break
;
if
(
!
h
ost_handler
.
get_monitors
(
adapters
[
adapter
].
id
,
&
monitors
,
&
monitor_count
))
break
;
TRACE
(
"adapter: %#lx, monitor count: %d
\n
"
,
adapters
[
adapter
].
id
,
monitor_count
);
/* Initialize monitors */
for
(
monitor
=
0
;
monitor
<
monitor_count
;
monitor
++
)
device_manager
->
add_monitor
(
&
monitors
[
monitor
],
param
);
h
andler
->
free_monitors
(
monitors
,
monitor_count
);
h
ost_handler
.
free_monitors
(
monitors
,
monitor_count
);
/* Get the settings handler id for the adapter */
snprintf
(
buffer
,
sizeof
(
buffer
),
"
\\\\
.
\\
DISPLAY%d"
,
adapter
+
1
);
asciiz_to_unicode
(
devname
,
buffer
);
if
(
!
settings_handler
.
get_id
(
devname
,
is_primary
,
&
settings_id
))
break
;
/* We don't need to set the win32u current mode when we are in
* virtual desktop mode, and, additionally, skipping this avoids a
* deadlock, since the desktop get_current_mode() implementation
* recurses into win32u. */
if
(
!
virtual_desktop
)
settings_handler
.
get_current_mode
(
settings_id
,
&
current_mode
);
settings_handler
.
get_current_mode
(
settings_id
,
&
current_mode
);
if
(
!
settings_handler
.
get_modes
(
settings_id
,
EDS_ROTATEDMODE
,
&
modes
,
&
mode_count
))
continue
;
...
...
@@ -613,10 +586,10 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage
settings_handler
.
free_modes
(
modes
);
}
h
andler
->
free_adapters
(
adapters
);
h
ost_handler
.
free_adapters
(
adapters
);
}
h
andler
->
free_gpus
(
gpus
);
h
ost_handler
.
free_gpus
(
gpus
);
return
TRUE
;
}
...
...
dlls/winex11.drv/x11drv.h
View file @
9b766959
...
...
@@ -805,7 +805,6 @@ struct x11drv_display_device_handler
void
(
*
register_event_handlers
)(
void
);
};
extern
BOOL
get_host_primary_gpu
(
struct
gdi_gpu
*
gpu
)
DECLSPEC_HIDDEN
;
extern
void
X11DRV_DisplayDevices_SetHandler
(
const
struct
x11drv_display_device_handler
*
handler
)
DECLSPEC_HIDDEN
;
extern
void
X11DRV_DisplayDevices_Init
(
BOOL
force
)
DECLSPEC_HIDDEN
;
extern
void
X11DRV_DisplayDevices_RegisterEventHandlers
(
void
)
DECLSPEC_HIDDEN
;
...
...
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