In preparation for per-monitor DPI awareness.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/window.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index ab58cabb40e..3252260ce0a 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -5347,9 +5347,11 @@ static void fix_cs_coordinates( CREATESTRUCTW *cs, INT *sw ) /*********************************************************************** * map_dpi_create_struct */ -static void map_dpi_create_struct( CREATESTRUCTW *cs, UINT dpi_from, UINT dpi_to ) +static void map_dpi_create_struct( CREATESTRUCTW *cs, UINT dpi_to ) { - if (!dpi_from && !dpi_to) return; + RECT rect = {cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy}; + UINT dpi_from = get_thread_dpi(); + if (!dpi_from || !dpi_to) { POINT pt = { cs->x, cs->y }; @@ -5357,11 +5359,12 @@ static void map_dpi_create_struct( CREATESTRUCTW *cs, UINT dpi_from, UINT dpi_to if (!dpi_from) dpi_from = mon_dpi; else dpi_to = mon_dpi; } - if (dpi_from == dpi_to) return; - cs->x = muldiv( cs->x, dpi_to, dpi_from ); - cs->y = muldiv( cs->y, dpi_to, dpi_from ); - cs->cx = muldiv( cs->cx, dpi_to, dpi_from ); - cs->cy = muldiv( cs->cy, dpi_to, dpi_from ); + + rect = map_dpi_rect( rect, dpi_from, dpi_to ); + cs->x = rect.left; + cs->y = rect.top; + cs->cx = rect.right - rect.left; + cs->cy = rect.bottom - rect.top; }
/*********************************************************************** @@ -5373,7 +5376,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, HWND parent, HMENU menu, HINSTANCE instance, void *params, DWORD flags, HINSTANCE client_instance, DWORD unk, BOOL ansi ) { - UINT win_dpi, thread_dpi = get_thread_dpi(), context; + UINT win_dpi, context; struct window_surface *surface; struct window_rects new_rects; CBT_CREATEWNDW cbtc; @@ -5532,7 +5535,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, win_dpi = NTUSER_DPI_CONTEXT_GET_DPI( win->dpi_context ); release_win_ptr( win );
- if (parent) map_dpi_create_struct( &cs, thread_dpi, win_dpi ); + if (parent) map_dpi_create_struct( &cs, win_dpi );
context = set_thread_dpi_awareness_context( get_window_dpi_awareness_context( hwnd ));
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/window.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 3252260ce0a..4d5e57d3710 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -3249,15 +3249,15 @@ static void dump_winpos_flags( UINT flags ) */ static void map_dpi_winpos( WINDOWPOS *winpos ) { - UINT dpi_from = get_thread_dpi(); - UINT dpi_to = get_dpi_for_window( winpos->hwnd ); + RECT rect = {winpos->x, winpos->y, winpos->x + winpos->cx, winpos->y + winpos->cy}; + UINT dpi_from = get_thread_dpi(), dpi_to = get_dpi_for_window( winpos->hwnd );
if (!dpi_from) dpi_from = get_win_monitor_dpi( winpos->hwnd ); - if (dpi_from == dpi_to) return; - winpos->x = muldiv( winpos->x, dpi_to, dpi_from ); - winpos->y = muldiv( winpos->y, dpi_to, dpi_from ); - winpos->cx = muldiv( winpos->cx, dpi_to, dpi_from ); - winpos->cy = muldiv( winpos->cy, dpi_to, dpi_from ); + rect = map_dpi_rect( rect, dpi_from, dpi_to ); + winpos->x = rect.left; + winpos->y = rect.top; + winpos->cx = rect.right - rect.left; + winpos->cy = rect.bottom - rect.top; }
/***********************************************************************
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 116 ++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 53 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index b85700d1c6f..6199ad978cd 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2136,12 +2136,73 @@ UINT get_monitor_dpi( HMONITOR monitor ) return system_dpi; }
+/* display_lock must be held */ static RECT get_monitor_rect( struct monitor *monitor, BOOL work, UINT dpi ) { RECT rect = work ? monitor->rc_work : monitor->rc_monitor; return map_dpi_rect( rect, get_monitor_dpi( monitor->handle ), dpi ); }
+/* display_lock must be held */ +static struct monitor *get_monitor_from_rect( RECT rect, UINT flags, UINT dpi ) +{ + struct monitor *monitor, *primary = NULL, *nearest = NULL, *found = NULL; + UINT max_area = 0, min_distance = -1; + + if (IsRectEmpty( &rect )) + { + rect.right = rect.left + 1; + rect.bottom = rect.top + 1; + } + + LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry) + { + RECT intersect, monitor_rect; + + if (!is_monitor_active( monitor ) || monitor->is_clone) continue; + + monitor_rect = get_monitor_rect( monitor, FALSE, dpi ); + if (intersect_rect( &intersect, &monitor_rect, &rect )) + { + /* check for larger intersecting area */ + UINT area = (intersect.right - intersect.left) * (intersect.bottom - intersect.top); + if (area > max_area) + { + max_area = area; + found = monitor; + } + } + + if (!found && (flags & MONITOR_DEFAULTTONEAREST)) /* if not intersecting, check for min distance */ + { + UINT distance; + UINT x, y; + + if (rect.right <= monitor_rect.left) x = monitor_rect.left - rect.right; + else if (monitor_rect.right <= rect.left) x = rect.left - monitor_rect.right; + else x = 0; + if (rect.bottom <= monitor_rect.top) y = monitor_rect.top - rect.bottom; + else if (monitor_rect.bottom <= rect.top) y = rect.top - monitor_rect.bottom; + else y = 0; + distance = x * x + y * y; + if (distance < min_distance) + { + min_distance = distance; + nearest = monitor; + } + } + + if (!found && (flags & MONITOR_DEFAULTTOPRIMARY)) + { + if (is_monitor_primary( monitor )) primary = monitor; + } + } + + if (found) return found; + if (primary) return primary; + return nearest; +} + /********************************************************************** * get_win_monitor_dpi */ @@ -3700,67 +3761,16 @@ BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info, UINT dpi )
HMONITOR monitor_from_rect( const RECT *rect, UINT flags, UINT dpi ) { - HMONITOR primary = 0, nearest = 0, ret = 0; - UINT max_area = 0, min_distance = ~0u; struct monitor *monitor; + HMONITOR ret = 0; RECT r;
r = map_dpi_rect( *rect, dpi, system_dpi ); - if (IsRectEmpty( &r )) - { - r.right = r.left + 1; - r.bottom = r.top + 1; - }
if (!lock_display_devices()) return 0; - - LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry) - { - RECT intersect, monitor_rect; - - if (!is_monitor_active( monitor ) || monitor->is_clone) continue; - - monitor_rect = get_monitor_rect( monitor, FALSE, system_dpi ); - if (intersect_rect( &intersect, &monitor_rect, &r )) - { - /* check for larger intersecting area */ - UINT area = (intersect.right - intersect.left) * (intersect.bottom - intersect.top); - if (area > max_area) - { - max_area = area; - ret = monitor->handle; - } - } - else if (!max_area) /* if not intersecting, check for min distance */ - { - UINT distance; - UINT x, y; - - if (r.right <= monitor_rect.left) x = monitor_rect.left - r.right; - else if (monitor_rect.right <= r.left) x = r.left - monitor_rect.right; - else x = 0; - if (r.bottom <= monitor_rect.top) y = monitor_rect.top - r.bottom; - else if (monitor_rect.bottom <= r.top) y = r.top - monitor_rect.bottom; - else y = 0; - distance = x * x + y * y; - if (distance < min_distance) - { - min_distance = distance; - nearest = monitor->handle; - } - } - - if (is_monitor_primary( monitor )) primary = monitor->handle; - } - + if ((monitor = get_monitor_from_rect( r, flags, system_dpi ))) ret = monitor->handle; unlock_display_devices();
- if (!ret) - { - if (flags & MONITOR_DEFAULTTOPRIMARY) ret = primary; - else if (flags & MONITOR_DEFAULTTONEAREST) ret = nearest; - } - TRACE( "%s flags %x returning %p\n", wine_dbgstr_rect(rect), flags, ret ); return ret; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 62 ++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 22 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 6199ad978cd..d1ff1430a5b 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2137,12 +2137,27 @@ UINT get_monitor_dpi( HMONITOR monitor ) }
/* display_lock must be held */ -static RECT get_monitor_rect( struct monitor *monitor, BOOL work, UINT dpi ) +static RECT monitor_get_rect( struct monitor *monitor, BOOL work, UINT dpi ) { RECT rect = work ? monitor->rc_work : monitor->rc_monitor; return map_dpi_rect( rect, get_monitor_dpi( monitor->handle ), dpi ); }
+static void monitor_get_info( struct monitor *monitor, MONITORINFO *info, UINT dpi ) +{ + info->rcMonitor = monitor_get_rect( monitor, FALSE, dpi ); + info->rcWork = monitor_get_rect( monitor, TRUE, dpi ); + info->dwFlags = is_monitor_primary( monitor ) ? MONITORINFOF_PRIMARY : 0; + + if (info->cbSize >= sizeof(MONITORINFOEXW)) + { + char buffer[CCHDEVICENAME]; + if (monitor->source) snprintf( buffer, sizeof(buffer), "\\.\DISPLAY%d", monitor->source->id + 1 ); + else strcpy( buffer, "WinDisc" ); + asciiz_to_unicode( ((MONITORINFOEXW *)info)->szDevice, buffer ); + } +} + /* display_lock must be held */ static struct monitor *get_monitor_from_rect( RECT rect, UINT flags, UINT dpi ) { @@ -2161,7 +2176,7 @@ static struct monitor *get_monitor_from_rect( RECT rect, UINT flags, UINT dpi )
if (!is_monitor_active( monitor ) || monitor->is_clone) continue;
- monitor_rect = get_monitor_rect( monitor, FALSE, dpi ); + monitor_rect = monitor_get_rect( monitor, FALSE, dpi ); if (intersect_rect( &intersect, &monitor_rect, &rect )) { /* check for larger intersecting area */ @@ -2203,6 +2218,21 @@ static struct monitor *get_monitor_from_rect( RECT rect, UINT flags, UINT dpi ) return nearest; }
+/* display_lock must be held */ +static struct monitor *get_monitor_from_handle( HMONITOR handle ) +{ + struct monitor *monitor; + + LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) + { + if (monitor->handle != handle) continue; + if (!is_monitor_active( monitor )) continue; + return monitor; + } + + return NULL; +} + /********************************************************************** * get_win_monitor_dpi */ @@ -2417,7 +2447,7 @@ RECT get_virtual_screen_rect( UINT dpi ) { RECT monitor_rect; if (!is_monitor_active( monitor ) || monitor->is_clone) continue; - monitor_rect = get_monitor_rect( monitor, FALSE, dpi ); + monitor_rect = monitor_get_rect( monitor, FALSE, dpi ); union_rect( &rect, &rect, &monitor_rect ); }
@@ -2439,7 +2469,7 @@ static BOOL is_window_rect_full_screen( const RECT *rect, UINT dpi )
if (!is_monitor_active( monitor ) || monitor->is_clone) continue;
- monrect = get_monitor_rect( monitor, FALSE, dpi ); + monrect = monitor_get_rect( monitor, FALSE, dpi ); if (rect->left <= monrect.left && rect->right >= monrect.right && rect->top <= monrect.top && rect->bottom >= monrect.bottom) { @@ -2478,7 +2508,7 @@ RECT get_display_rect( const WCHAR *display ) LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { if (!monitor->source || monitor->source->id + 1 != index) continue; - rect = get_monitor_rect( monitor, FALSE, dpi ); + rect = monitor_get_rect( monitor, FALSE, dpi ); break; }
@@ -2496,7 +2526,7 @@ RECT get_primary_monitor_rect( UINT dpi ) LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { if (!is_monitor_primary( monitor )) continue; - rect = get_monitor_rect( monitor, FALSE, dpi ); + rect = monitor_get_rect( monitor, FALSE, dpi ); break; }
@@ -3636,7 +3666,7 @@ static BOOL should_enumerate_monitor( struct monitor *monitor, const POINT *orig if (!is_monitor_active( monitor )) return FALSE; if (monitor->is_clone) return FALSE;
- *rect = get_monitor_rect( monitor, FALSE, get_thread_dpi() ); + *rect = monitor_get_rect( monitor, FALSE, get_thread_dpi() ); OffsetRect( rect, -origin->x, -origin->y ); return intersect_rect( rect, rect, limit ); } @@ -3731,21 +3761,9 @@ BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info, UINT dpi )
if (!lock_display_devices()) return FALSE;
- LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) + if ((monitor = get_monitor_from_handle( handle ))) { - if (monitor->handle != handle) continue; - if (!is_monitor_active( monitor )) continue; - - info->rcMonitor = get_monitor_rect( monitor, FALSE, dpi ); - info->rcWork = get_monitor_rect( monitor, TRUE, dpi ); - info->dwFlags = is_monitor_primary( monitor ) ? MONITORINFOF_PRIMARY : 0; - if (info->cbSize >= sizeof(MONITORINFOEXW)) - { - char buffer[CCHDEVICENAME]; - if (monitor->source) snprintf( buffer, sizeof(buffer), "\\.\DISPLAY%d", monitor->source->id + 1 ); - else strcpy( buffer, "WinDisc" ); - asciiz_to_unicode( ((MONITORINFOEXW *)info)->szDevice, buffer ); - } + monitor_get_info( monitor, info, dpi ); unlock_display_devices();
TRACE( "flags %04x, monitor %s, work %s\n", (int)info->dwFlags, @@ -5352,7 +5370,7 @@ BOOL WINAPI NtUserSystemParametersInfo( UINT action, UINT val, void *ptr, UINT w LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { if (!is_monitor_primary( monitor )) continue; - work_area = get_monitor_rect( monitor, TRUE, dpi ); + work_area = monitor_get_rect( monitor, TRUE, dpi ); break; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index d1ff1430a5b..481c568ce02 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2127,10 +2127,8 @@ static void release_display_dc( HDC hdc ) pthread_mutex_unlock( &display_dc_lock ); }
-/********************************************************************** - * get_monitor_dpi - */ -UINT get_monitor_dpi( HMONITOR monitor ) +/* display_lock must be held */ +static UINT monitor_get_dpi( struct monitor *monitor ) { /* FIXME: use the monitor DPI instead */ return system_dpi; @@ -2140,7 +2138,7 @@ UINT get_monitor_dpi( HMONITOR monitor ) static RECT monitor_get_rect( struct monitor *monitor, BOOL work, UINT dpi ) { RECT rect = work ? monitor->rc_work : monitor->rc_monitor; - return map_dpi_rect( rect, get_monitor_dpi( monitor->handle ), dpi ); + return map_dpi_rect( rect, monitor_get_dpi( monitor ), dpi ); }
static void monitor_get_info( struct monitor *monitor, MONITORINFO *info, UINT dpi ) @@ -2233,6 +2231,21 @@ static struct monitor *get_monitor_from_handle( HMONITOR handle ) return NULL; }
+/********************************************************************** + * get_monitor_dpi + */ +UINT get_monitor_dpi( HMONITOR handle ) +{ + struct monitor *monitor; + UINT dpi = system_dpi; + + if (!lock_display_devices()) return 0; + if ((monitor = get_monitor_from_handle( handle ))) dpi = monitor_get_dpi( monitor ); + unlock_display_devices(); + + return dpi; +} + /********************************************************************** * get_win_monitor_dpi */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/input.c | 48 +++++++++++++++++------------------- dlls/win32u/sysparams.c | 17 ++++++++++--- dlls/win32u/win32u_private.h | 2 +- dlls/win32u/window.c | 16 ++++-------- 4 files changed, 42 insertions(+), 41 deletions(-)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 0324909c954..9a4ee0e25a1 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -706,22 +706,19 @@ UINT WINAPI NtUserSendInput( UINT count, INPUT *inputs, int size ) */ BOOL WINAPI NtUserSetCursorPos( INT x, INT y ) { - POINT pt = { x, y }; + RECT rect = {x, y, x, y}; BOOL ret; INT prev_x, prev_y, new_x, new_y; UINT dpi;
- if ((dpi = get_thread_dpi())) - { - HMONITOR monitor = monitor_from_point( pt, MONITOR_DEFAULTTOPRIMARY, get_thread_dpi() ); - pt = map_dpi_point( pt, dpi, get_monitor_dpi( monitor )); - } + dpi = monitor_dpi_from_rect( rect, get_thread_dpi() ); + rect = map_dpi_rect( rect, get_thread_dpi(), dpi );
SERVER_START_REQ( set_cursor ) { req->flags = SET_CURSOR_POS; - req->x = pt.x; - req->y = pt.y; + req->x = rect.left; + req->y = rect.top; if ((ret = !wine_server_call( req ))) { prev_x = reply->prev_x; @@ -742,9 +739,10 @@ BOOL get_cursor_pos( POINT *pt ) { struct object_lock lock = OBJECT_LOCK_INIT; const desktop_shm_t *desktop_shm; - BOOL ret; + BOOL ret = TRUE; DWORD last_change = 0; NTSTATUS status; + RECT rect; UINT dpi;
if (!pt) return FALSE; @@ -755,15 +753,16 @@ BOOL get_cursor_pos( POINT *pt ) pt->y = desktop_shm->cursor.y; last_change = desktop_shm->cursor.last_change; } - ret = !status; + if (status) return FALSE;
/* query new position from graphics driver if we haven't updated recently */ - if (ret && NtGetTickCount() - last_change > 100) ret = user_driver->pGetCursorPos( pt ); - if (ret && (dpi = get_thread_dpi())) - { - HMONITOR monitor = monitor_from_point( *pt, MONITOR_DEFAULTTOPRIMARY, 0 ); - *pt = map_dpi_point( *pt, get_monitor_dpi( monitor ), dpi ); - } + if (NtGetTickCount() - last_change > 100) ret = user_driver->pGetCursorPos( pt ); + if (ret) return FALSE; + + SetRect( &rect, pt->x, pt->y, pt->x, pt->y ); + dpi = monitor_dpi_from_rect( rect, get_thread_dpi() ); + rect = map_dpi_rect( rect, dpi, get_thread_dpi() ); + *pt = *(POINT *)&rect.left; return ret; }
@@ -2619,8 +2618,10 @@ BOOL get_clip_cursor( RECT *rect, UINT dpi )
if (!status) { - HMONITOR monitor = monitor_from_rect( rect, MONITOR_DEFAULTTOPRIMARY, 0 ); - *rect = map_dpi_rect( *rect, get_monitor_dpi( monitor ), dpi ); + UINT ctx = set_thread_dpi_awareness_context( NTUSER_DPI_PER_MONITOR_AWARE ); + UINT dpi_from = monitor_dpi_from_rect( *rect, get_thread_dpi() ); + *rect = map_dpi_rect( *rect, dpi_from, dpi ); + set_thread_dpi_awareness_context( ctx ); } return !status; } @@ -2666,7 +2667,7 @@ BOOL process_wine_clipcursor( HWND hwnd, UINT flags, BOOL reset ) */ BOOL WINAPI NtUserClipCursor( const RECT *rect ) { - UINT dpi; + UINT dpi_from = get_thread_dpi(), dpi_to; BOOL ret; RECT new_rect;
@@ -2675,12 +2676,9 @@ BOOL WINAPI NtUserClipCursor( const RECT *rect ) if (rect) { if (rect->left > rect->right || rect->top > rect->bottom) return FALSE; - if ((dpi = get_thread_dpi())) - { - HMONITOR monitor = monitor_from_rect( rect, MONITOR_DEFAULTTOPRIMARY, dpi ); - new_rect = map_dpi_rect( *rect, dpi, get_monitor_dpi( monitor )); - rect = &new_rect; - } + dpi_to = monitor_dpi_from_rect( *rect, dpi_from ); + new_rect = map_dpi_rect( *rect, dpi_from, dpi_to ); + rect = &new_rect; }
SERVER_START_REQ( set_cursor ) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 481c568ce02..e16e8869b40 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2231,10 +2231,7 @@ static struct monitor *get_monitor_from_handle( HMONITOR handle ) return NULL; }
-/********************************************************************** - * get_monitor_dpi - */ -UINT get_monitor_dpi( HMONITOR handle ) +static UINT get_monitor_dpi( HMONITOR handle ) { struct monitor *monitor; UINT dpi = system_dpi; @@ -3813,6 +3810,18 @@ HMONITOR monitor_from_point( POINT pt, UINT flags, UINT dpi ) return monitor_from_rect( &rect, flags, dpi ); }
+UINT monitor_dpi_from_rect( RECT rect, UINT dpi ) +{ + struct monitor *monitor; + UINT ret = system_dpi; + + if (!lock_display_devices()) return 0; + if ((monitor = get_monitor_from_rect( rect, MONITOR_DEFAULTTONEAREST, dpi ))) ret = monitor_get_dpi( monitor ); + unlock_display_devices(); + + return ret; +} + /* see MonitorFromWindow */ HMONITOR monitor_from_window( HWND hwnd, UINT flags, UINT dpi ) { diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index f7d869d1feb..fff5004c950 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -167,7 +167,6 @@ extern LONG get_char_dimensions( HDC hdc, TEXTMETRICW *metric, int *height ); extern HBITMAP get_display_bitmap(void); extern INT get_display_depth( UNICODE_STRING *name ); extern RECT get_display_rect( const WCHAR *display ); -extern UINT get_monitor_dpi( HMONITOR monitor ); extern BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info, UINT dpi ); extern UINT get_win_monitor_dpi( HWND hwnd ); extern RECT get_primary_monitor_rect( UINT dpi ); @@ -193,6 +192,7 @@ extern RECT rect_thread_to_win_dpi( HWND hwnd, RECT rect ); extern HMONITOR monitor_from_point( POINT pt, UINT flags, UINT dpi ); extern HMONITOR monitor_from_rect( const RECT *rect, UINT flags, UINT dpi ); extern HMONITOR monitor_from_window( HWND hwnd, UINT flags, UINT dpi ); +extern UINT monitor_dpi_from_rect( RECT rect, UINT dpi ); extern BOOL update_display_cache( BOOL force ); extern void user_lock(void); extern void user_unlock(void); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 4d5e57d3710..88bf35ccb8e 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -903,8 +903,8 @@ UINT get_dpi_for_window( HWND hwnd ) } if (win == WND_DESKTOP) { - POINT pt = { 0, 0 }; - return get_monitor_dpi( monitor_from_point( pt, MONITOR_DEFAULTTOPRIMARY, 0 )); + RECT rect = {0}; + return monitor_dpi_from_rect( rect, get_thread_dpi() ); } if (win != WND_OTHER_PROCESS) { @@ -1899,12 +1899,10 @@ static struct window_surface *get_window_surface( HWND hwnd, UINT swp_flags, BOO struct window_surface *new_surface; struct window_rects monitor_rects; UINT monitor_dpi, style, ex_style; - HMONITOR monitor; RECT dummy; HRGN shape;
- monitor = monitor_from_rect( &rects->window, MONITOR_DEFAULTTONEAREST, get_thread_dpi() ); - monitor_dpi = get_monitor_dpi( monitor ); + monitor_dpi = monitor_dpi_from_rect( rects->window, get_thread_dpi() );
style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); ex_style = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ); @@ -1977,7 +1975,6 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru struct window_rects old_rects; RECT extra_rects[3]; struct window_surface *old_surface; - HMONITOR monitor; UINT monitor_dpi;
is_layered = new_surface && new_surface->alpha_mask; @@ -1998,9 +1995,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru valid_rects = NULL; }
- monitor = monitor_from_rect( &new_rects->window, MONITOR_DEFAULTTONEAREST, get_thread_dpi() ); - monitor_dpi = get_monitor_dpi( monitor ); - + monitor_dpi = monitor_dpi_from_rect( new_rects->window, get_thread_dpi() ); monitor_rects = map_dpi_window_rects( *new_rects, get_thread_dpi(), monitor_dpi );
SERVER_START_REQ( set_window_pos ) @@ -5354,8 +5349,7 @@ static void map_dpi_create_struct( CREATESTRUCTW *cs, UINT dpi_to )
if (!dpi_from || !dpi_to) { - POINT pt = { cs->x, cs->y }; - UINT mon_dpi = get_monitor_dpi( monitor_from_point( pt, MONITOR_DEFAULTTONEAREST, dpi_from )); + UINT mon_dpi = monitor_dpi_from_rect( rect, get_thread_dpi() ); if (!dpi_from) dpi_from = mon_dpi; else dpi_to = mon_dpi; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/defwnd.c | 21 +++++++-------------- dlls/win32u/menu.c | 10 +++------- dlls/win32u/sysparams.c | 15 ++++++++++----- dlls/win32u/win32u_private.h | 3 +-- dlls/win32u/window.c | 5 +---- 5 files changed, 22 insertions(+), 32 deletions(-)
diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index c8b9897644c..c6103276cf9 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -670,7 +670,6 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) UINT style = get_window_long( hwnd, GWL_STYLE ); POINT capture_point, pt; MINMAXINFO minmax; - HMONITOR mon = 0; HWND parent; UINT dpi; HDC hdc; @@ -724,7 +723,6 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) { parent = 0; mouse_rect = get_virtual_screen_rect( get_thread_dpi() ); - mon = monitor_from_point( pt, MONITOR_DEFAULTTONEAREST, dpi ); }
if (on_left_border( hittest )) @@ -819,20 +817,15 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam )
if (!parent) { - HMONITOR newmon; MONITORINFO info; + RECT rect;
- if ((newmon = monitor_from_point( pt, MONITOR_DEFAULTTONULL, get_thread_dpi() ))) - mon = newmon; - - info.cbSize = sizeof(info); - if (mon && get_monitor_info( mon, &info, get_thread_dpi() )) - { - pt.x = max( pt.x, info.rcWork.left ); - pt.x = min( pt.x, info.rcWork.right - 1 ); - pt.y = max( pt.y, info.rcWork.top ); - pt.y = min( pt.y, info.rcWork.bottom - 1 ); - } + SetRect( &rect, pt.x, pt.y, pt.x, pt.y ); + info = monitor_info_from_rect( rect, get_thread_dpi() ); + pt.x = max( pt.x, info.rcWork.left ); + pt.x = min( pt.x, info.rcWork.right - 1 ); + pt.y = max( pt.y, info.rcWork.top ); + pt.y = min( pt.y, info.rcWork.bottom - 1 ); }
dx = pt.x - capture_point.x; diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c index 81b5fda6176..1f1e5f68e21 100644 --- a/dlls/win32u/menu.c +++ b/dlls/win32u/menu.c @@ -3046,10 +3046,9 @@ static BOOL show_popup( HWND owner, HMENU hmenu, UINT id, UINT flags, int x, int y, INT xanchor, INT yanchor ) { struct menu *menu; - HMONITOR monitor; MONITORINFO info; UINT max_height; - POINT pt; + RECT rect;
TRACE( "owner=%p hmenu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n", owner, hmenu, id, x, y, xanchor, yanchor ); @@ -3064,11 +3063,8 @@ static BOOL show_popup( HWND owner, HMENU hmenu, UINT id, UINT flags, menu->nScrollPos = 0;
/* FIXME: should use item rect */ - pt.x = x; - pt.y = y; - monitor = monitor_from_point( pt, MONITOR_DEFAULTTONEAREST, get_thread_dpi() ); - info.cbSize = sizeof(info); - get_monitor_info( monitor, &info, get_thread_dpi() ); + SetRect( &rect, x, y, x, y ); + info = monitor_info_from_rect( rect, get_thread_dpi() );
max_height = info.rcWork.bottom - info.rcWork.top; if (menu->cyMax) max_height = min( max_height, menu->cyMax ); diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index e16e8869b40..c54659a0e2e 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -3787,7 +3787,7 @@ BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info, UINT dpi ) return FALSE; }
-HMONITOR monitor_from_rect( const RECT *rect, UINT flags, UINT dpi ) +static HMONITOR monitor_from_rect( const RECT *rect, UINT flags, UINT dpi ) { struct monitor *monitor; HMONITOR ret = 0; @@ -3803,11 +3803,16 @@ HMONITOR monitor_from_rect( const RECT *rect, UINT flags, UINT dpi ) return ret; }
-HMONITOR monitor_from_point( POINT pt, UINT flags, UINT dpi ) +MONITORINFO monitor_info_from_rect( RECT rect, UINT dpi ) { - RECT rect; - SetRect( &rect, pt.x, pt.y, pt.x + 1, pt.y + 1 ); - return monitor_from_rect( &rect, flags, dpi ); + MONITORINFO info = {.cbSize = sizeof(info)}; + struct monitor *monitor; + + if (!lock_display_devices()) return info; + if ((monitor = get_monitor_from_rect( rect, MONITOR_DEFAULTTONEAREST, dpi ))) monitor_get_info( monitor, &info, dpi ); + unlock_display_devices(); + + return info; }
UINT monitor_dpi_from_rect( RECT rect, UINT dpi ) diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index fff5004c950..2c0defe06ea 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -189,9 +189,8 @@ extern BOOL message_beep( UINT i ); extern POINT point_phys_to_win_dpi( HWND hwnd, POINT pt ); extern POINT point_thread_to_win_dpi( HWND hwnd, POINT pt ); extern RECT rect_thread_to_win_dpi( HWND hwnd, RECT rect ); -extern HMONITOR monitor_from_point( POINT pt, UINT flags, UINT dpi ); -extern HMONITOR monitor_from_rect( const RECT *rect, UINT flags, UINT dpi ); extern HMONITOR monitor_from_window( HWND hwnd, UINT flags, UINT dpi ); +extern MONITORINFO monitor_info_from_rect( RECT rect, UINT dpi ); extern UINT monitor_dpi_from_rect( RECT rect, UINT dpi ); extern BOOL update_display_cache( BOOL force ); extern void user_lock(void); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 88bf35ccb8e..9e20316f3e1 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2741,11 +2741,8 @@ BOOL WINAPI NtUserGetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *placement ) /* make sure the specified rect is visible on screen */ static void make_rect_onscreen( RECT *rect ) { - MONITORINFO info; - HMONITOR monitor = monitor_from_rect( rect, MONITOR_DEFAULTTONEAREST, get_thread_dpi() ); + MONITORINFO info = monitor_info_from_rect( *rect, get_thread_dpi() );
- info.cbSize = sizeof(info); - if (!monitor || !get_monitor_info( monitor, &info, get_thread_dpi() )) return; /* FIXME: map coordinates from rcWork to rcMonitor */ if (rect->right <= info.rcWork.left) {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/input.c | 13 +++++++------ dlls/win32u/sysparams.c | 10 +++++++++- dlls/win32u/win32u_private.h | 2 +- dlls/win32u/window.c | 23 ++++------------------- 4 files changed, 21 insertions(+), 27 deletions(-)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 9a4ee0e25a1..8e27a841dd2 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2549,10 +2549,9 @@ BOOL clip_fullscreen_window( HWND hwnd, BOOL reset ) { struct user_thread_info *thread_info = get_user_thread_info(); MONITORINFO monitor_info = {.cbSize = sizeof(MONITORINFO)}; - RECT rect; - HMONITOR monitor; + RECT rect, virtual_rect; DWORD style; - UINT dpi; + UINT dpi, ctx; BOOL ret;
if (hwnd == NtUserGetDesktopWindow()) return FALSE; @@ -2571,11 +2570,13 @@ BOOL clip_fullscreen_window( HWND hwnd, BOOL reset ) if (NtGetTickCount() - thread_info->clipping_reset < 1000) return FALSE; if (!reset && clipping_cursor && thread_info->clipping_cursor) return FALSE; /* already clipping */
- if (!(monitor = NtUserMonitorFromWindow( hwnd, MONITOR_DEFAULTTONEAREST ))) return FALSE; - if (!get_monitor_info( monitor, &monitor_info, 0 )) return FALSE; + ctx = set_thread_dpi_awareness_context( NTUSER_DPI_PER_MONITOR_AWARE ); + monitor_info = monitor_info_from_window( hwnd, MONITOR_DEFAULTTONEAREST ); + virtual_rect = NtUserGetVirtualScreenRect(); + set_thread_dpi_awareness_context( ctx ); + if (!grab_fullscreen) { - RECT virtual_rect = NtUserGetVirtualScreenRect(); if (!EqualRect( &monitor_info.rcMonitor, &virtual_rect )) return FALSE; if (is_virtual_desktop()) return FALSE; } diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index c54659a0e2e..70e330e6017 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -3763,7 +3763,7 @@ BOOL WINAPI NtUserEnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC proc return ret; }
-BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info, UINT dpi ) +static BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info, UINT dpi ) { struct monitor *monitor;
@@ -3848,6 +3848,14 @@ HMONITOR monitor_from_window( HWND hwnd, UINT flags, UINT dpi ) return monitor_from_rect( &rect, flags, dpi ); }
+MONITORINFO monitor_info_from_window( HWND hwnd, UINT flags ) +{ + MONITORINFO info = {.cbSize = sizeof(info)}; + HMONITOR monitor = monitor_from_window( hwnd, flags, get_thread_dpi() ); + get_monitor_info( monitor, &info, get_thread_dpi() ); + return info; +} + /*********************************************************************** * NtUserGetSystemDpiForProcess (win32u.@) */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 2c0defe06ea..aa411d8addb 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -167,7 +167,6 @@ extern LONG get_char_dimensions( HDC hdc, TEXTMETRICW *metric, int *height ); extern HBITMAP get_display_bitmap(void); extern INT get_display_depth( UNICODE_STRING *name ); extern RECT get_display_rect( const WCHAR *display ); -extern BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info, UINT dpi ); extern UINT get_win_monitor_dpi( HWND hwnd ); extern RECT get_primary_monitor_rect( UINT dpi ); extern DWORD get_process_layout(void); @@ -191,6 +190,7 @@ extern POINT point_thread_to_win_dpi( HWND hwnd, POINT pt ); extern RECT rect_thread_to_win_dpi( HWND hwnd, RECT rect ); extern HMONITOR monitor_from_window( HWND hwnd, UINT flags, UINT dpi ); extern MONITORINFO monitor_info_from_rect( RECT rect, UINT dpi ); +extern MONITORINFO monitor_info_from_window( HWND hwnd, UINT flags ); extern UINT monitor_dpi_from_rect( RECT rect, UINT dpi ); extern BOOL update_display_cache( BOOL force ); extern void user_lock(void); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 9e20316f3e1..0e9963c670c 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2585,14 +2585,10 @@ HWND WINAPI NtUserRealChildWindowFromPoint( HWND parent, LONG x, LONG y ) */ static BOOL get_work_rect( HWND hwnd, RECT *rect ) { - HMONITOR monitor = monitor_from_window( hwnd, MONITOR_DEFAULTTOPRIMARY, get_thread_dpi() ); MONITORINFO mon_info; DWORD style;
- if (!monitor) return FALSE; - - mon_info.cbSize = sizeof(mon_info); - get_monitor_info( monitor, &mon_info, get_thread_dpi() ); + mon_info = monitor_info_from_window( hwnd, MONITOR_DEFAULTTOPRIMARY ); *rect = mon_info.rcMonitor;
style = get_window_long( hwnd, GWL_STYLE ); @@ -4259,11 +4255,7 @@ static POINT get_minimized_pos( HWND hwnd, POINT pt ) parent = NtUserGetAncestor( hwnd, GA_PARENT ); if (parent == get_desktop_window()) { - MONITORINFO mon_info; - HMONITOR monitor = monitor_from_window( hwnd, MONITOR_DEFAULTTOPRIMARY, get_thread_dpi() ); - - mon_info.cbSize = sizeof( mon_info ); - get_monitor_info( monitor, &mon_info, get_thread_dpi() ); + MONITORINFO mon_info = monitor_info_from_window( hwnd, MONITOR_DEFAULTTOPRIMARY ); parent_rect = mon_info.rcWork; } else get_client_rect( parent, &parent_rect, get_thread_dpi() ); @@ -4443,11 +4435,7 @@ static UINT arrange_iconic_windows( HWND parent )
if (parent == get_desktop_window()) { - MONITORINFO mon_info; - HMONITOR monitor = monitor_from_window( 0, MONITOR_DEFAULTTOPRIMARY, get_thread_dpi() ); - - mon_info.cbSize = sizeof( mon_info ); - get_monitor_info( monitor, &mon_info, get_thread_dpi() ); + MONITORINFO mon_info = monitor_info_from_window( 0, MONITOR_DEFAULTTOPRIMARY ); parent_rect = mon_info.rcWork; } else get_client_rect( parent, &parent_rect, get_thread_dpi() ); @@ -5294,15 +5282,12 @@ static void fix_cs_coordinates( CREATESTRUCTW *cs, INT *sw ) else /* overlapped window */ { RTL_USER_PROCESS_PARAMETERS *params = NtCurrentTeb()->Peb->ProcessParameters; - HMONITOR monitor; MONITORINFO mon_info;
if (!is_default_coord( cs->x ) && !is_default_coord( cs->cx ) && !is_default_coord( cs->cy )) return;
- monitor = monitor_from_window( cs->hwndParent, MONITOR_DEFAULTTOPRIMARY, get_thread_dpi() ); - mon_info.cbSize = sizeof(mon_info); - get_monitor_info( monitor, &mon_info, get_thread_dpi() ); + mon_info = monitor_info_from_window( cs->hwndParent, MONITOR_DEFAULTTOPRIMARY );
if (is_default_coord( cs->x )) {
GetCursorPos failures are probably related, I'll have a look.