[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