Jacek Caban : win32u: Move monitor_from_rect implementation from user32.

Alexandre Julliard julliard at winehq.org
Mon Feb 14 15:41:30 CST 2022


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

Author: Jacek Caban <jacek at 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 at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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 */




More information about the wine-cvs mailing list