[PATCH][TESTSUITE] fullscreen-code from g1

Fabian Franz <[email protected]>
Newsgroups gmane.comp.video.mplayer.g2.devel
Message-ID <[email protected]>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

attached the new fs patch, especially for Gabucino to test it ...

There are some issues:

- - First: Design, this patch simply sucks. Its just a test suite for added 
x11_fs.c and for two window-system. So no resize, etc. ...

This file is for guis and every code, that wants to use fullscreen (if with 
two windows or XReparentWindow). As it would be really bloat if each gui 
implemented this file itself ...

I plan to make more functions static, all variables are already static and a 
header-file is missing, yet.

This patch is NOT for inclusion.

Its just for testers and people, who want to have fullscreen with g2 ;)

- - Second issue is, that its all about timing, if you press 'f' at the right 
time, you get a good fullscreen-window else its not on top or not even there, 
just vanished ... Thats strange behaviour, but I guess there is somewhere a 
10l I missed, yet ;)
After you pressed f at leat 3 times it then does work:

So the following should bring you always to good fullscreen-mode ;) :

echo fff | ./test-play <filename>

cu

Fabian
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.0 (GNU/Linux)

iD8DBQE/QAMpI0lSH7CXz7MRAj36AJ0WUP6d7CBLmMk+A90JVonpIOeBLwCeMkW0
wppYZjkdWqYY1IcOYdfnaJ4=
=Klkz
-----END PGP SIGNATURE-----

