Alexandre Julliard : user32: Scale coordinates in WIN_GetRectangles() based on DPI awareness.

Alexandre Julliard julliard at winehq.org
Fri Aug 24 13:59:15 CDT 2018


Module: wine
Branch: master
Commit: c5a692567698b07d9237071cea2bffe6a19ac65d
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c5a692567698b07d9237071cea2bffe6a19ac65d

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Aug 24 12:06:45 2018 +0200

user32: Scale coordinates in WIN_GetRectangles() based on DPI awareness.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/sysparams.c        | 10 ++++++++++
 dlls/user32/win.c              |  6 ++++--
 dlls/user32/win.h              |  1 +
 include/wine/server_protocol.h |  4 ++--
 server/protocol.def            |  1 +
 server/request.h               |  1 +
 server/trace.c                 |  1 +
 server/user.h                  | 14 ++++++++++++++
 server/window.c                | 11 +++++++++++
 9 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c
index b6679c5..2dc5cb2 100644
--- a/dlls/user32/sysparams.c
+++ b/dlls/user32/sysparams.c
@@ -3237,6 +3237,16 @@ RECT map_dpi_rect( RECT rect, UINT dpi_from, UINT dpi_to )
 }
 
 /**********************************************************************
+ *              rect_win_to_thread_dpi
+ */
+RECT rect_win_to_thread_dpi( HWND hwnd, RECT rect )
+{
+    UINT dpi = get_thread_dpi();
+    if (!dpi) dpi = get_win_monitor_dpi( hwnd );
+    return map_dpi_rect( rect, GetDpiForWindow( hwnd ), dpi );
+}
+
+/**********************************************************************
  *              SetProcessDpiAwarenessContext   (USER32.@)
  */
 BOOL WINAPI SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT context )
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index c7a3b06..d9ef151 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -844,6 +844,7 @@ BOOL WIN_GetRectangles( HWND hwnd, enum coords_relative relative, RECT *rectWind
         {
             rect.right  = 100;
             rect.bottom = 100;
+            rect = rect_win_to_thread_dpi( hwnd, rect );
         }
         else
         {
@@ -921,8 +922,8 @@ BOOL WIN_GetRectangles( HWND hwnd, enum coords_relative relative, RECT *rectWind
             }
             break;
         }
-        if (rectWindow) *rectWindow = window_rect;
-        if (rectClient) *rectClient = client_rect;
+        if (rectWindow) *rectWindow = rect_win_to_thread_dpi( hwnd, window_rect );
+        if (rectClient) *rectClient = rect_win_to_thread_dpi( hwnd, client_rect );
         WIN_ReleasePtr( win );
         return TRUE;
     }
@@ -932,6 +933,7 @@ other_process:
     {
         req->handle = wine_server_user_handle( hwnd );
         req->relative = relative;
+        req->dpi = get_thread_dpi();
         if ((ret = !wine_server_call_err( req )))
         {
             if (rectWindow)
diff --git a/dlls/user32/win.h b/dlls/user32/win.h
index 226e3e9..3fff0fc 100644
--- a/dlls/user32/win.h
+++ b/dlls/user32/win.h
@@ -132,6 +132,7 @@ 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 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,
                             const RECT *window_rect, const RECT *client_rect,
                             const RECT *valid_rects ) DECLSPEC_HIDDEN;
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index c636bac..9c5deca 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -3692,7 +3692,7 @@ struct get_window_rectangles_request
     struct request_header __header;
     user_handle_t  handle;
     int            relative;
-    char __pad_20[4];
+    int            dpi;
 };
 struct get_window_rectangles_reply
 {
@@ -6533,6 +6533,6 @@ union generic_reply
     struct terminate_job_reply terminate_job_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 556
+#define SERVER_PROTOCOL_VERSION 557
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index c8bb3b1..43f5f01 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2651,6 +2651,7 @@ enum message_type
 @REQ(get_window_rectangles)
     user_handle_t  handle;        /* handle to the window */
     int            relative;      /* coords relative to (see below) */
+    int            dpi;           /* DPI to map to, or zero for per-monitor DPI */
 @REPLY
     rectangle_t    window;        /* window rectangle */
     rectangle_t    client;        /* client rectangle */
diff --git a/server/request.h b/server/request.h
index d3028f0..c3aed96 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1773,6 +1773,7 @@ C_ASSERT( FIELD_OFFSET(struct set_window_pos_reply, needs_update) == 20 );
 C_ASSERT( sizeof(struct set_window_pos_reply) == 24 );
 C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_request, handle) == 12 );
 C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_request, relative) == 16 );
+C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_request, dpi) == 20 );
 C_ASSERT( sizeof(struct get_window_rectangles_request) == 24 );
 C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_reply, window) == 8 );
 C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_reply, client) == 24 );
diff --git a/server/trace.c b/server/trace.c
index 68e47d4..1d773fb 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3229,6 +3229,7 @@ static void dump_get_window_rectangles_request( const struct get_window_rectangl
 {
     fprintf( stderr, " handle=%08x", req->handle );
     fprintf( stderr, ", relative=%d", req->relative );
+    fprintf( stderr, ", dpi=%d", req->dpi );
 }
 
 static void dump_get_window_rectangles_reply( const struct get_window_rectangles_reply *req )
diff --git a/server/user.h b/server/user.h
index 1236b0e..fe3aa09 100644
--- a/server/user.h
+++ b/server/user.h
@@ -198,6 +198,20 @@ static inline int point_in_rect( const rectangle_t *rect, int x, int y )
     return (x >= rect->left && x < rect->right && y >= rect->top && y < rect->bottom);
 }
 
+static inline int scale_dpi( int val, unsigned int dpi_from, unsigned int dpi_to )
+{
+    if (val >= 0) return (val * dpi_to + (dpi_from / 2)) / dpi_from;
+    return (val * dpi_to - (dpi_from / 2)) / dpi_from;
+}
+
+static inline void scale_dpi_rect( rectangle_t *rect, unsigned int dpi_from, unsigned int dpi_to )
+{
+    rect->left   = scale_dpi( rect->left, dpi_from, dpi_to );
+    rect->top    = scale_dpi( rect->top, dpi_from, dpi_to );
+    rect->right  = scale_dpi( rect->right, dpi_from, dpi_to );
+    rect->bottom = scale_dpi( rect->bottom, dpi_from, dpi_to );
+}
+
 /* offset the coordinates of a rectangle */
 static inline void offset_rect( rectangle_t *rect, int offset_x, int offset_y )
 {
diff --git a/server/window.c b/server/window.c
index e58d7e4..c286a0a 100644
--- a/server/window.c
+++ b/server/window.c
@@ -630,6 +630,15 @@ static inline void inc_window_paint_count( struct window *win, int incr )
     if (win->thread) inc_queue_paint_count( win->thread, incr );
 }
 
+/* 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 )
+{
+    if (!from) from = get_monitor_dpi( win );
+    if (!to) to = get_monitor_dpi( win );
+    if (from == to) return;
+    scale_dpi_rect( rect, from, to );
+}
+
 /* check if window and all its ancestors are visible */
 static int is_visible( const struct window *win )
 {
@@ -2349,6 +2358,8 @@ DECL_HANDLER(get_window_rectangles)
         set_error( STATUS_INVALID_PARAMETER );
         break;
     }
+    map_dpi_rect( win, &reply->window, win->dpi, req->dpi );
+    map_dpi_rect( win, &reply->client, win->dpi, req->dpi );
 }
 
 




More information about the wine-cvs mailing list