Module: wine Branch: master Commit: db8fcc1c9dd32af92d68ae36653608a333adf7bd URL: https://source.winehq.org/git/wine.git/?a=commit;h=db8fcc1c9dd32af92d68ae366...
Author: Jacek Caban jacek@codeweavers.com Date: Mon Feb 14 14:07:14 2022 +0100
win32u: Move monitor_from_rect implementation from user32.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/user32/sysparams.c | 79 +------------------------------------------------ dlls/win32u/sysparams.c | 68 ++++++++++++++++++++++++++++++++++++++++++ include/ntuser.h | 1 + 3 files changed, 70 insertions(+), 78 deletions(-)
diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c index 9d553d7dfff..1b26098a413 100644 --- a/dlls/user32/sysparams.c +++ b/dlls/user32/sysparams.c @@ -989,89 +989,12 @@ BOOL WINAPI PhysicalToLogicalPointForPerMonitorDPI( HWND hwnd, POINT *pt ) return ret; }
-struct monitor_enum_info -{ - RECT rect; - UINT max_area; - UINT min_distance; - HMONITOR primary; - HMONITOR nearest; - HMONITOR ret; -}; - -/* helper callback for MonitorFromRect */ -static BOOL CALLBACK monitor_enum( HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM lp ) -{ - struct monitor_enum_info *info = (struct monitor_enum_info *)lp; - RECT intersect; - - if (IntersectRect( &intersect, rect, &info->rect )) - { - /* check for larger intersecting area */ - UINT area = (intersect.right - intersect.left) * (intersect.bottom - intersect.top); - if (area > info->max_area) - { - info->max_area = area; - info->ret = monitor; - } - } - else if (!info->max_area) /* if not intersecting, check for min distance */ - { - UINT distance; - UINT x, y; - - if (info->rect.right <= rect->left) x = rect->left - info->rect.right; - else if (rect->right <= info->rect.left) x = info->rect.left - rect->right; - else x = 0; - if (info->rect.bottom <= rect->top) y = rect->top - info->rect.bottom; - else if (rect->bottom <= info->rect.top) y = info->rect.top - rect->bottom; - else y = 0; - distance = x * x + y * y; - if (distance < info->min_distance) - { - info->min_distance = distance; - info->nearest = monitor; - } - } - if (!info->primary) - { - MONITORINFO mon_info; - mon_info.cbSize = sizeof(mon_info); - GetMonitorInfoW( monitor, &mon_info ); - if (mon_info.dwFlags & MONITORINFOF_PRIMARY) info->primary = monitor; - } - return TRUE; -} - /*********************************************************************** * MonitorFromRect (USER32.@) */ HMONITOR WINAPI MonitorFromRect( const RECT *rect, DWORD flags ) { - struct monitor_enum_info info; - - info.rect = *rect; - info.max_area = 0; - info.min_distance = ~0u; - info.primary = 0; - info.nearest = 0; - info.ret = 0; - - if (IsRectEmpty(&info.rect)) - { - info.rect.right = info.rect.left + 1; - info.rect.bottom = info.rect.top + 1; - } - - if (!NtUserEnumDisplayMonitors( 0, NULL, monitor_enum, (LPARAM)&info )) return 0; - if (!info.ret) - { - if (flags & MONITOR_DEFAULTTOPRIMARY) info.ret = info.primary; - else if (flags & MONITOR_DEFAULTTONEAREST) info.ret = info.nearest; - } - - TRACE( "%s flags %x returning %p\n", wine_dbgstr_rect(rect), flags, info.ret ); - return info.ret; + return UlongToHandle( NtUserCallTwoParam( (LONG_PTR)rect, flags, NtUserMonitorFromRect )); }
/*********************************************************************** diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 6c8c297bc63..7123b0d95c8 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1936,6 +1936,72 @@ static BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info ) return FALSE; }
+static HMONITOR monitor_from_rect( const RECT *rect, DWORD flags, UINT dpi ) +{ + HMONITOR primary = 0, nearest = 0, ret = 0; + UINT max_area = 0, min_distance = ~0u; + struct monitor *monitor; + RECT r; + + r = map_dpi_rect( *rect, dpi, system_dpi ); + if (is_rect_empty( &r )) + { + r.right = r.left + 1; + r.bottom = r.top + 1; + } + + if (!lock_display_devices()) return 0; + + LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry) + { + RECT intersect; + RECT monitor_rect = map_dpi_rect( monitor->rc_monitor, get_monitor_dpi( monitor->handle ), + system_dpi ); + + if (intersect_rect( &intersect, &monitor_rect, &r )) + { + /* check for larger intersecting area */ + UINT area = (intersect.right - intersect.left) * (intersect.bottom - intersect.top); + if (area > max_area) + { + max_area = area; + ret = monitor->handle; + } + } + else if (!max_area) /* if not intersecting, check for min distance */ + { + UINT distance; + UINT x, y; + + if (r.right <= monitor_rect.left) x = monitor_rect.left - r.right; + else if (monitor_rect.right <= r.left) x = r.left - monitor_rect.right; + else x = 0; + if (r.bottom <= monitor_rect.top) y = monitor_rect.top - r.bottom; + else if (monitor_rect.bottom <= r.top) y = r.top - monitor_rect.bottom; + else y = 0; + distance = x * x + y * y; + if (distance < min_distance) + { + min_distance = distance; + nearest = monitor->handle; + } + } + + if (monitor->flags & MONITORINFOF_PRIMARY) primary = monitor->handle; + } + + unlock_display_devices(); + + if (!ret) + { + if (flags & MONITOR_DEFAULTTOPRIMARY) ret = primary; + else if (flags & MONITOR_DEFAULTTONEAREST) ret = nearest; + } + + TRACE( "%s flags %x returning %p\n", wine_dbgstr_rect(rect), flags, ret ); + return ret; +} + /*********************************************************************** * NtUserGetSystemDpiForProcess (win32u.@) */ @@ -4427,6 +4493,8 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code return get_system_metrics_for_dpi( arg1, arg2 ); case NtUserMirrorRgn: return mirror_window_region( UlongToHandle(arg1), UlongToHandle(arg2) ); + case NtUserMonitorFromRect: + return HandleToUlong( monitor_from_rect( (const RECT *)arg1, arg2, get_thread_dpi() )); default: FIXME( "invalid code %u\n", code ); return 0; diff --git a/include/ntuser.h b/include/ntuser.h index 4b665e6a364..89106f38628 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -67,6 +67,7 @@ enum NtUserGetMonitorInfo, NtUserGetSystemMetricsForDpi, NtUserMirrorRgn, + NtUserMonitorFromRect, };
/* color index used to retrieve system 55aa brush */