[PATCH 1/2] winex11.drv: Refactor query_work_area() to get intersected work area directly.

Zhiyi Zhang zzhang at codeweavers.com
Tue Jun 30 04:56:21 CDT 2020


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 at codeweavers.com>
---
 dlls/winex11.drv/display.c  | 32 ++++++++++++++++++++++++++++++++
 dlls/winex11.drv/x11drv.h   |  2 +-
 dlls/winex11.drv/xinerama.c | 30 +++---------------------------
 dlls/winex11.drv/xrandr.c   |  6 ++----
 4 files changed, 38 insertions(+), 32 deletions(-)

diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index a6fe23ea68a..625e8be4f47 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -259,6 +259,38 @@ RECT get_host_primary_monitor_rect(void)
     return rect;
 }
 
+RECT get_work_area(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)
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index cfce09bf11d..bfc9aee027c 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -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( RECT *monitor_rect ) DECLSPEC_HIDDEN;
 extern void xinerama_init( unsigned int width, unsigned int height ) DECLSPEC_HIDDEN;
 
 struct x11drv_mode_info
diff --git a/dlls/winex11.drv/xinerama.c b/dlls/winex11.drv/xinerama.c
index 7e79fdeed77..c9863482534 100644
--- a/dlls/winex11.drv/xinerama.c
+++ b/dlls/winex11.drv/xinerama.c
@@ -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;
     }
diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c
index dce4e6739e4..14574e198f5 100644
--- a/dlls/winex11.drv/xrandr.c
+++ b/dlls/winex11.drv/xrandr.c
@@ -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 ))
-- 
2.25.1




More information about the wine-devel mailing list