user32: Scale coordinates in MapWindowPoints() based on DPI awareness.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c5a6925676
commit
8de1b2c2ce
|
@ -3221,6 +3221,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
|
||||
*/
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue