[PATCH][TESTSUITE2] fullscreen again ...

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

Hi,

much cleaner, but not clean anough for A'rpi. ;)

Still I don't understand the architecture enough, to change it accordingly ...

So for now aspect-code is in x11_helper.c.

However there are just 3 new global static vars... (and they _are_ needed) and 
2 new EVENTS  - FULLSCREEN & MOVIE, where the last sets the MOVIE-aspect, as 
I could not get this from vf_vo2 in any other way ...

I can't see how to include aspect nicely with vf_layer from x11_helpers point 
of view ...

Also you say, vo should not handle fullscreen directly and so on, but it has 
flags for vm, zoom, fs and flip ?!

That seems to me a bit confusing ...

cu

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

iD8DBQE/QrfyI0lSH7CXz7MRAs0hAJ4kk9GIBlXPAPyyrc/gOMpbHUoN9gCfQENP
AROVD2Ilxz612q1uT2iliKg=
=Qtwm
-----END PGP SIGNATURE-----

_______________________________________________
MPlayer-G2-dev mailing list
[email protected]
http://mplayerhq.hu/mailman/listinfo/mplayer-g2-dev
g2-fs_v3.diff (text/x-diff, 25.7 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-20 01:25:29.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-20 00:43:42.000000000 +0200
@@ -46,6 +46,8 @@
 #define VO_EVENT_MOVE 4
 #define VO_EVENT_EXPOSE 5
 #define VO_EVENT_CONFIG 6
+#define VO_EVENT_FULLSCREEN 7
+#define VO_EVENT_MOVIE 8
 
 // 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-20 00:47:26.000000000 +0200
@@ -45,13 +45,13 @@
 	    vo->priv->gc = XCreateGC(vo->priv->dpy, vo->priv->win, 0L, &vo->priv->xgcv);
 	}
 	return VO_TRUE;
-#if 0
+#if 1
     case VOCTRL_RESIZE_DEST:
 	if( ((int*)data)[0] >= 0 ) vo->x=((int*)data)[0];
 	if( ((int*)data)[1] >= 0 ) vo->y=((int*)data)[1];
 	if( ((int*)data)[2] > 0 ) vo->w=((int*)data)[2];
 	if( ((int*)data)[3] > 0 ) vo->h=((int*)data)[3];
-	mp_msg(MSGT_VO,MSGL_V,"vo_xv: control RESIZE_DEST: %d;%d %dx%d  \n",vo->x,vo->y,vo->w,vo->h);
+	mp_msg(MSGT_VO,MSGL_V,"vo_x11: control RESIZE_DEST: %d;%d %dx%d  \n",vo->x,vo->y,vo->w,vo->h);
 	return VO_FALSE;
 #endif
     }
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-20 01:27:55.000000000 +0200
@@ -21,6 +21,7 @@
 #include "mp_msg.h"
 #include "help_mp.h"
 #include "video_out.h"
+#include "aspect.h"
 
 // for mouse/key events:
 #include "input/input.h"
@@ -37,6 +38,7 @@
 static int vo_depthonscreen=0;
 static int vo_screenwidth=0;
 static int vo_screenheight=0;
+static int vo_fs=0;
 
 static char* mDisplayName=NULL;
 static Display* mDisplay=NULL;
@@ -145,6 +147,7 @@
   }
  mScreen=DefaultScreen( mDisplay );     // Screen ID.
  mRootWin=RootWindow( mDisplay,mScreen );// Root window ID.
+ vo_x11_fs_init(mDisplay, mScreen, mRootWin);
 
 #ifdef HAVE_XF86VM
  {
@@ -215,7 +218,7 @@
  return 1;
 }
 
-static Window vo_x11_create_window(int w,int h){
+static Window vo_x11_create_window(int w,int h, int flag_display){
     Window vo_window=-1;
     XSizeHints hint;
     XVisualInfo vinfo;
@@ -248,7 +251,8 @@
 
 //    XSetStandardProperties(mDisplay, vo_window, hello, hello, None, NULL, 0, &hint);
     XSetWMNormalHints( mDisplay,vo_window,&hint );
-    XMapWindow(mDisplay, vo_window);
+    if (flag_display)
+      XMapWindow(mDisplay, vo_window);
     return vo_window;
 }
 
@@ -365,6 +369,8 @@
 }
 
 static Window vo_window=None;
+static Window vo_fullscreen_window=None;
+static Window vo_backup_window=None;
 
 static void vo_x11_check_event(struct vo_instance_s* vo){
  XEvent         Event;
@@ -388,6 +394,8 @@
 //	   if (!vo_fs && (Event.xconfigure.width == vo_screenwidth || Event.xconfigure.height == vo_screenheight)) break;
 //	   if (vo_fs && Event.xconfigure.width != vo_screenwidth && Event.xconfigure.height != vo_screenheight) break;
            if ( vo_window == None ) break;
+	   if (!vo_fs)
+	   {
 	   if(vo_dwidth!=Event.xconfigure.width || vo_dheight!=Event.xconfigure.height){
         	vo_dwidth=Event.xconfigure.width;
         	vo_dheight=Event.xconfigure.height;
@@ -403,6 +411,7 @@
 		&vo_dx, &vo_dy, &win);
 	   }
     	   vo->event_callback(vo,VO_EVENT_MOVE,0,vo_dx,vo_dy);
+	   }
            break;
       case KeyPress:
            { 
@@ -448,12 +457,67 @@
 	// this event is generated by vf_vo2.c
 	mp_msg(MSGT_CPLAYER,MSGL_V,"vo-event: configured to %d x %d\n",x,y);
 	if(vo_window==None){
-	    vo_window=vo_x11_create_window(x,y);
+	    vo_window=vo_x11_create_window(x,y,1);
 	    vo_x11_selectinput_witherr( mDisplay,vo_window,StructureNotifyMask | KeyPressMask | PropertyChangeMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask );
 	    mp_msg(MSGT_CPLAYER,MSGL_V,"vo: window created: %d\n",vo_window);
 	    vo->control(vo,VOCTRL_SET_WINDOW,&vo_window);
+	    aspect_save_prescale(x,y);
+	    aspect_save_screenres(vo_screenwidth, vo_screenheight);
 	}
 	break;
+    case VO_EVENT_MOVIE:
+	aspect_save_orig(x,y);
+	break;
+    case VO_EVENT_FULLSCREEN:
+     if (!vo_fs)
+      {
+        vo_backup_window=vo_window;
+	if (vo_fullscreen_window==None)
+	{
+	  vo_fullscreen_window=vo_x11_create_window(vo_screenwidth,vo_screenheight,0);
+          vo_x11_fs(vo_fullscreen_window, 1, 0, 0, vo_screenwidth, vo_screenheight);
+	}
+	vo_window=vo_fullscreen_window;
+	XUnmapWindow(mDisplay, vo_backup_window);
+	XMapWindow(mDisplay, vo_fullscreen_window);
+      }
+      else
+      {
+        vo_window=vo_backup_window;
+	vo_backup_window=None;
+	XUnmapWindow(mDisplay, vo_fullscreen_window);
+	XMapWindow(mDisplay, vo_window);
+      }
+      vo_fs=(vo_fs)?0:1;
+      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",vo_fs?"on":"off");
+      vo->control(vo,VOCTRL_SET_WINDOW,&vo_window);
+      if (vo_fs)
+      {
+        int tmp[4];
+        int vo_dx, vo_dy, vo_dwidth, vo_dheight;
+        vo_dwidth=vo_screenwidth;
+        vo_dheight=vo_screenheight;
+        aspect(&vo_dwidth,&vo_dheight, A_ZOOM); // FIXME: How to find out if a VO supports HWSCALE or user used -zoom ?
+        vo_dx=( vo_screenwidth - (vo_dwidth > vo_screenwidth?vo_screenwidth:vo_dwidth) ) / 2;
+        vo_dy=( vo_screenheight - (vo_dheight > vo_screenheight?vo_screenheight:vo_dheight) ) / 2;
+        vo_dwidth=(vo_dwidth > vo_screenwidth?vo_screenwidth:vo_dwidth);
+        vo_dheight=(vo_dheight > vo_screenheight?vo_screenheight:vo_dheight);
+        tmp[0]=vo_dx;
+        tmp[1]=vo_dy;
+        tmp[2]=tmp[3]=-1;
+        vo->control(vo,VOCTRL_RESIZE_DEST,tmp);
+        vo->event_callback(vo,VO_EVENT_RESIZE,0,vo_dwidth,vo_dheight);
+      }
+      else
+      {
+        int tmp[4];
+	tmp[0]=0;
+	tmp[1]=0;
+	tmp[2]=tmp[3]=-1;
+        vo->control(vo,VOCTRL_RESIZE_DEST,tmp);
+      }
+      break;
     // events generated by vo_x11_check_events():
     case VO_EVENT_EXPOSE:
     case VO_EVENT_MOVE: {
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.