_______________________________________________
MPlayer-G2-dev mailing list
[email protected]
http://mplayerhq.hu/mailman/listinfo/mplayer-g2-dev
g2-fs_v1.diff (text/x-diff, 26.8 KB)
diff -Nur g2.old/libvo2/aspect.c g2/libvo2/aspect.c
--- g2.old/libvo2/aspect.c	1970-01-01 01:00:00.000000000 +0100
+++ g2/libvo2/aspect.c	2003-08-16 12:17:10.000000000 +0200
@@ -0,0 +1,124 @@
+/* Stuff for correct aspect scaling. */
+#include "aspect.h"
+#ifndef ASPECT_TEST
+#include "../mp_msg.h"
+#endif
+
+//#define ASPECT_DEBUG
+
+#if defined(ASPECT_DEBUG) || defined(ASPECT_TEST)
+#include <stdio.h>
+#endif
+
+int vo_panscan_x = 0;
+int vo_panscan_y = 0;
+float vo_panscan_amount = 0;
+
+#include "video_out.h"
+
+float monitor_aspect=4.0/3.0;
+
+static struct {
+  int orgw; // real width
+  int orgh; // real height
+  int prew; // prescaled width
+  int preh; // prescaled height
+  int scrw; // horizontal resolution
+  int scrh; // vertical resolution
+  float asp;
+} aspdat;
+
+void aspect_save_orig(int orgw, int orgh){
+#ifdef ASPECT_DEBUG
+  printf("aspect_save_orig %dx%d \n",orgw,orgh);
+#endif
+  aspdat.orgw = orgw;
+  aspdat.orgh = orgh;
+}
+
+void aspect_save_prescale(int prew, int preh){
+#ifdef ASPECT_DEBUG
+  printf("aspect_save_prescale %dx%d \n",prew,preh);
+#endif
+  aspdat.prew = prew;
+  aspdat.preh = preh;
+}
+
+void aspect_save_screenres(int scrw, int scrh){
+#ifdef ASPECT_DEBUG
+  printf("aspect_save_screenres %dx%d \n",scrw,scrh);
+#endif
+  aspdat.scrw = scrw;
+  aspdat.scrh = scrh;
+}
+
+/* aspect is called with the source resolution and the
+ * resolution, that the scaled image should fit into
+ */
+
+void aspect(int *srcw, int *srch, int zoom){
+  int tmpw;
+
+#ifdef ASPECT_DEBUG
+  printf("aspect(0) fitin: %dx%d zoom: %d screenaspect: %.2f\n",aspdat.scrw,aspdat.scrh,
+      zoom,monitor_aspect);
+  printf("aspect(1) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat.prew,aspdat.preh);
+#endif
+  if(zoom){
+    *srcw = aspdat.scrw;
+    *srch = (int)(((float)aspdat.scrw / (float)aspdat.prew * (float)aspdat.preh)
+               * ((float)aspdat.scrh / ((float)aspdat.scrw / monitor_aspect)));
+  }else{
+    *srcw = aspdat.prew;
+    *srch = (int)((float)aspdat.preh
+               * ((float)aspdat.scrh / ((float)aspdat.scrw / monitor_aspect)));
+  }
+  *srch+= *srch%2; // round
+#ifdef ASPECT_DEBUG
+  printf("aspect(2) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat.prew,aspdat.preh);
+#endif
+  if(*srch>aspdat.scrh || *srch<aspdat.orgh){
+    if(zoom)
+      tmpw = (int)(((float)aspdat.scrh / (float)aspdat.preh * (float)aspdat.prew)
+                * ((float)aspdat.scrw / ((float)aspdat.scrh / (1.0/monitor_aspect))));
+    else
+      tmpw = (int)((float)aspdat.prew
+                * ((float)aspdat.scrw / ((float)aspdat.scrh / (1.0/monitor_aspect))));
+    tmpw+= tmpw%2; // round
+    if(tmpw<=aspdat.scrw /*&& tmpw>=aspdat.orgw*/){
+      *srch = zoom?aspdat.scrh:aspdat.preh;
+      *srcw = tmpw;
+    }else{
+#ifndef ASPECT_TEST
+      mp_msg(MSGT_VO,MSGL_WARN,"aspect: Warning: no suitable new res found!\n");
+#else
+      printf("error: no new size found that fits into res!\n");
+#endif
+    }
+  }
+  aspdat.asp=*srcw / (float)*srch;
+#ifdef ASPECT_DEBUG
+  printf("aspect(3) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat.prew,aspdat.preh);
+#endif
+}
+
+/*void panscan_init( void )
+{
+ vo_panscan_x=0;
+ vo_panscan_y=0;
+ vo_panscan_amount=0.0f;
+}
+
+void panscan_calc( void )
+{
+ int fwidth,fheight;
+ int vo_panscan_area;
+
+ aspect(&fwidth,&fheight,A_ZOOM);
+ vo_panscan_area = (aspdat.scrh-fheight);
+
+ vo_panscan_amount = vo_fs ? vo_panscan : 0;
+ vo_panscan_x = vo_panscan_area * vo_panscan_amount * aspdat.asp;
+ vo_panscan_y = vo_panscan_area * vo_panscan_amount;
+}*/
+
diff -Nur g2.old/libvo2/aspect.h g2/libvo2/aspect.h
--- g2.old/libvo2/aspect.h	1970-01-01 01:00:00.000000000 +0100
+++ g2/libvo2/aspect.h	2003-08-16 12:16:22.000000000 +0200
@@ -0,0 +1,24 @@
+#ifndef __ASPECT_H
+#define __ASPECT_H
+/* Stuff for correct aspect scaling. */
+
+extern int vo_panscan_x;
+extern int vo_panscan_y;
+extern float vo_panscan_amount;
+
+extern void panscan_init( void );
+extern void panscan_calc( void );
+
+void aspect_save_orig(int orgw, int orgh);
+
+void aspect_save_prescale(int prew, int preh);
+
+void aspect_save_screenres(int scrw, int scrh);
+
+#define A_ZOOM 1
+#define A_NOZOOM 0
+
+void aspect(int *srcw, int *srch, int zoom);
+
+#endif
+
diff -Nur g2.old/libvo2/aspecttest.c g2/libvo2/aspecttest.c
--- g2.old/libvo2/aspecttest.c	1970-01-01 01:00:00.000000000 +0100
+++ g2/libvo2/aspecttest.c	2003-08-16 12:16:23.000000000 +0200
@@ -0,0 +1,43 @@
+/* testapp for aspect.[ch] by Atmos
+ * gcc aspecttest.c aspect.c -o aspecttest -DASPECT_TEST [-DASPECT_DEBUG]
+ */
+
+#include <stdio.h>
+
+#include "aspect.h"
+
+/* default zoom state 0 off, 1 on */
+#define DEF_ZOOM 1
+
+extern float monitor_aspect;
+
+int main(int argc, char *argv[]) {
+  int w,h,z=DEF_ZOOM;
+  //printf("argc: %d\n",argc);
+  switch(argc) {
+    case 10:
+      z = atoi(argv[9]);
+    case 9:
+      monitor_aspect = (float)atoi(argv[7])/(float)atoi(argv[8]);
+    case 7:
+      aspect_save_prescale(atoi(argv[5]),atoi(argv[6]));
+      printf("prescale size:  %sx%s\n",argv[5],argv[6]);
+    case 5:
+      aspect_save_screenres(atoi(argv[1]),atoi(argv[2]));
+      printf("screenres:      %sx%s\n",argv[1],argv[2]);
+      aspect_save_orig(atoi(argv[3]),atoi(argv[4]));
+      printf("original size:  %sx%s\n",argv[3],argv[4]);
+      w=atoi(argv[3]); h=atoi(argv[4]);
+    break;
+    default:
+      printf("USAGE: %s <screenw> <screenh> <origw> <origh>\n[<prescalew> "
+             "<prescaleh>] [<screenaspectw> <screenaspecth>] [<zoom 0/1>]\n",
+        argv[0]);
+      return 1;
+  }
+  printf("monitor_aspect: %f\n",monitor_aspect);
+  aspect(&w,&h,z); 
+  printf("new size:       %dx%d\n",w,h);
+  return 0;
+}
+
diff -Nur g2.old/libvo2/Makefile g2/libvo2/Makefile
--- g2.old/libvo2/Makefile	2003-07-24 00:12:27.000000000 +0200
+++ g2/libvo2/Makefile	2003-08-17 14:59:55.000000000 +0200
@@ -3,7 +3,7 @@
 
 LIBNAME = libvo2.a
 
-SRCS=vo_null.c vo_fbdev.c vo_x11.c vo_xv.c vo_mga.c vo_tdfx_vid.c vo_xover.c video_out.c event.c x11_helper.c # vo_pgm.c vo_md5.c
+SRCS=vo_null.c vo_fbdev.c vo_x11.c vo_xv.c vo_mga.c vo_tdfx_vid.c vo_xover.c video_out.c event.c x11_helper.c aspect.c x11_fs.c # vo_pgm.c vo_md5.c
 OBJS=$(SRCS:.c=.o)
 
 ifeq ($(VIDIX),yes)
diff -Nur g2.old/libvo2/video_out.h g2/libvo2/video_out.h
--- g2.old/libvo2/video_out.h	2003-08-03 01:01:24.000000000 +0200
+++ g2/libvo2/video_out.h	2003-08-16 13:32:24.000000000 +0200
@@ -34,6 +34,8 @@
 #define VOCTRL_SET_EQUALIZER 17
 #define VOCTRL_GET_EQUALIZER 18
 
+#define VOCTRL_FULLSCREEN 50
+
 #define VO_NOTIMPL      -3
 #define VO_NOTAVAIL     -2
 #define VO_ERROR        -1
@@ -46,6 +48,7 @@
 #define VO_EVENT_MOVE 4
 #define VO_EVENT_EXPOSE 5
 #define VO_EVENT_CONFIG 6
+#define VO_EVENT_FULLSCREEN 7
 
 // we cannot access the buffer directly, just via draw_slice() :(
 #define VO_BUFFER_FLAG_INDIRECT 1
diff -Nur g2.old/libvo2/vo_x11.c g2/libvo2/vo_x11.c
--- g2.old/libvo2/vo_x11.c	2003-07-13 23:55:49.000000000 +0200
+++ g2/libvo2/vo_x11.c	2003-08-17 14:40:53.000000000 +0200
@@ -7,6 +7,7 @@
 #include "mp_msg.h"
 
 #include "video_out.h"
+#include "aspect.h"
 #include "video/vfcap.h"
 #include "video/img_format.h"
 
@@ -34,6 +35,9 @@
     int depth,bpp;
 };
 
+extern int vo_screenwidth, vo_screenheight; // FIXME!!!!
+static int zoom=1; // FIXME!!!
+
 static int control(struct vo_instance_s* vo,
 	int request, void *data, ...){
     switch(request){
@@ -45,6 +49,22 @@
 	    vo->priv->gc = XCreateGC(vo->priv->dpy, vo->priv->win, 0L, &vo->priv->xgcv);
 	}
 	return VO_TRUE;
+    case VOCTRL_FULLSCREEN:
+	vo->fullscreen=(int)*(int*)data;
+	if (vo->fullscreen)
+	{
+  	    vo->x=( vo_screenwidth - (vo->w > vo_screenwidth?vo_screenwidth:vo->w) ) / 2;
+            vo->y=( vo_screenheight - (vo->h > vo_screenheight?vo_screenheight:vo->h) ) / 2;
+  	    vo->w=(vo->w > vo_screenwidth?vo_screenwidth:vo->w);
+            vo->h=(vo->h > vo_screenheight?vo_screenheight:vo->h);
+            mp_msg(MSGT_VO,MSGL_V, "[x11-fs] dx: %d dy: %d dw: %d dh: %d\n",vo->x,vo->y,vo->w,vo->h );	
+	}
+	else
+	{
+	  vo->x=0;
+	  vo->y=0;
+	}
+	return VO_TRUE;
 #if 0
     case VOCTRL_RESIZE_DEST:
 	if( ((int*)data)[0] >= 0 ) vo->x=((int*)data)[0];
@@ -155,6 +175,11 @@
 
     vo->w=d_width; vo->h=d_height;
     vo->buffer_w=width; vo->buffer_h=height; vo->format=format;
+    // FIXME - Add panscan ?
+    aspect_save_orig(width,height);
+    aspect_save_prescale(d_width,d_height);
+    // FIXME !
+    aspect_save_screenres(vo_screenwidth,vo_screenheight);
 
 //    XClearWindow(vo->priv->dpy, vo->priv->win);
 
diff -Nur g2.old/libvo2/vo_xv.c g2/libvo2/vo_xv.c
--- g2.old/libvo2/vo_xv.c	2003-08-02 20:54:44.000000000 +0200
+++ g2/libvo2/vo_xv.c	2003-08-17 14:38:52.000000000 +0200
@@ -7,6 +7,7 @@
 #include "mp_msg.h"
 
 #include "video_out.h"
+#include "aspect.h"
 #include "video/vfcap.h"
 #include "video/img_format.h"
 
@@ -35,6 +36,7 @@
     GC gc;
     int shm_flag;
 };
+extern int vo_screenwidth, vo_screenheight;
 
 static int control(struct vo_instance_s* vo,
 	int request, void *data, ...){
@@ -47,7 +49,26 @@
 	    vo->priv->gc = XCreateGC(vo->priv->dpy, vo->priv->win, 0L, &vo->priv->xgcv);
 	}
 	return VO_TRUE;
+    case VOCTRL_FULLSCREEN:
+	vo->fullscreen=(int)*(int*)data;
+	if (vo->fullscreen)
+	{
+          aspect(&vo->w,&vo->h, A_ZOOM);
+	  vo->x=( vo_screenwidth - (vo->w > vo_screenwidth?vo_screenwidth:vo->w) ) / 2;
+          vo->y=( vo_screenheight - (vo->h > vo_screenheight?vo_screenheight:vo->h) ) / 2;
+	  vo->w=(vo->w > vo_screenwidth?vo_screenwidth:vo->w);
+          vo->h=(vo->h > vo_screenheight?vo_screenheight:vo->h);
+          mp_msg(MSGT_VO,MSGL_V, "[xv-fs] dx: %d dy: %d dw: %d dh: %d\n",vo->x,vo->y,vo->w,vo->h );	
+	}
+	else
+	{
+	  vo->x=0;
+	  vo->y=0;
+	}
+	return VO_TRUE;
     case VOCTRL_RESIZE_DEST:
+	if (vo->fullscreen)
+	    return VO_NOTAVAIL;
 #if 1
 	if( ((int*)data)[0] >= 0 ) vo->x=((int*)data)[0];
 	if( ((int*)data)[1] >= 0 ) vo->y=((int*)data)[1];
@@ -163,6 +184,11 @@
 
     vo->w=d_width; vo->h=d_height;
     vo->buffer_w=width; vo->buffer_h=height; vo->format=format;
+    // FIXME - Add panscan ?
+    aspect_save_orig(width,height);
+    aspect_save_prescale(d_width,d_height);
+    // FIXME !
+    aspect_save_screenres(vo_screenwidth,vo_screenheight);
 
     if(!vo->buffers){
 	vo->num_buffers=1;
diff -Nur g2.old/libvo2/x11_fs.c g2/libvo2/x11_fs.c
--- g2.old/libvo2/x11_fs.c	1970-01-01 01:00:00.000000000 +0100
+++ g2/libvo2/x11_fs.c	2003-08-17 16:36:52.000000000 +0200
@@ -0,0 +1,465 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <inttypes.h>
+
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <signal.h>
+
+#include "video_out.h"
+#include "help_mp.h"
+#include "mp_msg.h"
+
+#include <X11/Xmd.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+/*#ifdef HAVE_XDPMS
+#include <X11/extensions/dpms.h>
+#endif
+
+#ifdef HAVE_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+
+#ifdef HAVE_XF86VM
+#include <X11/extensions/xf86vmode.h>
+#include <X11/XF86keysym.h>
+#endif
+
+#ifdef HAVE_XV
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#endif
+
+#include "../input/input.h"
+#include "../input/mouse.h"
+
+#ifdef HAVE_NEW_GUI
+#include "../Gui/interface.h"
+#include "../mplayer.h"
+#endif
+
+#define WIN_LAYER_ONBOTTOM               2
+#define WIN_LAYER_NORMAL                 4
+#define WIN_LAYER_ONTOP                  6
+#define WIN_LAYER_ABOVE_DOCK             10
+ 
+int fs_layer=WIN_LAYER_ABOVE_DOCK;
+static int orig_layer=0;
+
+int stop_xscreensaver=0;
+
+static int dpms_disabled=0;
+static int timeout_save=0;
+static int kdescreensaver_was_running=0;
+
+char* mDisplayName=NULL;
+Window   mRootWin;
+int mScreen;
+int mLocalDisplay;*/
+
+#define WIN_LAYER_ONBOTTOM               2
+#define WIN_LAYER_NORMAL                 4
+#define WIN_LAYER_ONTOP                  6
+#define WIN_LAYER_ABOVE_DOCK             10
+ 
+static int fs_layer=WIN_LAYER_ABOVE_DOCK;
+static int orig_layer=0;
+
+// FIXME: Move to headerfile
+#define vo_wm_LAYER 1
+#define vo_wm_FULLSCREEN 2
+#define vo_wm_STAYS_ON_TOP 4
+#define vo_wm_ABOVE 8
+#define vo_wm_BELOW 16
+#define vo_wm_NETWM (vo_wm_FULLSCREEN | vo_wm_STAYS_ON_TOP | vo_wm_ABOVE | vo_wm_BELOW)
+
+static Display* mDisplay=NULL;
+static Window   mRootWin;
+int mScreen;
+
+static int vo_wm_type = 0;
+static int vo_fs_type = 0;
+static int vo_fsmode = 0; // FIXME: Not used !!!
+static char** vo_fstype_list;
+
+/* if equal to 1 means that WM is a metacity (broken as hell) */
+static int metacity_hack = 0;
+
+static Atom XA_NET_SUPPORTED;
+static Atom XA_NET_WM_STATE;
+static Atom XA_NET_WM_STATE_FULLSCREEN;
+static Atom XA_NET_WM_STATE_ABOVE;
+static Atom XA_NET_WM_STATE_STAYS_ON_TOP;
+static Atom XA_NET_WM_STATE_BELOW;
+static Atom XA_NET_WM_PID;
+static Atom XA_WIN_PROTOCOLS;
+static Atom XA_WIN_LAYER;
+static Atom XA_WIN_HINTS;
+static Atom XA_BLACKBOX_PID;
+
+#define XA_INIT(x) XA##x = XInternAtom(mDisplay, #x, False)
+
+static int vo_x11_keepaspect = 1;
+
+static XSizeHints vo_hint;
+
+static int vo_x11_get_fs_type(int supported);
+
+void fstype_help(void)
+{
+ mp_msg(MSGT_VO, MSGL_INFO, MSGTR_AvailableFsType);
+ 
+ mp_msg(MSGT_VO, MSGL_INFO, "    %-15s %s\n", "none", "don't set fullscreen window layer");
+ mp_msg(MSGT_VO, MSGL_INFO, "    %-15s %s\n", "layer", "use _WIN_LAYER hint with default layer");
+ mp_msg(MSGT_VO, MSGL_INFO, "    %-15s %s\n", "layer=<0..15>", "use _WIN_LAYER hint with a given layer number");
+ mp_msg(MSGT_VO, MSGL_INFO, "    %-15s %s\n", "above", "use _NETWM_STATE_ABOVE hint if available");
+ mp_msg(MSGT_VO, MSGL_INFO, "    %-15s %s\n", "below", "use _NETWM_STATE_BELOW hint if available");
+ mp_msg(MSGT_VO, MSGL_INFO, "    %-15s %s\n", "fullscreen", "use _NETWM_STATE_FULLSCREEN hint if availale");
+ mp_msg(MSGT_VO, MSGL_INFO, "    %-15s %s\n", "stays_on_top", "use _NETWM_STATE_STAYS_ON_TOP hint if available");
+}
+ 
+static int net_wm_support_state_test(Atom atom)
+{
+#define NET_WM_STATE_TEST(x) { if (atom == XA_NET_WM_STATE_##x) { mp_msg( MSGT_VO,MSGL_V, "[x11] Detected wm supports " #x " state.\n" ); return vo_wm_##x; } }
+ 
+ NET_WM_STATE_TEST(FULLSCREEN);
+ NET_WM_STATE_TEST(ABOVE);
+ NET_WM_STATE_TEST(STAYS_ON_TOP);
+ NET_WM_STATE_TEST(BELOW);
+ return 0;
+}
+
+static int x11_get_property(Atom type, Atom **args, unsigned long *nitems)
+{
+  int             format;
+  unsigned long   bytesafter;
+
+  return (Success == XGetWindowProperty( mDisplay,mRootWin,type,0,16384,
+                                         False,AnyPropertyType,&type,&format,nitems,&bytesafter,
+                                         (unsigned char **) args ) && *nitems > 0 );
+}
+
+static int vo_wm_detect(void)
+{
+ int             i;
+ int             wm = 0;
+ unsigned long   nitems;
+ Atom          * args = NULL;
+ 
+// -- supports layers
+  if (x11_get_property(XA_WIN_PROTOCOLS, &args, &nitems))
+  {
+   mp_msg( MSGT_VO,MSGL_V,"[x11] Detected wm supports layers.\n" );
+   for (i = 0; i < nitems; i++)
+   {
+     if ( args[i] == XA_WIN_LAYER) {
+       wm |= vo_wm_LAYER;
+       metacity_hack |= 1;
+     } else
+       // metacity is the only manager I know which reports support only for _WIN_LAYER
+       // hint in _WIN_PROTOCOLS (what's more support for it is broken)
+       metacity_hack |= 2;
+   }
+   XFree( args );
+   if (wm && (metacity_hack == 1))
+   {
+     // metacity reports that it supports layers, but it is not really truth :-)
+     wm ^= vo_wm_LAYER;
+     mp_msg( MSGT_VO,MSGL_V,"[x11] Using workaround for Metacity bugs.\n" );
+   }
+  }
+
+// --- netwm 
+  if (x11_get_property(XA_NET_SUPPORTED, &args, &nitems))
+  {
+   mp_msg( MSGT_VO,MSGL_V,"[x11] Detected wm supports NetWM.\n" );
+   for (i = 0; i < nitems; i++)
+     wm |= net_wm_support_state_test (args[i]);
+   XFree( args );
+   // ugly hack for broken OpenBox _NET_WM_STATE_FULLSCREEN support
+   // (in their implementation it only changes internal state of window, nothing more!!!)
+   if (wm & vo_wm_FULLSCREEN)
+   {
+      if (x11_get_property(XA_BLACKBOX_PID, &args, &nitems))
+	{
+           mp_msg( MSGT_VO,MSGL_V,"[x11] Detected wm is a broken OpenBox.\n" );
+           wm ^= vo_wm_FULLSCREEN;
+	}
+      XFree (args);
+   }
+  }
+
+ if ( wm == 0 ) mp_msg( MSGT_VO,MSGL_V,"[x11] Unknown wm type...\n" );
+ return wm;
+}    
+
+static void init_atoms(void)
+{
+ XA_INIT(_NET_SUPPORTED);
+ XA_INIT(_NET_WM_STATE);
+ XA_INIT(_NET_WM_STATE_FULLSCREEN);
+ XA_INIT(_NET_WM_STATE_ABOVE);
+ XA_INIT(_NET_WM_STATE_STAYS_ON_TOP);
+ XA_INIT(_NET_WM_STATE_BELOW);
+ XA_INIT(_NET_WM_PID);
+ XA_INIT(_WIN_PROTOCOLS);
+ XA_INIT(_WIN_LAYER);
+ XA_INIT(_WIN_HINTS);
+ XA_INIT(_BLACKBOX_PID);
+}
+
+
+// ----- Motif header: -------
+
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define MWM_HINTS_INPUT_MODE    (1L << 2)
+#define MWM_HINTS_STATUS        (1L << 3)
+
+#define MWM_FUNC_ALL            (1L << 0)
+#define MWM_FUNC_RESIZE         (1L << 1)
+#define MWM_FUNC_MOVE           (1L << 2)
+#define MWM_FUNC_MINIMIZE       (1L << 3)
+#define MWM_FUNC_MAXIMIZE       (1L << 4)
+#define MWM_FUNC_CLOSE          (1L << 5)
+
+#define MWM_DECOR_ALL           (1L << 0)
+#define MWM_DECOR_BORDER        (1L << 1)
+#define MWM_DECOR_RESIZEH       (1L << 2)
+#define MWM_DECOR_TITLE         (1L << 3)
+#define MWM_DECOR_MENU          (1L << 4)
+#define MWM_DECOR_MINIMIZE      (1L << 5)
+#define MWM_DECOR_MAXIMIZE      (1L << 6)
+
+#define MWM_INPUT_MODELESS 0
+#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
+#define MWM_INPUT_SYSTEM_MODAL 2
+#define MWM_INPUT_FULL_APPLICATION_MODAL 3
+#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL
+
+#define MWM_TEAROFF_WINDOW      (1L<<0)
+
+typedef struct
+{
+  long flags;
+  long functions;
+  long decorations;
+  long input_mode;
+  long state;
+} MotifWmHints;
+
+extern MotifWmHints vo_MotifWmHints;
+extern Atom         vo_MotifHints;
+extern int          vo_depthonscreen;
+extern int          vo_screenwidth;
+extern int          vo_screenheight;
+
+static MotifWmHints   vo_MotifWmHints;
+static Atom           vo_MotifHints  = None;
+
+// Note: always d==0 !
+void vo_x11_decoration( Display * vo_Display,Window w,int d )
+{
+
+  if(vo_fsmode&1){
+    XSetWindowAttributes attr;
+    attr.override_redirect = (!d) ? True : False;
+    XChangeWindowAttributes(vo_Display, w, CWOverrideRedirect, &attr);
+//    XMapWindow(vo_Display, w);
+  }
+
+  if(vo_fsmode&8){
+    XSetTransientForHint (vo_Display, w, mRootWin);
+  }
+
+ vo_MotifHints=XInternAtom( vo_Display,"_MOTIF_WM_HINTS",0 );
+ if ( vo_MotifHints != None )
+  {
+   memset( &vo_MotifWmHints,0,sizeof( MotifWmHints ) );
+   vo_MotifWmHints.flags=MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
+   if ( d )
+    {
+     vo_MotifWmHints.functions=MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE;
+     d=MWM_DECOR_ALL;
+    }
+#if 0
+   vo_MotifWmHints.decorations=d|((vo_fsmode&2)?0:MWM_DECOR_MENU);
+#else
+   vo_MotifWmHints.decorations=d|((vo_fsmode&2)?MWM_DECOR_MENU:0);
+#endif
+   XChangeProperty( vo_Display,w,vo_MotifHints,vo_MotifHints,32,
+                    PropModeReplace,(unsigned char *)&vo_MotifWmHints,(vo_fsmode&4)?4:5 );
+  }
+}
+
+static int vo_x11_get_gnome_layer(Display * mDisplay, Window win)
+{
+ Atom type;
+ int format;
+ unsigned long nitems;
+ unsigned long bytesafter;
+ unsigned short *args = NULL;
+
+ if (XGetWindowProperty (mDisplay, win, XA_WIN_LAYER, 0, 16384,
+                         False, AnyPropertyType, &type, &format, &nitems,
+                         &bytesafter, (unsigned char **) &args) == Success
+     && nitems > 0 && args)
+ {
+    mp_msg (MSGT_VO, MSGL_V, "[x11] original window layer is %d.\n", *args);
+    return *args;
+ }
+ return WIN_LAYER_NORMAL;
+}
+
+void vo_x11_setlayer( Display * mDisplay,Window vo_window,int layer )
+{
+ if ( vo_fs_type & vo_wm_LAYER )
+  {
+    XClientMessageEvent xev;
+    
+    if (!orig_layer) orig_layer=vo_x11_get_gnome_layer( mDisplay, vo_window );
+
+    memset(&xev, 0, sizeof(xev));
+    xev.type = ClientMessage;
+    xev.display= mDisplay;
+    xev.window = vo_window;
+    xev.message_type = XA_WIN_LAYER;
+    xev.format = 32;
+    xev.data.l[0] = layer?fs_layer:orig_layer; // if not fullscreen, stay on default layer
+    xev.data.l[1] = CurrentTime;
+    mp_msg( MSGT_VO,MSGL_V,"[x11] Layered style stay on top (layer %d).\n",xev.data.l[0] );
+    XSendEvent(mDisplay, mRootWin, False, SubstructureNotifyMask, (XEvent *) &xev);
+  } else
+ if ( vo_fs_type & vo_wm_NETWM )
+ {
+   XClientMessageEvent  xev;
+   char *state;
+
+   memset( &xev,0,sizeof( xev ) );
+   xev.type=ClientMessage;
+   xev.message_type=XA_NET_WM_STATE;
+   xev.display=mDisplay;
+   xev.window=vo_window;
+   xev.format=32;
+   xev.data.l[0]=layer;
+   
+   if ( vo_fs_type & vo_wm_STAYS_ON_TOP )
+     xev.data.l[1]=XA_NET_WM_STATE_STAYS_ON_TOP;
+   else
+   if ( vo_fs_type & vo_wm_ABOVE )
+     xev.data.l[1]=XA_NET_WM_STATE_ABOVE;
+   else
+   if ( vo_fs_type & vo_wm_FULLSCREEN )
+     xev.data.l[1]=XA_NET_WM_STATE_FULLSCREEN;
+   else
+   if ( vo_fs_type & vo_wm_BELOW )
+     // This is not fallback. We can safely assume that situation where
+     // only NETWM_STATE_BELOW is supported and others not, doesn't exist.
+     xev.data.l[1]=XA_NET_WM_STATE_BELOW;
+
+   XSendEvent( mDisplay,mRootWin,False,SubstructureRedirectMask,(XEvent*)&xev );
+   state = XGetAtomName (mDisplay, xev.data.l[1]);
+   mp_msg( MSGT_VO,MSGL_V,"[x11] NET style stay on top (layer %d). Using state %s.\n",layer,state );
+   XFree (state);
+ }
+}
+
+static int vo_x11_get_fs_type(int supported)
+{
+  int i;
+  int type;
+  
+  if (vo_fstype_list) {
+    i = 0;
+    for (i = 0; vo_fstype_list[i]; i++)
+    {
+      type = supported;
+
+      if (strncmp(vo_fstype_list[i], "layer", 5) == 0)
+      {
+        if (vo_fstype_list[i][5] == '=')
+        {
+          char *endptr = NULL;
+          int layer = strtol(vo_fstype_list[i]+6, &endptr, 10);
+            
+          if (endptr && *endptr == '\0' && layer >= 0 && layer <= 15) 
+            fs_layer = layer;
+        }
+        type &= vo_wm_LAYER;
+      }
+      else if (strcmp(vo_fstype_list[i], "above") == 0) type &= vo_wm_ABOVE;
+      else if (strcmp(vo_fstype_list[i], "fullscreen") == 0) type &= vo_wm_FULLSCREEN;
+      else if (strcmp(vo_fstype_list[i], "stays_on_top") == 0) type &= vo_wm_STAYS_ON_TOP;
+      else if (strcmp(vo_fstype_list[i], "below") == 0) type &= vo_wm_BELOW;
+      else if (strcmp(vo_fstype_list[i], "none") == 0) return 0;
+      else type = 0;
+      
+      if (type)
+        return type;
+    }
+  }
+
+  return supported;
+}
+
+void vo_x11_sizehint( int x, int y, int width, int height, int max, Window vo_window )
+{
+ vo_hint.flags=PPosition | PSize | PWinGravity;
+ if(vo_x11_keepaspect)
+ {
+ 	vo_hint.flags |= PAspect;
+	vo_hint.min_aspect.x = width;
+	vo_hint.min_aspect.y = height;
+	vo_hint.max_aspect.x = width;
+	vo_hint.max_aspect.y = height;
+  }
+
+ vo_hint.x=x; vo_hint.y=y; vo_hint.width=width; vo_hint.height=height;
+ if ( max )
+  {
+   vo_hint.max_width=width; vo_hint.max_height=height;
+   vo_hint.flags|=PMaxSize;
+  } else { vo_hint.max_width=0; vo_hint.max_height=0; }
+ vo_hint.win_gravity=StaticGravity;
+ XSetWMNormalHints( mDisplay,vo_window,&vo_hint );
+}
+
+
+// API
+//
+//
+static int inited = 0;
+
+void vo_x11_fs_init(Display* tDisplay, int tScreen, Window tRootWin)
+{
+ mDisplay=tDisplay;
+ mRootWin=tRootWin;
+ mScreen=tScreen;
+ init_atoms();
+ 
+ vo_wm_type=vo_wm_detect();
+
+ vo_fs_type=vo_x11_get_fs_type(vo_wm_type);
+ 
+ inited=1;
+}
+
+void vo_x11_fs(Window vo_window, int vo_fs, int x, int y, int w, int h)
+{
+  if (!inited) return;
+  vo_x11_decoration( mDisplay, vo_window,(vo_fs) ? 0 : 1 );
+  vo_x11_sizehint( x,y,w,h,0, vo_window );
+  vo_x11_setlayer( mDisplay,vo_window,vo_fs );
+  XMoveResizeWindow( mDisplay,vo_window,x,y,w,h );
+  if(vo_wm_type==0 && !(vo_fsmode&16))
+    XUnmapWindow( mDisplay,vo_window );  // required for MWM
+  XWithdrawWindow(mDisplay,vo_window,mScreen);
+  XMapRaised( mDisplay,vo_window );
+  XRaiseWindow( mDisplay,vo_window );
+  XFlush( mDisplay );
+}
diff -Nur g2.old/libvo2/x11_helper.c g2/libvo2/x11_helper.c
--- g2.old/libvo2/x11_helper.c	2003-07-19 02:11:58.000000000 +0200
+++ g2/libvo2/x11_helper.c	2003-08-17 16:57:08.000000000 +0200
@@ -35,8 +35,8 @@
 #endif
 
 static int vo_depthonscreen=0;
-static int vo_screenwidth=0;
-static int vo_screenheight=0;
+int vo_screenwidth=0;
+int vo_screenheight=0;
 
 static char* mDisplayName=NULL;
 static Display* mDisplay=NULL;
@@ -145,6 +145,7 @@
   }
  mScreen=DefaultScreen( mDisplay );     // Screen ID.
  mRootWin=RootWindow( mDisplay,mScreen );// Root window ID.
+ vo_x11_fs_init(mDisplay, mScreen, mRootWin);
 
 #ifdef HAVE_XF86VM
  {
@@ -410,6 +411,8 @@
             XLookupString( &Event.xkey,buf,sizeof(buf),&keySym,&stat );
 	    key=vo_x11_convert_keysym(keySym);
 	    if(key) vo->event_callback(vo,VO_EVENT_KEYPRESS,0,key,0);
+	    //if(key=='f') 
+	//	vo->event_callback(vo,VO_EVENT_FULLSCREEN,0,key,0);
 	   }
            break;
       case MotionNotify:
@@ -441,8 +444,12 @@
   }
 }
 
