[PATCH 4/7] winex11.drv: Implement WGL_WINE_fullscreen_exclusive extension.

Rémi Bernon rbernon at codeweavers.com
Sat Mar 7 04:29:23 CST 2020


Fullscreen exclusive windows are treated as undecorated managed windows
and the window rect as the rendering area, instead of client rect.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winex11.drv/event.c  |  2 +-
 dlls/winex11.drv/opengl.c | 28 ++++++++++++++++++++++++
 dlls/winex11.drv/window.c | 45 ++++++++++++++++++++++++++++++---------
 dlls/winex11.drv/x11drv.h |  1 +
 4 files changed, 65 insertions(+), 11 deletions(-)

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 07f7a1ad502..30d15b9a236 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -1160,7 +1160,7 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
                data->window_rect.bottom - data->window_rect.top, cx, cy );
 
     style = GetWindowLongW( data->hwnd, GWL_STYLE );
-    if ((style & WS_CAPTION) == WS_CAPTION)
+    if ((style & WS_CAPTION) == WS_CAPTION && !data->fullscreen_exclusive)
     {
         read_net_wm_states( event->display, data );
         if ((data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)))
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index 7fb97f5f446..997df873b16 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -3043,6 +3043,30 @@ static BOOL X11DRV_wglSwapIntervalEXT(int interval)
     return ret;
 }
 
+
+/**
+ * X11DRV_wglSetFullscreenExclusiveWINE
+ *
+ * WGL_WINE_fullscreen_exclusive: wglSetFullscreenExclusiveWINE
+ */
+static BOOL X11DRV_wglSetFullscreenExclusiveWINE(HWND hwnd, int fullscreen_exclusive)
+{
+    struct x11drv_win_data *data;
+
+    TRACE("(%p,%d)\n", hwnd, fullscreen_exclusive);
+
+    if (!(data = get_win_data( hwnd )))
+    {
+        WARN("not a proper window %p\n", hwnd);
+        return FALSE;
+    }
+
+    data->fullscreen_exclusive = fullscreen_exclusive;
+    release_win_data( data );
+    return TRUE;
+}
+
+
 /**
  * X11DRV_wglSetPixelFormatWINE
  *
@@ -3213,6 +3237,10 @@ static void X11DRV_WineGL_LoadExtensions(void)
 
     /* WINE-specific WGL Extensions */
 
+    /* In WineD3D we need the ability to make a window fullscreen exclusive. */
+    register_extension( "WGL_WINE_fullscreen_exclusive" );
+    opengl_funcs.ext.p_wglSetFullscreenExclusiveWINE = X11DRV_wglSetFullscreenExclusiveWINE;
+
     /* In WineD3D we need the ability to set the pixel format more than once (e.g. after a device reset).
      * The default wglSetPixelFormat doesn't allow this, so add our own which allows it.
      */
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 723f0c6e7b0..144da39f3ab 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -227,6 +227,7 @@ static BOOL is_window_managed( struct x11drv_win_data *data, UINT swp_flags, con
     DWORD style, ex_style;
 
     if (!managed_mode) return FALSE;
+    if (data->fullscreen_exclusive) return TRUE;
 
     /* child windows are not managed */
     style = GetWindowLongW( data->hwnd, GWL_STYLE );
@@ -272,7 +273,8 @@ static inline BOOL is_window_resizable( struct x11drv_win_data *data, DWORD styl
 {
     if (style & WS_THICKFRAME) return TRUE;
     /* Metacity needs the window to be resizable to make it fullscreen */
-    return is_window_rect_fullscreen( &data->whole_rect );
+    return is_window_rect_fullscreen( &data->whole_rect ) ||
+           data->fullscreen_exclusive;
 }
 
 
@@ -285,6 +287,7 @@ static unsigned long get_mwm_decorations( struct x11drv_win_data *data,
     unsigned long ret = 0;
 
     if (!decorated_mode) return 0;
+    if (data->fullscreen_exclusive) return 0;
 
     if (IsRectEmpty( &data->window_rect )) return 0;
     if (data->shaped) return 0;
@@ -944,7 +947,9 @@ void update_net_wm_states( struct x11drv_win_data *data )
     style = GetWindowLongW( data->hwnd, GWL_STYLE );
     if (style & WS_MINIMIZE)
         new_state |= data->net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED));
-    if (is_window_rect_fullscreen( &data->whole_rect ))
+    if (data->fullscreen_exclusive)
+        new_state |= (1 << NET_WM_STATE_FULLSCREEN);
+    else if (is_window_rect_fullscreen( &data->whole_rect ))
     {
         if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION)
             new_state |= (1 << NET_WM_STATE_MAXIMIZED);
@@ -1298,10 +1303,20 @@ static void sync_client_position( struct x11drv_win_data *data,
 
     if (!data->client_window) return;
 
-    changes.x      = data->client_rect.left - data->whole_rect.left;
-    changes.y      = data->client_rect.top - data->whole_rect.top;
-    changes.width  = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 );
-    changes.height = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 );
+    if (data->fullscreen_exclusive)
+    {
+        changes.x      = data->whole_rect.left;
+        changes.y      = data->whole_rect.top;
+        changes.width  = min( max( 1, data->whole_rect.right - data->whole_rect.left ), 65535 );
+        changes.height = min( max( 1, data->whole_rect.bottom - data->whole_rect.top ), 65535 );
+    }
+    else
+    {
+        changes.x      = data->client_rect.left - data->whole_rect.left;
+        changes.y      = data->client_rect.top - data->whole_rect.top;
+        changes.width  = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 );
+        changes.height = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 );
+    }
 
     if (changes.x != old_client_rect->left - old_whole_rect->left) mask |= CWX;
     if (changes.y != old_client_rect->top  - old_whole_rect->top)  mask |= CWY;
@@ -1456,10 +1471,20 @@ Window create_client_window( HWND hwnd, const XVisualInfo *visual )
     attr.backing_store = NotUseful;
     attr.border_pixel = 0;
 
-    x = data->client_rect.left - data->whole_rect.left;
-    y = data->client_rect.top - data->whole_rect.top;
-    cx = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 );
-    cy = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 );
+    if (data->fullscreen_exclusive)
+    {
+        x = data->whole_rect.left;
+        y = data->whole_rect.top;
+        cx = min( max( 1, data->whole_rect.right - data->whole_rect.left ), 65535 );
+        cy = min( max( 1, data->whole_rect.bottom - data->whole_rect.top ), 65535 );
+    }
+    else
+    {
+        x = data->client_rect.left - data->whole_rect.left;
+        y = data->client_rect.top - data->whole_rect.top;
+        cx = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 );
+        cy = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 );
+    }
 
     ret = data->client_window = XCreateWindow( gdi_display,
                                                data->whole_window ? data->whole_window : dummy_parent,
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 98cab8947be..baa0f7478e9 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -565,6 +565,7 @@ struct x11drv_win_data
     RECT        whole_rect;     /* X window rectangle for the whole window relative to parent */
     RECT        client_rect;    /* client area relative to parent */
     XIC         xic;            /* X input context */
+    BOOL        fullscreen_exclusive : 1; /* is window fullscreen exclusive? */
     BOOL        managed : 1;    /* is window managed? */
     BOOL        mapped : 1;     /* is window mapped? (in either normal or iconic state) */
     BOOL        iconic : 1;     /* is window in iconic state? */
-- 
2.25.0




More information about the wine-devel mailing list