winex11.drv: Refactor query_work_area() to get intersected work area directly.

Refactor query_work_area() to pass in a monitor rectangle and check
if the resulting work area intersects with the monitor rectangle in
the function rather than doing it in the callers. Also move the function
to display.c and rename it to get_work_area().

Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zhiyi Zhang 2020-06-30 17:56:21 +08:00 committed by Alexandre Julliard
parent b0f6650452
commit 5dd03cbc8f
4 changed files with 38 additions and 32 deletions

View File

@ -259,6 +259,38 @@ RECT get_host_primary_monitor_rect(void)
return rect;
}
RECT get_work_area(const RECT *monitor_rect)
{
Atom type;
int format;
unsigned long count, remaining;
long *work_area;
RECT work_rect;
if (!XGetWindowProperty(gdi_display, DefaultRootWindow(gdi_display), x11drv_atom(_NET_WORKAREA),
0, ~0, False, XA_CARDINAL, &type, &format, &count, &remaining,
(unsigned char **)&work_area))
{
if (type == XA_CARDINAL && format == 32 && count >= 4)
{
SetRect(&work_rect, work_area[0], work_area[1], work_area[0] + work_area[2],
work_area[1] + work_area[3]);
if (IntersectRect(&work_rect, &work_rect, monitor_rect))
{
TRACE("work_rect:%s.\n", wine_dbgstr_rect(&work_rect));
XFree(work_area);
return work_rect;
}
}
XFree(work_area);
}
WARN("_NET_WORKAREA is not supported, Work areas may be incorrect.\n");
TRACE("work_rect:%s.\n", wine_dbgstr_rect(monitor_rect));
return *monitor_rect;
}
void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *new_handler)
{
if (new_handler->priority > host_handler.priority)

View File

@ -645,7 +645,7 @@ extern POINT root_to_virtual_screen( INT x, INT y ) DECLSPEC_HIDDEN;
extern RECT get_virtual_screen_rect(void) DECLSPEC_HIDDEN;
extern RECT get_primary_monitor_rect(void) DECLSPEC_HIDDEN;
extern RECT get_host_primary_monitor_rect(void) DECLSPEC_HIDDEN;
extern void query_work_area( RECT *rc_work ) DECLSPEC_HIDDEN;
extern RECT get_work_area( const RECT *monitor_rect ) DECLSPEC_HIDDEN;
extern void xinerama_init( unsigned int width, unsigned int height ) DECLSPEC_HIDDEN;
struct x11drv_mode_info

View File

@ -54,26 +54,6 @@ static inline MONITORINFOEXW *get_primary(void)
return &monitors[idx];
}
void query_work_area( RECT *rc_work )
{
Atom type;
int format;
unsigned long count, remaining;
long *work_area;
if (!XGetWindowProperty( gdi_display, DefaultRootWindow(gdi_display), x11drv_atom(_NET_WORKAREA), 0,
~0, False, XA_CARDINAL, &type, &format, &count,
&remaining, (unsigned char **)&work_area ))
{
if (type == XA_CARDINAL && format == 32 && count >= 4)
{
SetRect( rc_work, work_area[0], work_area[1],
work_area[0] + work_area[2], work_area[1] + work_area[3] );
}
XFree( work_area );
}
}
#ifdef SONAME_LIBXINERAMA
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
@ -100,13 +80,10 @@ static int query_screens(void)
{
int i, count, event_base, error_base;
XineramaScreenInfo *screens;
RECT rc_work = {0, 0, 0, 0};
if (!monitors) /* first time around */
load_xinerama();
query_work_area( &rc_work );
if (!pXineramaQueryExtension || !pXineramaQueryScreens ||
!pXineramaQueryExtension( gdi_display, &event_base, &error_base ) ||
!(screens = pXineramaQueryScreens( gdi_display, &count ))) return 0;
@ -123,8 +100,7 @@ static int query_screens(void)
monitors[i].rcMonitor.right = screens[i].x_org + screens[i].width;
monitors[i].rcMonitor.bottom = screens[i].y_org + screens[i].height;
monitors[i].dwFlags = 0;
if (!IntersectRect( &monitors[i].rcWork, &rc_work, &monitors[i].rcMonitor ))
monitors[i].rcWork = monitors[i].rcMonitor;
monitors[i].rcWork = get_work_area( &monitors[i].rcMonitor );
}
get_primary()->dwFlags |= MONITORINFOF_PRIMARY;
@ -298,8 +274,8 @@ void xinerama_init( unsigned int width, unsigned int height )
SetRect( &rect, 0, 0, width, height );
if (!query_screens())
{
default_monitor.rcWork = default_monitor.rcMonitor = rect;
query_work_area( &default_monitor.rcWork );
default_monitor.rcMonitor = rect;
default_monitor.rcWork = get_work_area( &default_monitor.rcMonitor );
nb_monitors = 1;
monitors = &default_monitor;
}

View File

@ -1054,7 +1054,7 @@ static BOOL xrandr14_get_monitors( ULONG_PTR adapter_id, struct x11drv_monitor *
XRROutputInfo *output_info = NULL, *enum_output_info = NULL;
XRRCrtcInfo *crtc_info = NULL, *enum_crtc_info;
INT primary_index = 0, monitor_count = 0, capacity;
RECT work_rect, primary_rect;
RECT primary_rect;
BOOL ret = FALSE;
INT i;
@ -1089,7 +1089,6 @@ static BOOL xrandr14_get_monitors( ULONG_PTR adapter_id, struct x11drv_monitor *
/* Active monitors, need to find other monitors with the same coordinates as mirrored */
else
{
query_work_area( &work_rect );
primary_rect = get_primary_rect( screen_resources );
for (i = 0; i < screen_resources->noutput; ++i)
@ -1132,8 +1131,7 @@ static BOOL xrandr14_get_monitors( ULONG_PTR adapter_id, struct x11drv_monitor *
SetRect( &monitors[monitor_count].rc_monitor, crtc_info->x, crtc_info->y,
crtc_info->x + crtc_info->width, crtc_info->y + crtc_info->height );
if (!IntersectRect( &monitors[monitor_count].rc_work, &work_rect, &monitors[monitor_count].rc_monitor ))
monitors[monitor_count].rc_work = monitors[monitor_count].rc_monitor;
monitors[monitor_count].rc_work = get_work_area( &monitors[monitor_count].rc_monitor );
monitors[monitor_count].state_flags = DISPLAY_DEVICE_ATTACHED;
if (!IsRectEmpty( &monitors[monitor_count].rc_monitor ))