Module: wine Branch: master Commit: 8de1b2c2ceda0a69257f4390540e2239ec592272 URL: https://source.winehq.org/git/wine.git/?a=commit;h=8de1b2c2ceda0a69257f43905...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Aug 24 12:12:44 2018 +0200
user32: Scale coordinates in MapWindowPoints() based on DPI awareness.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/user32/sysparams.c | 23 ++++++++++++++++++++ dlls/user32/win.h | 2 ++ dlls/user32/winpos.c | 12 ++++++++--- include/wine/server_protocol.h | 4 ++-- server/protocol.def | 1 + server/request.h | 1 + server/trace.c | 1 + server/window.c | 48 ++++++++++++++++++++++-------------------- 8 files changed, 64 insertions(+), 28 deletions(-)
diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c index 2dc5cb2..a971062 100644 --- a/dlls/user32/sysparams.c +++ b/dlls/user32/sysparams.c @@ -3222,6 +3222,29 @@ UINT get_thread_dpi(void) }
/********************************************************************** + * map_dpi_point + */ +POINT map_dpi_point( POINT pt, UINT dpi_from, UINT dpi_to ) +{ + if (dpi_from && dpi_to && dpi_from != dpi_to) + { + pt.x = MulDiv( pt.x, dpi_to, dpi_from ); + pt.y = MulDiv( pt.y, dpi_to, dpi_from ); + } + return pt; +} + +/********************************************************************** + * point_win_to_thread_dpi + */ +POINT point_win_to_thread_dpi( HWND hwnd, POINT pt ) +{ + UINT dpi = get_thread_dpi(); + if (!dpi) dpi = get_win_monitor_dpi( hwnd ); + return map_dpi_point( pt, GetDpiForWindow( hwnd ), dpi ); +} + +/********************************************************************** * map_dpi_rect */ RECT map_dpi_rect( RECT rect, UINT dpi_from, UINT dpi_to ) diff --git a/dlls/user32/win.h b/dlls/user32/win.h index 3fff0fc..b912ef8 100644 --- a/dlls/user32/win.h +++ b/dlls/user32/win.h @@ -131,6 +131,8 @@ extern void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) DECLSPEC_HIDDE extern UINT get_monitor_dpi( HMONITOR monitor ) DECLSPEC_HIDDEN; extern UINT get_win_monitor_dpi( HWND hwnd ) DECLSPEC_HIDDEN; extern UINT get_thread_dpi(void) DECLSPEC_HIDDEN; +extern POINT map_dpi_point( POINT pt, UINT dpi_from, UINT dpi_to ) DECLSPEC_HIDDEN; +extern POINT point_win_to_thread_dpi( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN; extern RECT map_dpi_rect( RECT rect, UINT dpi_from, UINT dpi_to ) DECLSPEC_HIDDEN; extern RECT rect_win_to_thread_dpi( HWND hwnd, RECT rect ) DECLSPEC_HIDDEN; extern BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index e26dc6e..1dd9c12 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -446,6 +446,7 @@ static BOOL WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, BOOL *mirrored, POI } } if (wndPtr && wndPtr != WND_DESKTOP) WIN_ReleasePtr( wndPtr ); + offset = point_win_to_thread_dpi( hwndFrom, offset ); } }
@@ -460,15 +461,16 @@ static BOOL WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, BOOL *mirrored, POI if (wndPtr == WND_OTHER_PROCESS) goto other_process; if (wndPtr != WND_DESKTOP) { + POINT pt = { 0, 0 }; if (wndPtr->dwExStyle & WS_EX_LAYOUTRTL) { mirror_to = TRUE; - offset.x -= wndPtr->client_rect.right - wndPtr->client_rect.left; + pt.x += wndPtr->client_rect.right - wndPtr->client_rect.left; } while (wndPtr->parent) { - offset.x -= wndPtr->client_rect.left; - offset.y -= wndPtr->client_rect.top; + pt.x += wndPtr->client_rect.left; + pt.y += wndPtr->client_rect.top; hwnd = wndPtr->parent; WIN_ReleasePtr( wndPtr ); if (!(wndPtr = WIN_GetPtr( hwnd ))) break; @@ -481,6 +483,9 @@ static BOOL WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, BOOL *mirrored, POI } } if (wndPtr && wndPtr != WND_DESKTOP) WIN_ReleasePtr( wndPtr ); + pt = point_win_to_thread_dpi( hwndTo, pt ); + offset.x -= pt.x; + offset.y -= pt.y; } }
@@ -494,6 +499,7 @@ static BOOL WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, BOOL *mirrored, POI { req->from = wine_server_user_handle( hwndFrom ); req->to = wine_server_user_handle( hwndTo ); + req->dpi = get_thread_dpi(); if ((ret = !wine_server_call_err( req ))) { ret_offset->x = reply->x; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 9c5deca..a888a63 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -3743,7 +3743,7 @@ struct get_windows_offset_request struct request_header __header; user_handle_t from; user_handle_t to; - char __pad_20[4]; + int dpi; }; struct get_windows_offset_reply { @@ -6533,6 +6533,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; };
-#define SERVER_PROTOCOL_VERSION 557 +#define SERVER_PROTOCOL_VERSION 558
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index 43f5f01..f1f4709 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2685,6 +2685,7 @@ enum coords_relative @REQ(get_windows_offset) user_handle_t from; /* handle to the first window */ user_handle_t to; /* handle to the second window */ + int dpi; /* DPI to map to, or zero for per-monitor DPI */ @REPLY int x; /* x coordinate offset */ int y; /* y coordinate offset */ diff --git a/server/request.h b/server/request.h index c3aed96..ddf8a68 100644 --- a/server/request.h +++ b/server/request.h @@ -1786,6 +1786,7 @@ C_ASSERT( FIELD_OFFSET(struct set_window_text_request, handle) == 12 ); C_ASSERT( sizeof(struct set_window_text_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_windows_offset_request, from) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_windows_offset_request, to) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_windows_offset_request, dpi) == 20 ); C_ASSERT( sizeof(struct get_windows_offset_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct get_windows_offset_reply, x) == 8 ); C_ASSERT( FIELD_OFFSET(struct get_windows_offset_reply, y) == 12 ); diff --git a/server/trace.c b/server/trace.c index 1d773fb..6886688 100644 --- a/server/trace.c +++ b/server/trace.c @@ -3259,6 +3259,7 @@ static void dump_get_windows_offset_request( const struct get_windows_offset_req { fprintf( stderr, " from=%08x", req->from ); fprintf( stderr, ", to=%08x", req->to ); + fprintf( stderr, ", dpi=%d", req->dpi ); }
static void dump_get_windows_offset_reply( const struct get_windows_offset_reply *req ) diff --git a/server/window.c b/server/window.c index c286a0a..e45cf38 100644 --- a/server/window.c +++ b/server/window.c @@ -630,6 +630,16 @@ static inline void inc_window_paint_count( struct window *win, int incr ) if (win->thread) inc_queue_paint_count( win->thread, incr ); }
+/* map a point between different DPI scaling levels */ +static void map_dpi_point( struct window *win, int *x, int *y, unsigned int from, unsigned int to ) +{ + if (!from) from = get_monitor_dpi( win ); + if (!to) to = get_monitor_dpi( win ); + if (from == to) return; + *x = scale_dpi( *x, from, to ); + *y = scale_dpi( *y, from, to ); +} + /* map a window rectangle between different DPI scaling levels */ static void map_dpi_rect( struct window *win, rectangle_t *rect, unsigned int from, unsigned int to ) { @@ -2401,38 +2411,30 @@ DECL_HANDLER(set_window_text) DECL_HANDLER(get_windows_offset) { struct window *win; - int mirror_from = 0, mirror_to = 0; + int x, y, mirror_from = 0, mirror_to = 0;
reply->x = reply->y = 0; if (req->from) { if (!(win = get_window( req->from ))) return; - if (win->ex_style & WS_EX_LAYOUTRTL) - { - mirror_from = 1; - reply->x += win->client_rect.right - win->client_rect.left; - } - while (win && !is_desktop_window(win)) - { - reply->x += win->client_rect.left; - reply->y += win->client_rect.top; - win = win->parent; - } + if (win->ex_style & WS_EX_LAYOUTRTL) mirror_from = 1; + x = mirror_from ? win->client_rect.right - win->client_rect.left : 0; + y = 0; + client_to_screen( win, &x, &y ); + map_dpi_point( win, &x, &y, win->dpi, req->dpi ); + reply->x += x; + reply->y += y; } if (req->to) { if (!(win = get_window( req->to ))) return; - if (win->ex_style & WS_EX_LAYOUTRTL) - { - mirror_to = 1; - reply->x -= win->client_rect.right - win->client_rect.left; - } - while (win && !is_desktop_window(win)) - { - reply->x -= win->client_rect.left; - reply->y -= win->client_rect.top; - win = win->parent; - } + if (win->ex_style & WS_EX_LAYOUTRTL) mirror_to = 1; + x = mirror_to ? win->client_rect.right - win->client_rect.left : 0; + y = 0; + client_to_screen( win, &x, &y ); + map_dpi_point( win, &x, &y, win->dpi, req->dpi ); + reply->x -= x; + reply->y -= y; } if (mirror_from) reply->x = -reply->x; reply->mirror = mirror_from ^ mirror_to;