Re: [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 Am Montag, 18. August 2003 00:35 schrieb Fabian Franz: Updated version attached. Design still sucks, but fs is now always nice to use ... :) It seems that the Fullscreen window mustn't be visible, before its configured ... cu Fabian > 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/QA9bI0lSH7CXz7MRAqVlAJ9716lugGT1ubuIw1ilu5StHo1ZowCfdJXC uSPVseZbLInELn06cagerBs= =OZj3 -----END PGP SIGNATURE----- _______________________________________________ MPlayer-G2-dev mailing list [email protected] http://mplayerhq.hu/mailman/listinfo/mplayer-g2-dev
g2-fs_v2.diff
(text/x-diff, 27.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-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-18 01:20:12.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
{
@@ -215,7 +216,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 +249,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;
}
@@ -410,6 +412,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,19 +445,56 @@
}
}
+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
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);
}
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,0);
+ 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);
}