[AD] ALLEGRO_FULLSCREEN_WINDOW flag

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


The attached patch adds a new display flag called
ALLEGRO_FULLSCREEN_WINDOW which makes al_create_display ignore the
passed width and height and instead creates a fullscreen window as big
as the desktop. It's ignored under Windows and OSX for now.

If someone figures out how to do things with Xinerama and XRandR (or can
fix XVidMode) this may not be needed any longer as al_get_monitor_info()
and al_set_current_video_adapter() should be able to achieve the same.
But even then the flag makes things much easier for the user as X11
decides on which monitor to place the window (here it is for example
always the monitor the bash window from which I run my game was on,
which is just perfect).

-- 
Elias Pschernig <elias.pschernig@xxxxxxxxxx>
diff --git a/docs/src/refman/display.txt b/docs/src/refman/display.txt
index 0340684..2af90ca 100644
--- a/docs/src/refman/display.txt
+++ b/docs/src/refman/display.txt
@@ -166,6 +166,11 @@ reasonable combination of the following:
 
 * ALLEGRO_FULLSCREEN - prefer a fullscreen mode
 
+* ALLEGRO_FULLSCREEN_WINDOW - ignore the w and h parameters passed to
+al_create_display and instead make a window spanning the entire
+screen. Unlike ALLEGRO_FULLSCREEN this will never attempt to modify
+the screen resolution.
+
 * ALLEGRO_RESIZABLE - the display is resizable (only applicable if combined
 with ALLEGRO_WINDOWED)
 
diff --git a/include/allegro5/display_new.h b/include/allegro5/display_new.h
index 84e9aa5..f1e842c 100644
--- a/include/allegro5/display_new.h
+++ b/include/allegro5/display_new.h
@@ -23,7 +23,8 @@
 //#define ALLEGRO_SINGLEBUFFER 32
 #define ALLEGRO_NOFRAME      64
 #define ALLEGRO_GENERATE_EXPOSE_EVENTS 128
-
+//is something using 256? didn't seem to work...
+#define ALLEGRO_FULLSCREEN_WINDOW 512
 
 /* Possible parameters for al_set_display_option.
  * Make sure to update ALLEGRO_EXTRA_DISPLAY_SETTINGS if you modify
diff --git a/include/allegro5/internal/aintern_xglx.h b/include/allegro5/internal/aintern_xglx.h
index 8d1ff8b..637f51b 100644
--- a/include/allegro5/internal/aintern_xglx.h
+++ b/include/allegro5/internal/aintern_xglx.h
@@ -151,6 +151,7 @@ void _al_xglx_restore_video_mode(ALLEGRO_SYSTEM_XGLX *s);
 void _al_xglx_free_mode_infos(ALLEGRO_SYSTEM_XGLX *s);
 void _al_xglx_fullscreen_to_display(ALLEGRO_SYSTEM_XGLX *s,
    ALLEGRO_DISPLAY_XGLX *d);
+void _al_xglx_toggle_fullscreen_window(ALLEGRO_DISPLAY *display, bool onoff);
 
 /* glx_config */
 void _al_xglx_config_select_visual(ALLEGRO_DISPLAY_XGLX *glx);
