user32: Implement monitor rectangle filtering on the user32 side.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2be5b054d3
commit
aac37e8d0b
|
@ -21,6 +21,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -3562,49 +3563,79 @@ BOOL WINAPI GetMonitorInfoW( HMONITOR monitor, LPMONITORINFO info )
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct enum_mon_data
|
||||||
|
{
|
||||||
|
MONITORENUMPROC proc;
|
||||||
|
LPARAM lparam;
|
||||||
|
HDC hdc;
|
||||||
|
POINT origin;
|
||||||
|
RECT limit;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
/* Some apps pass a non-stdcall callback to EnumDisplayMonitors,
|
/* Some apps pass a non-stdcall callback to EnumDisplayMonitors,
|
||||||
* so we need a small assembly wrapper to call it.
|
* so we need a small assembly wrapper to call it.
|
||||||
* MJ's Help Diagnostic expects that %ecx contains the address to the rect.
|
* MJ's Help Diagnostic expects that %ecx contains the address to the rect.
|
||||||
*/
|
*/
|
||||||
struct enumdisplaymonitors_lparam
|
extern BOOL enum_mon_callback_wrapper( HMONITOR monitor, LPRECT rect, struct enum_mon_data *data );
|
||||||
{
|
__ASM_GLOBAL_FUNC( enum_mon_callback_wrapper,
|
||||||
MONITORENUMPROC proc;
|
|
||||||
LPARAM lparam;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern BOOL CALLBACK enumdisplaymonitors_callback_wrapper(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM lparam);
|
|
||||||
__ASM_STDCALL_FUNC( enumdisplaymonitors_callback_wrapper, 16,
|
|
||||||
"pushl %ebp\n\t"
|
"pushl %ebp\n\t"
|
||||||
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||||
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
|
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
|
||||||
"movl %esp,%ebp\n\t"
|
"movl %esp,%ebp\n\t"
|
||||||
__ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
|
__ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
|
||||||
"subl $8,%esp\n\t"
|
"subl $8,%esp\n\t"
|
||||||
"movl 20(%ebp),%eax\n\t" /* struct enumdisplaymonitors_lparam *orig = (struct enumdisplaymonitors_lparam*)lparam */
|
"movl 16(%ebp),%eax\n\t" /* data */
|
||||||
"pushl 4(%eax)\n\t" /* push orig->lparam */
|
"movl 12(%ebp),%ecx\n\t" /* rect */
|
||||||
"pushl 16(%ebp)\n\t"
|
"pushl 4(%eax)\n\t" /* data->lparam */
|
||||||
"pushl 12(%ebp)\n\t"
|
"pushl %ecx\n\t" /* rect */
|
||||||
"pushl 8(%ebp)\n\t"
|
"pushl 8(%eax)\n\t" /* data->hdc */
|
||||||
"movl 16(%ebp),%ecx\n\t"
|
"pushl 8(%ebp)\n\t" /* monitor */
|
||||||
"call *(%eax)\n\t" /* call orig->proc */
|
"call *(%eax)\n\t" /* data->proc */
|
||||||
"leave\n\t"
|
"leave\n\t"
|
||||||
__ASM_CFI(".cfi_def_cfa %esp,4\n\t")
|
__ASM_CFI(".cfi_def_cfa %esp,4\n\t")
|
||||||
__ASM_CFI(".cfi_same_value %ebp\n\t")
|
__ASM_CFI(".cfi_same_value %ebp\n\t")
|
||||||
"ret $16" )
|
"ret" )
|
||||||
#endif /* __i386__ */
|
#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.@)
|
* EnumDisplayMonitors (USER32.@)
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
|
BOOL WINAPI EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
|
||||||
{
|
{
|
||||||
#ifdef __i386__
|
struct enum_mon_data data;
|
||||||
struct enumdisplaymonitors_lparam orig = { proc, lp };
|
|
||||||
proc = enumdisplaymonitors_callback_wrapper;
|
data.proc = proc;
|
||||||
lp = (LPARAM)&orig;
|
data.lparam = lp;
|
||||||
#endif
|
data.hdc = hdc;
|
||||||
return USER_Driver->pEnumDisplayMonitors( hdc, rect, proc, lp );
|
|
||||||
|
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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue