Alexandre Julliard : user32: Implement monitor rectangle filtering on the user32 side.

Alexandre Julliard julliard at winehq.org
Tue Jul 17 15:52:37 CDT 2018


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Jul 17 13:50:26 2018 +0200

user32: Implement monitor rectangle filtering on the user32 side.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/sysparams.c | 75 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 53 insertions(+), 22 deletions(-)

diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c
index 67eb90a..e1044e94 100644
--- a/dlls/user32/sysparams.c
+++ b/dlls/user32/sysparams.c
@@ -21,6 +21,7 @@
 #include "config.h"
 
 #include <assert.h>
+#include <limits.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -3562,49 +3563,79 @@ BOOL WINAPI GetMonitorInfoW( HMONITOR monitor, LPMONITORINFO info )
     return ret;
 }
 
-#ifdef __i386__
-/* Some apps pass a non-stdcall callback to EnumDisplayMonitors,
- * so we need a small assembly wrapper to call it.
- * MJ's Help Diagnostic expects that %ecx contains the address to the rect.
- */
-struct enumdisplaymonitors_lparam
+struct enum_mon_data
 {
     MONITORENUMPROC proc;
     LPARAM lparam;
+    HDC hdc;
+    POINT origin;
+    RECT limit;
 };
 
-extern BOOL CALLBACK enumdisplaymonitors_callback_wrapper(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM lparam);
-__ASM_STDCALL_FUNC( enumdisplaymonitors_callback_wrapper, 16,
+#ifdef __i386__
+/* Some apps pass a non-stdcall callback to EnumDisplayMonitors,
+ * so we need a small assembly wrapper to call it.
+ * MJ's Help Diagnostic expects that %ecx contains the address to the rect.
+ */
+extern BOOL enum_mon_callback_wrapper( HMONITOR monitor, LPRECT rect, struct enum_mon_data *data );
+__ASM_GLOBAL_FUNC( enum_mon_callback_wrapper,
     "pushl %ebp\n\t"
     __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
     __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
     "movl %esp,%ebp\n\t"
     __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
     "subl $8,%esp\n\t"
-    "movl 20(%ebp),%eax\n\t"    /* struct enumdisplaymonitors_lparam *orig = (struct enumdisplaymonitors_lparam*)lparam */
-    "pushl 4(%eax)\n\t"         /* push orig->lparam */
-    "pushl 16(%ebp)\n\t"
-    "pushl 12(%ebp)\n\t"
-    "pushl 8(%ebp)\n\t"
-    "movl 16(%ebp),%ecx\n\t"
-    "call *(%eax)\n\t"          /* call orig->proc */
+    "movl 16(%ebp),%eax\n\t"    /* data */
+    "movl 12(%ebp),%ecx\n\t"    /* rect */
+    "pushl 4(%eax)\n\t"         /* data->lparam */
+    "pushl %ecx\n\t"            /* rect */
+    "pushl 8(%eax)\n\t"         /* data->hdc */
+    "pushl 8(%ebp)\n\t"         /* monitor */
+    "call *(%eax)\n\t"          /* data->proc */
     "leave\n\t"
     __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
     __ASM_CFI(".cfi_same_value %ebp\n\t")
-    "ret $16" )
+    "ret" )
 #endif /* __i386__ */
 
+static BOOL CALLBACK enum_mon_callback( HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM lp )
+{
+    struct enum_mon_data *data = (struct enum_mon_data *)lp;
+    RECT monrect = *rect;
+
+    OffsetRect( &monrect, -data->origin.x, -data->origin.y );
+    if (!IntersectRect( &monrect, &monrect, &data->limit )) return TRUE;
+#ifdef __i386__
+    return enum_mon_callback_wrapper( monitor, &monrect, data );
+#else
+    return data->proc( monitor, data->hdc, &monrect, data->lparam );
+#endif
+}
+
 /***********************************************************************
  *		EnumDisplayMonitors (USER32.@)
  */
 BOOL WINAPI EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
 {
-#ifdef __i386__
-    struct enumdisplaymonitors_lparam orig = { proc, lp };
-    proc = enumdisplaymonitors_callback_wrapper;
-    lp = (LPARAM)&orig;
-#endif
-    return USER_Driver->pEnumDisplayMonitors( hdc, rect, proc, lp );
+    struct enum_mon_data data;
+
+    data.proc = proc;
+    data.lparam = lp;
+    data.hdc = hdc;
+
+    if (hdc)
+    {
+        if (!GetDCOrgEx( hdc, &data.origin )) return FALSE;
+        if (GetClipBox( hdc, &data.limit ) == ERROR) return FALSE;
+    }
+    else
+    {
+        data.origin.x = data.origin.y = 0;
+        data.limit.left = data.limit.top = INT_MIN;
+        data.limit.right = data.limit.bottom = INT_MAX;
+    }
+    if (rect && !IntersectRect( &data.limit, &data.limit, rect )) return TRUE;
+    return USER_Driver->pEnumDisplayMonitors( 0, NULL, enum_mon_callback, (LPARAM)&data );
 }
 
 




More information about the wine-cvs mailing list