Re: [AD] RFC - Linux WM Fullscreen Patch

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Ug. I swear I'll figure out how to create a correct patch one day. This is a full one.

On 14-08-07 02:13 PM, Trent Gamblin wrote:
Here's another patch. There are 4 lines added besides the new file.

On 14-08-07 01:46 PM, Trent Gamblin wrote:
The information I was given by someone here before was that the "WM
Fullscreen" ie ALLEGRO_FULLSCREEN_VIRTUAL mode would be scaled up but it
wold be all done without the user having to worry about it and behave
exactly like ALLEGRO_FULLSCREEN otherwise.

In actuality, as I learned today, it's almost identical to
ALLEGRO_FULLSCREEN. The only difference is, some WM flags are set when
supported. The reason we didn't combine ALLEGRO_FULLSCREEN and
ALLEGRO_FULLSCREEN_VIRTUAL before was that someone said the scaling would be
a problem on certain hardware ie they needed it to be exactly like a
hardware fullscreen mode. However, I found out today that it is exactly the
same as a real hardware fullscreen mode.

So IMO the best thing to do is to remove the ALLEGRO_FULLSCREEN_VIRTUAL flag
and use the code paths I just added all the time (they check for support
first.) I don't see any drawback of doing it that way, in fact SDL does the
same thing, so if anyone has legitimate objections bring them up now.

----- Original Message -----
From: "SiegeLordEx" <slabode@xxxxxxxxxx>
To: <alleg-developers@xxxxxxxxxx>
Sent: Thursday, August 07, 2014 1:16 PM
Subject: Re: [AD] RFC - Linux WM Fullscreen Patch


On 08/07/2014 02:58 PM, Trent Gamblin wrote:
Looked at SDL closer - it behaves differently than I was told. It
doesn't scale at all, it uses the window manager to go fullscreen and
then xrandr/xvidmode to change the mode. Better for us, I did the same
and the patch is a ton simpler now.

I'd like to propose changing ALLEGRO_FULLSCREEN_WINDOW so that it
implies ALLEGRO_FULLSCREEN as well. That'll require a few changed checks
here and there but not as bad as making ALLEGRO_FULLSCREEN separate from
ALLEGRO_FULLSCREEN_WINDOW and ALLEGRO_FULLSCREEN_VIRTUAL. IMO it should
have been that way from the start, as a modifier.
What does this implication mean exactly? Will you be able to do
mode-setting via ALLEGRO_FULLSCREEN_WINDOW? I note the patch doesn't
seem to do that...