+static Window vo_fullscreen_window=None;
+static Window vo_backup_window=None;
+
 static void vo_x11_event_callback(struct vo_instance_s* vo,
         int type, unsigned int flags, int x, int y){
+    int fs=0;
     switch(type){
     case VO_EVENT_CONFIG:
 	// this event is generated by vf_vo2.c
@@ -454,6 +461,39 @@
 	    vo->control(vo,VOCTRL_SET_WINDOW,&vo_window);
 	}
 	break;
+    case VO_EVENT_FULLSCREEN:
+     if (vo_backup_window==None)
+      {
+        vo_backup_window=vo_window;
+	if (vo_fullscreen_window==None)
+        {
+	  vo_window=None;
+	  //vo->event_callback(vo,VO_EVENT_CONFIG,0,vo_screenwidth,vo_screenheight);
+	  vo_window=vo_x11_create_window(vo_screenwidth,vo_screenheight);
+          vo_fullscreen_window=vo_window;
+        }
+	else
+	  vo_window=vo_fullscreen_window;
+	//XMapWindow(mDisplay, vo_fullscreen_window);
+	XUnmapWindow(mDisplay, vo_backup_window);
+	fs=1;
+        vo_x11_fs(vo_fullscreen_window, 1, 0, 0, vo_screenwidth, vo_screenheight);
+	XMapWindow(mDisplay, vo_fullscreen_window);
+      }
+      else
+      {
+        vo_window=vo_backup_window;
+	vo_backup_window=None;
+        //vo_x11_fs(vo_fullscreen_window, 0, 0, 0, vo_screenwidth, vo_screenheight);
+	XUnmapWindow(mDisplay, vo_fullscreen_window);
+	XMapWindow(mDisplay, vo_window);
+	fs=0;
+      }
+      vo_x11_selectinput_witherr( mDisplay,vo_window,StructureNotifyMask | KeyPressMask | PropertyChangeMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask );
+      mp_msg(MSGT_CPLAYER,MSGL_V,"vo: switched fullscreen: %s\n",fs?"on":"off");
+      vo->control(vo,VOCTRL_SET_WINDOW,&vo_window);
+      vo->control(vo,VOCTRL_FULLSCREEN,&fs);
+      break;
     // events generated by vo_x11_check_events():
     case VO_EVENT_EXPOSE:
     case VO_EVENT_MOVE: {
--- g2.old/test-play.c	2003-08-09 20:15:47.000000000 +0200
+++ g2/test-play.c	2003-08-17 15:52:44.000000000 +0200
@@ -646,6 +646,8 @@
 		mpi=NULL; // drop waiting frame, must be outdated already
 		time_pos=0; // reset wall-clock timer
 	    }
+	    else if (cmd->id==MP_CMD_VO_FULLSCREEN)
+		video_out->event_callback(video_out,VO_EVENT_FULLSCREEN,0,0,0);
 	    mp_cmd_free(cmd);
 	}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.