[PATCH] Fullscreen issues - g2 is great :-)
Fabian Franz <[email protected]>
| Newsgroups | gmane.comp.video.mplayer.g2.devel |
|---|---|
| Message-ID | <[email protected]> |
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, I wanted to gain some experience in the field of fullscreen :-). (And g1 was sooooooooo slow in compiling that it was a pain to develop in it :)) ) So I started with g2 and it was astounishingly easy ... :) I create a second window on the fly if fullscreen, which I hacked in as I couldn't find the function, where events are parsed, is selected ... This window still needs to be removed of any decorations and so on, but one can guess what it will look like ... For that I had to "port" the aspect-code (copy & paste, and comment something out) ... That however gives some questions: - - Are two static variables that are global ok for the fullscreen and backup-window ? (only x11_helper.c affected) - - How can vo_xv, vo_x11 give the aspect code the correct screensize (vo_screenwidth, vo_screenheight) if it does not know about it ... -> The same goes for centering the picture (btw. I think this should go to aspect.c as it always the same and aspect.c renamed to helper or tools or similar ...) Of course, x11_helper.c could include aspect.h and set the aspect, when it knows about screenwidth, screenheight, but this gives the problems that gui-programmers NEED to do the same ... Which is bad, as they could get undesired behaviour and for fullscreen and don't know why ... Also for fullscreen I'm not satisfied with this code in x11_helper.c, as perhaps it would be nice to have this functions available for gui, but I dunno ... Should guis also use the helper-code ? I added screenwidth,height as global (I know its ugly) variables for now ... - - vo_x11 is always fullscreened to the widht, height, the window had ... Why is the RESIZE_CODE uncommented, it would be easier if it was handled that way ... In fullscreen resize-commands are ignored ... :) Btw. thanks for adding fullscreen flag to vo_instance_s :)). - - zoom parameter not yet accepted by vo_x11 (as there is no wide-used config layer yet ) So, I really like the new clean design ... Its really nice, with alle the events and callbacks handled nice and allowing finally to communicate with vo->layer :). cu Fabian -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.0 (GNU/Linux) iD8DBQE/P3SbI0lSH7CXz7MRAl8CAJ9dBZJgEewnP/LXo3AdF68diknc1QCeNUp4 lmFJGfXKw+MGEaSOUabvSNM= =D0Nb -----END PGP SIGNATURE----- _______________________________________________ MPlayer-G2-dev mailing list [email protected] http://mplayerhq.hu/mailman/listinfo/mplayer-g2-dev
g2-fs.diff
(text/x-diff, 12.4 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-16 12:16:35.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 # 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:12:18.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*)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:12:40.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; // FIXME!!!!
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*)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_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 14:07:42.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;
@@ -410,6 +410,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 +443,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 +460,37 @@
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_fullscreen_window=vo_window;
+ //FIXME: Add removing of decorations, moving to top layer
+ }
+ else
+ vo_window=vo_fullscreen_window;
+ XMapWindow(mDisplay, vo_fullscreen_window);
+ XUnmapWindow(mDisplay, vo_backup_window);
+ fs=1;
+ }
+ else
+ {
+ vo_window=vo_backup_window;
+ vo_backup_window=None;
+ 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: {