From: Rémi Bernon <rbernon@codeweavers.com> Based on patches from Paul Gofman. --- dlls/win32u/sysparams.c | 2 +- dlls/win32u/window.c | 8 +++---- server/protocol.def | 12 +++++----- server/region.c | 2 +- server/trace.c | 8 ++++++- server/user.h | 10 ++++----- server/window.c | 49 +++++++++++++++++++++++------------------ tools/make_requests | 1 + 8 files changed, 52 insertions(+), 40 deletions(-) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index e1b04b0317e..fc067c0ab07 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2442,7 +2442,7 @@ static void set_winstation_monitors( BOOL increment ) if (is_monitor_primary( monitor )) info->flags |= MONITOR_FLAG_PRIMARY; if (!is_monitor_active( monitor )) info->flags |= MONITOR_FLAG_INACTIVE; if (monitor->is_clone) info->flags |= MONITOR_FLAG_CLONE; - info->dpi = monitor_get_dpi( monitor, MDT_EFFECTIVE_DPI, &x, &y ).num; + info->dpi = monitor_get_dpi( monitor, MDT_EFFECTIVE_DPI, &x, &y ); info->virt = wine_server_rectangle( monitor_get_rect( monitor, no_dpi, MDT_EFFECTIVE_DPI ) ); info->raw = wine_server_rectangle( monitor_get_rect( monitor, no_dpi, MDT_RAW_DPI ) ); info++; diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 947d16322b3..2d3ca556eb2 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1895,7 +1895,7 @@ other_process: { req->handle = wine_server_user_handle( hwnd ); req->relative = relative; - req->dpi = dpi.num; + req->dpi = dpi; if ((ret = !wine_server_call_err( req ))) { rects->window = wine_server_get_rect( reply->window ); @@ -2248,7 +2248,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru req->handle = wine_server_user_handle( hwnd ); req->previous = wine_server_user_handle( insert_after ); req->swp_flags = swp_flags; - req->monitor_dpi = monitor_dpi.num; + req->monitor_dpi = monitor_dpi; req->window = wine_server_rectangle( new_rects->window ); req->client = wine_server_rectangle( new_rects->client ); if (!EqualRect( &new_rects->window, &new_rects->visible ) || new_surface || valid_rects) @@ -2717,7 +2717,7 @@ static HWND *list_children_from_point( HWND hwnd, POINT pt, struct ratio dpi ) req->parent = wine_server_user_handle( hwnd ); req->x = pt.x; req->y = pt.y; - req->dpi = dpi.num; + req->dpi = dpi; wine_server_set_reply( req, list, (size-1) * sizeof(user_handle_t) ); if (!wine_server_call( req )) count = reply->count; } @@ -3373,7 +3373,7 @@ other_process: /* one of the parents may belong to another process, do it the h { req->from = wine_server_user_handle( hwnd_from ); req->to = wine_server_user_handle( hwnd_to ); - req->dpi = dpi.num; + req->dpi = dpi; if ((ret = !wine_server_call_err( req ))) { ret_offset->x = reply->x; diff --git a/server/protocol.def b/server/protocol.def index 02f19e711cc..2ba02303761 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -912,8 +912,8 @@ struct monitor_info { struct rectangle raw; /* host / physical position of the monitor rect */ struct rectangle virt; /* client / virtual position of the monitor rect */ - unsigned int flags; /* MONITOR_FLAG_* flags for the monitor */ - unsigned int dpi; /* physical DPI for the monitor */ + unsigned int flags; /* MONITOR_FLAG_* flags for the monitor */ + struct ratio dpi; /* physical DPI for the monitor */ }; #define MONITOR_FLAG_PRIMARY 0x01 #define MONITOR_FLAG_CLONE 0x02 @@ -2771,7 +2771,7 @@ enum message_type user_handle_t parent; /* parent window */ int x; /* point in parent coordinates */ int y; - int dpi; /* dpi for the point coordinates */ + struct ratio dpi; /* dpi for the point coordinates */ @REPLY int count; /* total count of children */ VARARG(children,user_handles); /* children handles */ @@ -2796,7 +2796,7 @@ enum message_type @REQ(set_window_pos) unsigned short swp_flags; /* SWP_* flags */ unsigned short paint_flags; /* paint flags (see below) */ - unsigned int monitor_dpi; /* DPI of the window's monitor */ + struct ratio monitor_dpi; /* DPI of the window's monitor */ user_handle_t handle; /* handle to the window */ user_handle_t previous; /* previous window in Z order */ struct rectangle window; /* window rectangle (in parent coords) */ @@ -2815,7 +2815,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 */ + struct ratio dpi; /* DPI to map to, or zero for per-monitor DPI */ @REPLY struct rectangle window; /* window rectangle */ struct rectangle client; /* client rectangle */ @@ -2849,7 +2849,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 */ + struct ratio 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/region.c b/server/region.c index 9b0b1c66402..d77038c161f 100644 --- a/server/region.c +++ b/server/region.c @@ -741,7 +741,7 @@ void mirror_region( const struct rectangle *client_rect, struct region *region ) /* scale a region for a given dpi factor */ -void scale_region( struct region *region, unsigned int dpi_from, unsigned int dpi_to ) +void scale_region( struct region *region, struct ratio dpi_from, struct ratio dpi_to ) { struct rectangle *rect, *end; diff --git a/server/trace.c b/server/trace.c index b02e08fce03..371466293c3 100644 --- a/server/trace.c +++ b/server/trace.c @@ -173,6 +173,11 @@ static void dump_rectangle( const char *prefix, const struct rectangle *rect ) rect->left, rect->top, rect->right, rect->bottom ); } +static void dump_ratio( const char *prefix, const struct ratio *q ) +{ + fprintf( stderr, "%s{%d:%d}", prefix, q->num, q->den ); +} + static void dump_ioctl_code( const char *prefix, const ioctl_code_t *code ) { switch(*code) @@ -1646,7 +1651,8 @@ static void dump_varargs_monitor_infos( const char *prefix, data_size_t size ) { dump_rectangle( "{raw:", &monitor->virt ); dump_rectangle( ",virt:", &monitor->virt ); - fprintf( stderr, ",flags:%#x,dpi:%u", monitor->flags, monitor->dpi ); + fprintf( stderr, ",flags:%#x", monitor->flags ); + dump_ratio( ",dpi:", &monitor->dpi ); fputc( '}', stderr ); if (--len) fputc( ',', stderr ); } diff --git a/server/user.h b/server/user.h index 1997029b0e9..77d8c3591ad 100644 --- a/server/user.h +++ b/server/user.h @@ -152,7 +152,7 @@ extern int is_region_equal( const struct region *region1, const struct region *r extern void get_region_extents( const struct region *region, struct rectangle *rect ); extern void offset_region( struct region *region, int x, int y ); extern void mirror_region( const struct rectangle *client_rect, struct region *region ); -extern void scale_region( struct region *region, unsigned int dpi_from, unsigned int dpi_to ); +extern void scale_region( struct region *region, struct ratio dpi_from, struct ratio dpi_to ); extern struct region *copy_region( struct region *dst, const struct region *src ); extern struct region *intersect_region( struct region *dst, const struct region *src1, const struct region *src2 ); @@ -232,13 +232,13 @@ static inline int point_in_rect( const struct rectangle *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 ) +static inline int scale_dpi( int val, struct ratio dpi_from, struct ratio dpi_to ) { - if (val >= 0) return (val * dpi_to + (dpi_from / 2)) / dpi_from; - return (val * dpi_to - (dpi_from / 2)) / dpi_from; + if (val >= 0) return (val * dpi_to.num + (dpi_from.num / 2)) / dpi_from.num; + return (val * dpi_to.num - (dpi_from.num / 2)) / dpi_from.num; } -static inline void scale_dpi_rect( struct rectangle *rect, unsigned int dpi_from, unsigned int dpi_to ) +static inline void scale_dpi_rect( struct rectangle *rect, struct ratio dpi_from, struct ratio dpi_to ) { rect->left = scale_dpi( rect->left, dpi_from, dpi_to ); rect->top = scale_dpi( rect->top, dpi_from, dpi_to ); diff --git a/server/window.c b/server/window.c index e6d5a6d377b..37ea9a9dc35 100644 --- a/server/window.c +++ b/server/window.c @@ -36,6 +36,8 @@ #include "user.h" #include "unicode.h" +static const struct ratio no_dpi; + /* a window property */ struct property { @@ -81,7 +83,7 @@ struct window unsigned int color_key; /* color key for a layered window */ unsigned int alpha; /* alpha value for a layered window */ unsigned int layered_flags; /* flags for a layered window */ - unsigned int monitor_dpi; /* DPI of the window monitor */ + struct ratio monitor_dpi; /* DPI of the window monitor */ WCHAR *text; /* window caption text */ data_size_t text_len; /* length of window caption */ unsigned int paint_flags; /* various painting flags */ @@ -319,16 +321,18 @@ static void map_point_raw_to_virt( struct desktop *desktop, int *x, int *y ) } /* get the per-monitor DPI for a window */ -static unsigned int get_monitor_dpi( struct window *win ) +static struct ratio get_monitor_dpi( struct window *win ) { while (win->parent && !is_desktop_window( win->parent )) win = win->parent; return win->monitor_dpi; } -static unsigned int get_window_dpi( struct window *win ) +static struct ratio get_window_dpi( struct window *win ) { + struct ratio dpi = {1, 1}; if (NTUSER_DPI_CONTEXT_IS_MONITOR_AWARE( win->shared->dpi_context )) return get_monitor_dpi( win ); - return NTUSER_DPI_CONTEXT_GET_DPI( win->shared->dpi_context ); + dpi.num = NTUSER_DPI_CONTEXT_GET_DPI( win->shared->dpi_context ); + return dpi; } /* link a window at the right place in the siblings list */ @@ -658,7 +662,8 @@ static struct window *create_window( struct window *parent, struct window *owner win->is_layered = 0; win->is_orphan = 0; win->set_foreground = 0; - win->monitor_dpi = USER_DEFAULT_SCREEN_DPI; + win->monitor_dpi.num = USER_DEFAULT_SCREEN_DPI; + win->monitor_dpi.den = 1; win->text = NULL; win->text_len = 0; win->paint_flags = 0; @@ -815,30 +820,30 @@ static inline void inc_window_paint_count( struct window *win, int 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 ) +static void map_dpi_point( struct window *win, int *x, int *y, struct ratio from, struct ratio to ) { - if (!from) from = get_monitor_dpi( win ); - if (!to) to = get_monitor_dpi( win ); - if (from == to) return; + if (!from.num) from = get_monitor_dpi( win ); + if (!to.num) to = get_monitor_dpi( win ); + if (from.num == to.num) 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, struct rectangle *rect, unsigned int from, unsigned int to ) +static void map_dpi_rect( struct window *win, struct rectangle *rect, struct ratio from, struct ratio to ) { - if (!from) from = get_monitor_dpi( win ); - if (!to) to = get_monitor_dpi( win ); - if (from == to) return; + if (!from.num) from = get_monitor_dpi( win ); + if (!to.num) to = get_monitor_dpi( win ); + if (from.num == to.num) return; scale_dpi_rect( rect, from, to ); } /* map a region between different DPI scaling levels */ -static void map_dpi_region( struct window *win, struct region *region, unsigned int from, unsigned int to ) +static void map_dpi_region( struct window *win, struct region *region, struct ratio from, struct ratio to ) { - if (!from) from = get_monitor_dpi( win ); - if (!to) to = get_monitor_dpi( win ); - if (from == to) return; + if (!from.num) from = get_monitor_dpi( win ); + if (!to.num) to = get_monitor_dpi( win ); + if (from.num == to.num) return; scale_region( region, from, to ); } @@ -853,7 +858,7 @@ static inline void client_to_screen( struct window *win, int *x, int *y ) } /* convert coordinates from screen to client coords and dpi */ -static void screen_to_client( struct window *win, int *x, int *y, unsigned int dpi ) +static void screen_to_client( struct window *win, int *x, int *y, struct ratio dpi ) { int offset_x = 0, offset_y = 0; @@ -909,7 +914,7 @@ static int is_parent_composited( struct window *win ) } /* check if point is inside the window, and map to window dpi */ -static int is_point_in_window( struct window *win, int *x, int *y, unsigned int dpi ) +static int is_point_in_window( struct window *win, int *x, int *y, struct ratio dpi ) { if (!(win->style & WS_VISIBLE)) return 0; /* not visible */ if ((win->style & (WS_POPUP|WS_CHILD|WS_DISABLED)) == (WS_CHILD|WS_DISABLED)) @@ -1038,7 +1043,7 @@ user_handle_t shallow_window_from_point( struct desktop *desktop, int x, int y ) { int x_child = x, y_child = y; - if (!is_point_in_window( ptr, &x_child, &y_child, 0 )) continue; /* skip it */ + if (!is_point_in_window( ptr, &x_child, &y_child, no_dpi )) continue; /* skip it */ return ptr->handle; } return desktop->top_window->handle; @@ -1053,14 +1058,14 @@ struct thread *window_thread_from_point( user_handle_t scope, int x, int y ) map_point_raw_to_virt( win->desktop, &x, &y ); - screen_to_client( win, &x, &y, 0 ); + screen_to_client( win, &x, &y, no_dpi ); win = child_window_from_point( win, x, y ); if (!win->thread) return NULL; return (struct thread *)grab_object( win->thread ); } /* return list of all windows containing point (in absolute coords) */ -static int all_windows_from_point( struct window *top, int x, int y, unsigned int dpi, +static int all_windows_from_point( struct window *top, int x, int y, struct ratio dpi, struct user_handle_array *array ) { if (!is_desktop_window( top ) && !is_desktop_window( top->parent )) diff --git a/tools/make_requests b/tools/make_requests index 7e317647a51..4b8139596a3 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -69,6 +69,7 @@ my %formats = "union udp_endpoint" => [ 32, 4 ], "struct user_apc" => [ 40, 8 ], "struct class_info" => [ 56, 8 ], + "struct ratio" => [ 4, 4 ], ); my $file_header = -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11301