From 2068b73db5e19e1ce3b54b2a8ecb5a5b99ea19b5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 27 Aug 2018 14:02:43 +0200 Subject: [PATCH] user32: Process hardware messages in physical coordinates. Signed-off-by: Alexandre Julliard --- dlls/user32/message.c | 33 ++++++++++++++++++++++----------- dlls/user32/sysparams.c | 38 ++++++++++++++++++++++++++------------ dlls/user32/win.h | 2 ++ 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 79ea577ba8d..1554fbf666f 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -2388,6 +2388,7 @@ static BOOL process_rawinput_message( MSG *msg, const struct hardware_msg_data * } msg->lParam = (LPARAM)rawinput; + msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt ); return TRUE; } @@ -2463,6 +2464,7 @@ static BOOL process_keyboard_message( MSG *msg, UINT hw_id, HWND hwnd_filter, return FALSE; } accept_hardware_message( hw_id, remove ); + msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt ); if ( remove && msg->message == WM_KEYDOWN ) if (ImmProcessKey(msg->hwnd, GetKeyboardLayout(0), msg->wParam, msg->lParam, 0) ) @@ -2520,6 +2522,9 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H return FALSE; } + msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt ); + SetThreadDpiAwarenessContext( GetWindowDpiAwarenessContext( msg->hwnd )); + /* FIXME: is this really the right place for this hook? */ event.message = msg->message; event.time = msg->time; @@ -2693,17 +2698,22 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H static BOOL process_hardware_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data, HWND hwnd_filter, UINT first, UINT last, BOOL remove ) { + DPI_AWARENESS_CONTEXT context; + BOOL ret = FALSE; + + /* hardware messages are always in physical coords */ + context = SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ); + if (msg->message == WM_INPUT) - return process_rawinput_message( msg, msg_data ); - - if (is_keyboard_message( msg->message )) - return process_keyboard_message( msg, hw_id, hwnd_filter, first, last, remove ); - - if (is_mouse_message( msg->message )) - return process_mouse_message( msg, hw_id, msg_data->info, hwnd_filter, first, last, remove ); - - ERR( "unknown message type %x\n", msg->message ); - return FALSE; + ret = process_rawinput_message( msg, msg_data ); + else if (is_keyboard_message( msg->message )) + ret = process_keyboard_message( msg, hw_id, hwnd_filter, first, last, remove ); + else if (is_mouse_message( msg->message )) + ret = process_mouse_message( msg, hw_id, msg_data->info, hwnd_filter, first, last, remove ); + else + ERR( "unknown message type %x\n", msg->message ); + SetThreadDpiAwarenessContext( context ); + return ret; } @@ -2938,7 +2948,8 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags continue; /* ignore it */ } *msg = info.msg; - thread_info->GetMessagePosVal = MAKELONG( info.msg.pt.x, info.msg.pt.y ); + msg->pt = point_phys_to_win_dpi( info.msg.hwnd, info.msg.pt ); + thread_info->GetMessagePosVal = MAKELONG( msg->pt.x, msg->pt.y ); thread_info->GetMessageTimeVal = info.msg.time; thread_info->GetMessageExtraInfoVal = 0; HeapFree( GetProcessHeap(), 0, buffer ); diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c index 9d7c256a308..028a0a916dd 100644 --- a/dlls/user32/sysparams.c +++ b/dlls/user32/sysparams.c @@ -3234,6 +3234,22 @@ POINT map_dpi_point( POINT pt, UINT dpi_from, UINT dpi_to ) return pt; } +/********************************************************************** + * point_win_to_phys_dpi + */ +POINT point_win_to_phys_dpi( HWND hwnd, POINT pt ) +{ + return map_dpi_point( pt, GetDpiForWindow( hwnd ), get_win_monitor_dpi( hwnd ) ); +} + +/********************************************************************** + * point_phys_to_win_dpi + */ +POINT point_phys_to_win_dpi( HWND hwnd, POINT pt ) +{ + return map_dpi_point( pt, get_win_monitor_dpi( hwnd ), GetDpiForWindow( hwnd )); +} + /********************************************************************** * point_win_to_thread_dpi */ @@ -3475,13 +3491,11 @@ DPI_AWARENESS_CONTEXT WINAPI SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT */ BOOL WINAPI LogicalToPhysicalPointForPerMonitorDPI( HWND hwnd, POINT *pt ) { - UINT dpi = GetDpiForWindow( hwnd ); RECT rect; - GetWindowRect( hwnd, &rect ); + if (!GetWindowRect( hwnd, &rect )) return FALSE; if (pt->x < rect.left || pt->y < rect.top || pt->x > rect.right || pt->y > rect.bottom) return FALSE; - pt->x = MulDiv( pt->x, system_dpi, dpi ); - pt->y = MulDiv( pt->y, system_dpi, dpi ); + *pt = point_win_to_phys_dpi( hwnd, *pt ); return TRUE; } @@ -3491,18 +3505,18 @@ BOOL WINAPI LogicalToPhysicalPointForPerMonitorDPI( HWND hwnd, POINT *pt ) BOOL WINAPI PhysicalToLogicalPointForPerMonitorDPI( HWND hwnd, POINT *pt ) { DPI_AWARENESS_CONTEXT context; - UINT dpi = GetDpiForWindow( hwnd ); RECT rect; + BOOL ret = FALSE; - /* get window rect in physical coords */ context = SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ); - GetWindowRect( hwnd, &rect ); + if (GetWindowRect( hwnd, &rect ) && + pt->x >= rect.left && pt->y >= rect.top && pt->x <= rect.right && pt->y <= rect.bottom) + { + *pt = point_phys_to_win_dpi( hwnd, *pt ); + ret = TRUE; + } SetThreadDpiAwarenessContext( context ); - - if (pt->x < rect.left || pt->y < rect.top || pt->x > rect.right || pt->y > rect.bottom) return FALSE; - pt->x = MulDiv( pt->x, dpi, system_dpi ); - pt->y = MulDiv( pt->y, dpi, system_dpi ); - return TRUE; + return ret; } struct monitor_enum_info diff --git a/dlls/user32/win.h b/dlls/user32/win.h index f30b00430bd..f3bdfd38d98 100644 --- a/dlls/user32/win.h +++ b/dlls/user32/win.h @@ -132,6 +132,8 @@ 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_phys_dpi( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN; +extern POINT point_phys_to_win_dpi( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN; extern POINT point_win_to_thread_dpi( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN; extern POINT point_thread_to_win_dpi( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN; extern RECT map_dpi_rect( RECT rect, UINT dpi_from, UINT dpi_to ) DECLSPEC_HIDDEN;