winex11.drv: Add support for _NET_WORKAREA. Try 3

Dmitry Timoshkov dmitry at codeweavers.com
Wed Oct 1 14:00:18 CDT 2008


This version of the patch should work correctly in desktop mode, and
actually compile without xinerama present.
---
 dlls/winex11.drv/x11drv.h      |    1 +
 dlls/winex11.drv/x11drv_main.c |    1 +
 dlls/winex11.drv/xinerama.c    |   41 +++++++++++++++++++++++++++++++++------
 3 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index f35ae5a..e5a40aa 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -614,6 +614,7 @@ enum x11drv_atoms
     XATOM__NET_WM_WINDOW_TYPE_DIALOG,
     XATOM__NET_WM_WINDOW_TYPE_NORMAL,
     XATOM__NET_WM_WINDOW_TYPE_UTILITY,
+    XATOM__NET_WORKAREA,
     XATOM__XEMBED_INFO,
     XATOM_XdndAware,
     XATOM_XdndEnter,
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 25a86f0..fc9996a 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -150,6 +150,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
     "_NET_WM_WINDOW_TYPE_DIALOG",
     "_NET_WM_WINDOW_TYPE_NORMAL",
     "_NET_WM_WINDOW_TYPE_UTILITY",
+    "_NET_WORKAREA",
     "_XEMBED_INFO",
     "XdndAware",
     "XdndEnter",
diff --git a/dlls/winex11.drv/xinerama.c b/dlls/winex11.drv/xinerama.c
index f68cf2a..fd95f92 100644
--- a/dlls/winex11.drv/xinerama.c
+++ b/dlls/winex11.drv/xinerama.c
@@ -65,6 +65,25 @@ static inline int monitor_to_index( HMONITOR handle )
     return index - 1;
 }
 
+static 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
 
@@ -88,7 +107,7 @@ static void load_xinerama(void)
     if (!pXineramaQueryScreens) WARN( "XineramaQueryScreens not found\n" );
 }
 
-static int query_screens(void)
+static int query_screens( RECT *rc_work )
 {
     int i, count, event_base, error_base;
     XineramaScreenInfo *screens;
@@ -96,6 +115,8 @@ static int query_screens(void)
     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;
@@ -111,7 +132,9 @@ static int query_screens(void)
             monitors[i].rcMonitor.top    = screens[i].y_org;
             monitors[i].rcMonitor.right  = screens[i].x_org + screens[i].width;
             monitors[i].rcMonitor.bottom = screens[i].y_org + screens[i].height;
-            monitors[i].rcWork           = monitors[i].rcMonitor;
+            monitors[i].rcWork           = *rc_work;
+            OffsetRect( &monitors[i].rcWork, monitors[i].rcMonitor.left, monitors[i].rcMonitor.top );
+            IntersectRect( &monitors[i].rcWork, &monitors[i].rcWork, &monitors[i].rcMonitor );
             monitors[i].dwFlags          = 0;
             /* FIXME: using the same device name for all monitors for now */
             lstrcpyW( monitors[i].szDevice, default_monitor.szDevice );
@@ -127,8 +150,9 @@ static int query_screens(void)
 
 #else  /* SONAME_LIBXINERAMA */
 
-static inline int query_screens(void)
+static int query_screens( RECT *rc_work )
 {
+    query_work_area( rc_work );
     return 0;
 }
 
@@ -138,15 +162,17 @@ void xinerama_init( unsigned int width, unsigned int height )
 {
     MONITORINFOEXW *primary;
     int i;
-    RECT rect;
+    RECT rect, rc_work;
 
     wine_tsx11_lock();
 
     SetRect( &rect, 0, 0, width, height );
+    rc_work = rect;
 
-    if (root_window != DefaultRootWindow( gdi_display ) || !query_screens())
+    if (root_window != DefaultRootWindow( gdi_display ) || !query_screens( &rc_work ))
     {
-        default_monitor.rcWork = default_monitor.rcMonitor = rect;
+        default_monitor.rcMonitor = rect;
+        default_monitor.rcWork = rc_work;
         nb_monitors = 1;
         monitors = &default_monitor;
     }
@@ -159,8 +185,9 @@ void xinerama_init( unsigned int width, unsigned int height )
     {
         OffsetRect( &monitors[i].rcMonitor, rect.left, rect.top );
         OffsetRect( &monitors[i].rcWork, rect.left, rect.top );
-        TRACE( "monitor %p: %s%s\n",
+        TRACE( "monitor %p: %s work %s%s\n",
                index_to_monitor(i), wine_dbgstr_rect(&monitors[i].rcMonitor),
+               wine_dbgstr_rect(&monitors[i].rcWork),
                (monitors[i].dwFlags & MONITORINFOF_PRIMARY) ? " (primary)" : "" );
     }
 
-- 
1.6.0.2




More information about the wine-patches mailing list