This wasn't really clear from the fullscreen thread earlier either...
what are the use cases for the 3 separate FULLSCREEN options? In the
current system, you use ALLEGRO_FULLSCREEN for performance (i.e. want
direct access and/or don't want to have a buffer bitmap + scaling) with
the caveat that it doesn't work well on modern monitors and
ALLEGRO_FULLSCREEN_WINDOW otherwise (i.e. most of the time). Does the
current plan change that reasoning? If the scaling idea is (at least
temporarily) abandoned, what is the use case for
ALLEGRO_FULLSCREEN_VIRTUAL?

Is there no way for ALLEGRO_FULLSCREEN_WINDOW and
ALLEGRO_FULLSCREEN_VIRTUAL to be combined?

-SL

------------------------------------------------------------------------------
Infragistics Professional
Build stunning WinForms apps today!
Reboot your WinForms applications with our WinForms controls.
Build a bridge from your legacy apps to the future.
http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk
-- 
https://lists.sourceforge.net/lists/listinfo/alleg-developers


------------------------------------------------------------------------------
Infragistics Professional
Build stunning WinForms apps today!
Reboot your WinForms applications with our WinForms controls.
Build a bridge from your legacy apps to the future.
http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk



------------------------------------------------------------------------------
Infragistics Professional
Build stunning WinForms apps today!
Reboot your WinForms applications with our WinForms controls. 
Build a bridge from your legacy apps to the future.
http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk



diff --git a/cmake/FileList.cmake b/cmake/FileList.cmake
index ede9c57..007dddd 100644
--- a/cmake/FileList.cmake
+++ b/cmake/FileList.cmake
@@ -114,6 +114,7 @@ set(ALLEGRO_SRC_X_FILES
     src/x/xrandr.c
     src/x/xsystem.c
     src/x/xwindow.c
+    src/x/xwmfullscreen.c
     src/linux/lhaptic.c
     src/linux/ljoynu.c
     )
diff --git a/include/allegro5/internal/aintern_xdisplay.h b/include/allegro5/internal/aintern_xdisplay.h
index a8e616d..d353376 100644
--- a/include/allegro5/internal/aintern_xdisplay.h
+++ b/include/allegro5/internal/aintern_xdisplay.h
@@ -92,6 +92,8 @@ struct ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE
 bool _al_xwin_set_gtk_display_overridable_interface(uint32_t check_version,
    const ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE *vt);
 
+bool x_try_fullscreen_via_netwm(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d);
+
 #endif /* !ALLEGRO_RASPBERRYPI */
 
 #endif
diff --git a/src/x/xfullscreen.c b/src/x/xfullscreen.c
index 0651e46..1e35b53 100644
--- a/src/x/xfullscreen.c
+++ b/src/x/xfullscreen.c
@@ -364,7 +364,9 @@ static bool xfvm_set_mode(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, int w
 {
    int mode_idx = -1;
    int adapter = _al_xglx_get_adapter(s, d, false);
-   
+
+   x_try_fullscreen_via_netwm(s, d);
+
 #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA
    /* TwinView workarounds, nothing to do here, since we can't really change or restore modes */
    if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) {
diff --git a/src/x/xrandr.c b/src/x/xrandr.c
index 36f3857..201b018 100644
--- a/src/x/xrandr.c
+++ b/src/x/xrandr.c
@@ -503,7 +503,9 @@ static bool xrandr_set_mode(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, int
 {
    int adapter = _al_xglx_get_adapter(s, d, false);
    int xscreen = _al_xglx_get_xscreen(s, adapter);
-   
+
+   x_try_fullscreen_via_netwm(s, d);
+
    xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, xscreen);
    
    xrandr_crtc *crtc = xrandr_map_to_crtc(s, xscreen, adapter);
diff --git a/src/x/xwmfullscreen.c b/src/x/xwmfullscreen.c
new file mode 100644
index 0000000..b03e023
--- /dev/null
+++ b/src/x/xwmfullscreen.c
@@ -0,0 +1,89 @@
+#include <X11/Xlib.h>
+
+#include "allegro5/allegro.h"
+#include "allegro5/internal/aintern_x.h"
+#include "allegro5/internal/aintern_xdisplay.h"
+#include "allegro5/internal/aintern_xfullscreen.h"
+#include "allegro5/internal/aintern_xsystem.h"
+
+#include <X11/Xatom.h>
+
+ALLEGRO_DEBUG_CHANNEL("display")
+
+#define _NET_WM_STATE_REMOVE    0l
+#define _NET_WM_STATE_ADD       1l
+#define _NET_WM_STATE_TOGGLE    2l
+
+#define GET_ATOM(X) XInternAtom(display, #X, False)
+
+static bool have_net_supporting_wm(Display *display)
+{
+   Atom _NET_SUPPORTING_WM_CHECK;
+   int status, real_format;
+   Atom real_type;
+   unsigned long items_read = 0, items_left = 0;
+   unsigned char *propdata = NULL;
+   Window wm_window = 0;
+
+   XSync(display, False);
+
+   _NET_SUPPORTING_WM_CHECK = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", False);
+   status = XGetWindowProperty(display, DefaultRootWindow(display), _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
+   if (status == Success) {
+      if (items_read) {
+         wm_window = ((Window*)propdata)[0];
+      }
+      if (propdata) {
+         XFree(propdata);
+         propdata = NULL;
+      }
+   }
+
+   if (wm_window) {
+      status = XGetWindowProperty(display, wm_window, _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
+      if (status != Success || !items_read || wm_window != ((Window*)propdata)[0]) {
+         wm_window = None;
+      }
+      if (status == Success && propdata) {
+         XFree(propdata);
+         propdata = NULL;
+      }
+   }
+
+   XSync(display, False);
+
+   if (!wm_window) {
+      return false;
+   }
+
+   return true;
+}
+
+bool x_try_fullscreen_via_netwm(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d)
+{
+   Display *display = s->x11display;
+   Atom _NET_WM_STATE = GET_ATOM(_NET_WM_STATE);
+   Atom _NET_WM_STATE_FULLSCREEN = GET_ATOM(_NET_WM_STATE_FULLSCREEN);
+
+   if (!have_net_supporting_wm(s->x11display)) {
+      return false;
+   }
+
+   Atom _NET_WM_STATE_MAXIMIZED_VERT = GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
+   Atom _NET_WM_STATE_MAXIMIZED_HORZ = GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
+   Atom _NET_WM_STATE_FOCUSED = GET_ATOM(_NET_WM_STATE_FOCUSED);
+
+   Atom atoms[4];
+
+   atoms[0] = _NET_WM_STATE_MAXIMIZED_VERT;
+   atoms[1] = _NET_WM_STATE_MAXIMIZED_HORZ;
+   atoms[2] = _NET_WM_STATE_FULLSCREEN;
+   atoms[3] = _NET_WM_STATE_FOCUSED;
+
+   XChangeProperty(display, d->window, _NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms, 4);
+
+   XFlush(display);
+
+   return true;
+}
+


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/