diff --git a/src/x/xdisplay.c b/src/x/xdisplay.c
index d14fccd..251efe6 100644
--- a/src/x/xdisplay.c
+++ b/src/x/xdisplay.c
@@ -34,7 +34,8 @@ static void setup_gl(ALLEGRO_DISPLAY *d)
 
 static void set_size_hints(ALLEGRO_DISPLAY *d, int w, int h)
 {
-   if (!(d->flags & ALLEGRO_RESIZABLE)) {
+   if (!(d->flags & ALLEGRO_RESIZABLE)
+      && !(d->flags & ALLEGRO_FULLSCREEN_WINDOW)) {
       ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver();
       ALLEGRO_DISPLAY_XGLX *glx = (void *)d;
       XSizeHints *hints = XAllocSizeHints();;
@@ -177,6 +178,12 @@ static void xdpy_toggle_frame(ALLEGRO_DISPLAY *display, bool onoff)
 }
 
 
+static Bool resize_predicate(Display *display, XEvent *event, XPointer arg)
+{
+   if (event->type == ConfigureNotify) return True;
+   return False;
+}
+
 
 /* Create a new X11 display, which maps directly to a GLX window. */
 static ALLEGRO_DISPLAY *xdpy_create_display(int w, int h)
@@ -291,6 +298,8 @@ static ALLEGRO_DISPLAY *xdpy_create_display(int w, int h)
    int new_x, new_y;
    al_get_new_window_position(&new_x, &new_y);
    if (new_x != INT_MAX && new_y != INT_MAX) {
+      ALLEGRO_DEBUG("Force window position to %d, %d.\n",
+         new_x, new_y);
       XWindowChanges wch;
       wch.x = new_x;
       wch.y = new_y;
@@ -309,6 +318,28 @@ static ALLEGRO_DISPLAY *xdpy_create_display(int w, int h)
       _al_cond_wait(&d->mapped, &system->lock);
    }
 
+   /* We can do this at any time, but if we already have a mapped
+    * window when switching to fullscreen it will use the same
+    * monitor (with the MetaCity version I'm using here right now).
+    */
+   if (display->flags & ALLEGRO_FULLSCREEN_WINDOW) {
+      _al_xglx_toggle_fullscreen_window(display, true);
+
+      /* Wait for the resize event so we can create the initial
+       * OpenGL view already with the full size.
+       */
+      XSync(system->x11display, False);
+      XEvent e;
+      XIfEvent(system->x11display, &e, resize_predicate, NULL); 
+
+      XWindowAttributes xwa;
+      XGetWindowAttributes(system->x11display, d->window, &xwa);
+      display->w = xwa.width;
+      display->h = xwa.height;
+      ALLEGRO_INFO("Using ALLEGRO_FULLSCREEN_WINDOW of %d x %d\n",
+         display->w, display->h);
+   }
+
    if (!_al_xglx_config_create_context(d)) {
       ALLEGRO_ERROR("Failed to create a context.\n");
       _AL_FREE(d);
@@ -390,7 +421,6 @@ static ALLEGRO_DISPLAY *xdpy_create_display(int w, int h)
          display->extra_settings.settings[ALLEGRO_VSYNC] = 0;
       }
    }
-   
 
    d->invisible_cursor = None; /* Will be created on demand. */
    d->current_cursor = None; /* Initially, we use the root cursor. */
diff --git a/src/x/xfullscreen.c b/src/x/xfullscreen.c
index 057cc49..6074970 100644
--- a/src/x/xfullscreen.c
+++ b/src/x/xfullscreen.c
@@ -235,4 +235,38 @@ void _al_xglx_free_mode_infos(ALLEGRO_SYSTEM_XGLX *s)
 
 #endif /* !ALLEGRO_XWINDOWS_WITH_XF86VIDMODE */
 
+static bool got_atoms;
+static Atom _NET_WM_STATE;
+static Atom _NET_WM_STATE_FULLSCREEN;
+#define X11_ATOM_STRING(x) x = XInternAtom(x11, #x, False);
+
+void _al_xglx_toggle_fullscreen_window(ALLEGRO_DISPLAY *display, bool onoff)
+{
+   ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver();
+   ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display;
+   Display *x11 = system->x11display;
+   
+   if (!got_atoms) {
+      X11_ATOM_STRING(_NET_WM_STATE)
+      X11_ATOM_STRING(_NET_WM_STATE_FULLSCREEN)
+      got_atoms = true;
+   }
+
+   XEvent xev;
+   xev.xclient.type = ClientMessage;
+   xev.xclient.serial = 0;
+   xev.xclient.send_event = True;
+   xev.xclient.message_type = _NET_WM_STATE;
+   xev.xclient.window = glx->window;
+   xev.xclient.format = 32;
+   xev.xclient.data.l[0] = onoff ? 1 : 0; /* 0 = off, 1 = on, 2 = toggle */
+   xev.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
+   xev.xclient.data.l[2] = 0;
+   xev.xclient.data.l[3] = 0;
+   xev.xclient.data.l[4] = 0;
+
+   XSendEvent(x11, DefaultRootWindow(x11), False,
+      SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+}
+
 /* vim: set sts=3 sw=3 et: */


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