From 908e6a761d276dc98fac7e2340bd67ff66dff235 Mon Sep 17 00:00:00 2001 From: mosu Date: Sun, 31 Aug 2003 22:27:10 +0000 Subject: Avoid flickering during resizes. Keep video contents even when paused. Fix by Tomas Simonaitis git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@10758 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libvo/vo_gl.c | 22 ++++++++++--------- libvo/vo_gl2.c | 25 +++++++++++----------- libvo/vo_x11.c | 29 ++++++++++++++++--------- libvo/vo_xv.c | 38 +++++++++++++++------------------ libvo/x11_common.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 53 deletions(-) (limited to 'libvo') diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c index 6b3d86e33a..4cd9bf2943 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -47,6 +47,8 @@ static uint32_t image_width; static uint32_t image_height; static uint32_t image_bytes; +static int int_pause; + static uint32_t texture_width; static uint32_t texture_height; @@ -77,12 +79,12 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin XEvent xev; // XGCValues xgcv; - XSetWindowAttributes xswa; - unsigned long xswamask; image_height = height; image_width = width; - + + int_pause = 0; + aspect_save_orig(width,height); aspect_save_prescale(d_width,d_height); aspect_save_screenres(vo_screenwidth,vo_screenheight); @@ -113,15 +115,12 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin return -1; } - xswa.background_pixel = 0; - xswa.border_pixel = 1; - xswa.colormap = XCreateColormap(mDisplay, mRootWin, vinfo->visual, AllocNone); - xswamask = CWBackPixel | CWBorderPixel | CWColormap; + if ( vo_window == None ) { - vo_window = XCreateWindow(mDisplay, mRootWin, - hint.x, hint.y, hint.width, hint.height, 4, vinfo->depth,CopyFromParent,vinfo->visual,xswamask,&xswa); + vo_window = vo_x11_create_smooth_window(mDisplay, mRootWin, vinfo->visual, hint.x, hint.y, hint.width, hint.height, + vinfo->depth, XCreateColormap(mDisplay, mRootWin, vinfo->visual, AllocNone)); vo_x11_classhint( mDisplay,vo_window,"gl" ); vo_hidecursor(mDisplay,vo_window); @@ -155,7 +154,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin XSync(mDisplay, False); vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PointerMotionMask - | ButtonPressMask | ButtonReleaseMask + | ButtonPressMask | ButtonReleaseMask | ExposureMask ); texture_width=32; @@ -213,6 +212,7 @@ static void check_events(void) { int e=vo_x11_check_events(mDisplay); if(e&VO_EVENT_RESIZE) resize(vo_dwidth,vo_dheight); + if(e&VO_EVENT_EXPOSE && int_pause) flip_page(); } static void draw_osd(void) @@ -308,6 +308,8 @@ static uint32_t preinit(const char *arg) static uint32_t control(uint32_t request, void *data, ...) { switch (request) { + case VOCTRL_PAUSE: return (int_pause=1); + case VOCTRL_RESUME: return (int_pause=0); case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_FULLSCREEN: diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c index f2e0d66cf6..0b173850fd 100644 --- a/libvo/vo_gl2.c +++ b/libvo/vo_gl2.c @@ -64,6 +64,8 @@ static uint32_t image_bpp; static int image_mode; static uint32_t image_bytes; +static int int_pause; + static uint32_t texture_width; static uint32_t texture_height; static int texnumx, texnumy, memory_x_len, memory_x_start_offset, raw_line_len; @@ -86,6 +88,7 @@ static int gl_antialias=0; static void (*draw_alpha_fnc) (int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride); + /* The squares that are tiled to make up the game screen polygon */ struct TexSquare @@ -642,14 +645,14 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin XEvent xev; // XGCValues xgcv; - XSetWindowAttributes xswa; - unsigned long xswamask; const unsigned char * glVersion; image_height = height; image_width = width; image_format = format; + + int_pause = 0; aspect_save_orig(width,height); aspect_save_prescale(d_width,d_height); @@ -691,15 +694,10 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin return -1; } - xswa.background_pixel = 0; - xswa.border_pixel = 1; - xswa.colormap = vo_x11_create_colormap(vinfo); - xswamask = CWBackPixel | CWBorderPixel | CWColormap; - if ( vo_window == None ) { - vo_window = XCreateWindow(mDisplay, RootWindow(mDisplay,mScreen), hint.x, hint.y, hint.width, hint.height, 4, vinfo->depth,CopyFromParent,vinfo->visual,xswamask,&xswa); - + vo_window = vo_x11_create_smooth_window(mDisplay, RootWindow(mDisplay,mScreen), + vinfo->visual, hint.x, hint.y, hint.width, hint.height, vinfo->depth, vo_x11_create_colormap(vinfo)); if ( flags&0x01 ) vo_x11_decoration( mDisplay,vo_window,0 ); XSelectInput(mDisplay, vo_window, StructureNotifyMask); @@ -741,7 +739,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin //XSelectInput(mDisplay, vo_window, StructureNotifyMask); // !!!! vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PointerMotionMask - | ButtonPressMask | ButtonReleaseMask + | ButtonPressMask | ButtonReleaseMask | ExposureMask ); glVersion = glGetString(GL_VERSION); @@ -965,7 +963,7 @@ static void check_events(void) int key; static XComposeStatus stat; int e; - + while ( XPending( mDisplay ) ) { XNextEvent( mDisplay,&Event ); @@ -983,8 +981,9 @@ static void check_events(void) break; } } - e=vo_x11_check_events(mDisplay); + e=vo_x11_check_events(mDisplay); if(e&VO_EVENT_RESIZE) resize(vo_dwidth,vo_dheight); + if(e&VO_EVENT_EXPOSE && int_pause) flip_page(); } static void draw_osd(void) @@ -1079,6 +1078,8 @@ static uint32_t preinit(const char *arg) static uint32_t control(uint32_t request, void *data, ...) { switch (request) { + case VOCTRL_PAUSE: return (int_pause=1); + case VOCTRL_RESUME: return (int_pause=0); case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_FULLSCREEN: diff --git a/libvo/vo_x11.c b/libvo/vo_x11.c index 3e827dac14..4207c57fdf 100644 --- a/libvo/vo_x11.c +++ b/libvo/vo_x11.c @@ -56,6 +56,8 @@ static XImage *myximage = NULL; static int depth,bpp,mode; static XWindowAttributes attribs; +static int int_pause; + static int Flip_Flag; static int zoomFlag; @@ -88,12 +90,15 @@ static int old_vo_dheight=-1; static void check_events(){ int ret = vo_x11_check_events(mDisplay); - /* clear the old window */ - if ( (ret & VO_EVENT_RESIZE)||(ret & VO_EVENT_EXPOSE) ) + /* clear left over borders and redraw frame if we are paused */ + if ( ret & VO_EVENT_EXPOSE && int_pause) { - XSetBackground(mDisplay, vo_gc, 0); - XClearWindow(mDisplay, vo_window); - } + vo_x11_clearwindow_part(mDisplay, vo_window, myximage->width, myximage->height, 0); + flip_page(); + } else + if ( (ret & VO_EVENT_RESIZE)||(ret & VO_EVENT_EXPOSE) ) + vo_x11_clearwindow_part(mDisplay, vo_window, myximage->width, myximage->height, 0); + } static void draw_alpha_32(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ @@ -252,6 +257,8 @@ static uint32_t config( uint32_t width,uint32_t height,uint32_t d_width,uint32_t if( flags&0x02 ) vm = 1; if( flags&0x08 ) Flip_Flag = 1; zoomFlag = flags&0x04; + + int_pause = 0; // if(!fullscreen) zoomFlag=1; //it makes no sense to avoid zooming on windowd mode //printf( "w: %d h: %d\n\n",vo_dwidth,vo_dheight ); @@ -326,10 +333,7 @@ static uint32_t config( uint32_t width,uint32_t height,uint32_t d_width,uint32_t { if ( vo_window == None ) { - vo_window=XCreateWindow( mDisplay,mRootWin, - vo_dx,vo_dy, - vo_dwidth,vo_dheight, - xswa.border_pixel,depth,CopyFromParent,vinfo.visual,xswamask,&xswa ); + vo_window=vo_x11_create_smooth_window( mDisplay,mRootWin,vinfo.visual, vo_dx, vo_dy, vo_dwidth, vo_dheight, depth, theCmap ); vo_x11_classhint( mDisplay,vo_window,"x11" ); vo_hidecursor(mDisplay,vo_window); @@ -627,6 +631,8 @@ static uint32_t preinit(const char *arg) static uint32_t control(uint32_t request, void *data, ...) { switch (request) { + case VOCTRL_PAUSE: return (int_pause=1); + case VOCTRL_RESUME: return (int_pause=0); case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_GUISUPPORT: @@ -652,7 +658,10 @@ static uint32_t control(uint32_t request, void *data, ...) return vo_x11_get_equalizer(data, value); } case VOCTRL_FULLSCREEN: - vo_x11_fullscreen(); + { + vo_x11_fullscreen(); + vo_x11_clearwindow(mDisplay, vo_window); + } return VO_TRUE; } return VO_NOTIMPL; diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c index 2c05e67895..f1b9c2a4f7 100644 --- a/libvo/vo_xv.c +++ b/libvo/vo_xv.c @@ -81,6 +81,8 @@ static uint32_t image_height; static uint32_t image_format; static int flip_flag; +static int int_pause; + static Window mRoot; static uint32_t drwX,drwY,drwBorderWidth,drwDepth; static uint32_t dwidth,dheight; @@ -148,6 +150,8 @@ static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width, uint32 vo_mouse_autohide=1; + int_pause=0; + vo_dx=( vo_screenwidth - d_width ) / 2; vo_dy=( vo_screenheight - d_height ) / 2; geometry(&vo_dx, &vo_dy, &d_width, &d_height, vo_screenwidth, vo_screenheight); vo_dwidth=d_width; vo_dheight=d_height; @@ -233,16 +237,14 @@ static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width, uint32 } else { drwX=vo_dx; drwY=vo_dy; } } else if ( vo_window == None ){ - vo_window = XCreateWindow(mDisplay, mRootWin, - hint.x, hint.y, hint.width, hint.height, - 0, depth,CopyFromParent,vinfo.visual,xswamask,&xswa); + vo_window = vo_x11_create_smooth_window(mDisplay, mRootWin, vinfo.visual, hint.x, hint.y, hint.width, hint.height, depth, CopyFromParent); vo_x11_classhint( mDisplay,vo_window,"xv" ); vo_hidecursor(mDisplay,vo_window); vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PropertyChangeMask | ((WinID==0) ? 0 : (PointerMotionMask - | ButtonPressMask | ButtonReleaseMask + | ButtonPressMask | ButtonReleaseMask | ExposureMask ))); XSetStandardProperties(mDisplay, vo_window, hello, hello, None, NULL, 0, &hint); XSetWMNormalHints( mDisplay,vo_window,&hint ); @@ -401,6 +403,10 @@ static void deallocate_xvimage(int foo) static void check_events(void) { int e=vo_x11_check_events(mDisplay); + + if (e&VO_EVENT_EXPOSE && vo_fs) + vo_x11_clearwindow(mDisplay, vo_window); + if(e&VO_EVENT_RESIZE) { if (vo_fs) { @@ -424,21 +430,9 @@ static void check_events(void) mp_msg(MSGT_VO,MSGL_V, "[xv-fs] dx: %d dy: %d dw: %d dh: %d\n",drwX,drwY,vo_dwidth,vo_dheight ); } } - if ( e & VO_EVENT_EXPOSE ) - { -#ifdef HAVE_SHM - if ( Shmem_Flag ) - { - XvShmPutImage(mDisplay, xv_port, vo_window, vo_gc, xvimage[current_buf], 0, 0, image_width, image_height, drwX, drwY, 1, 1, False); - XvShmPutImage(mDisplay, xv_port, vo_window, vo_gc, xvimage[current_buf], 0, 0, image_width, image_height, drwX,drwY,vo_dwidth,(vo_fs?vo_dheight - 1:vo_dheight), False); - } - else -#endif - { - XvPutImage(mDisplay, xv_port, vo_window, vo_gc, xvimage[current_buf], 0, 0, image_width, image_height, drwX, drwY, 1, 1); - XvPutImage(mDisplay, xv_port, vo_window, vo_gc, xvimage[current_buf], 0, 0, image_width, image_height, drwX,drwY,vo_dwidth,(vo_fs?vo_dheight - 1:vo_dheight)); - } - } + + if ( (e&VO_EVENT_EXPOSE || e&VO_EVENT_RESIZE) && int_pause) + flip_page(); } static void draw_osd(void) @@ -666,6 +660,8 @@ static uint32_t preinit(const char *arg) static uint32_t control(uint32_t request, void *data, ...) { switch (request) { + case VOCTRL_PAUSE: return (int_pause=1); + case VOCTRL_RESUME: return (int_pause=0); case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_GET_IMAGE: @@ -688,8 +684,8 @@ static uint32_t control(uint32_t request, void *data, ...) if(old_y != vo_panscan_y) { - XClearWindow(mDisplay, vo_window); - XFlush(mDisplay); + vo_x11_clearwindow_part(mDisplay, vo_window, vo_dwidth+vo_panscan_x-1, vo_dheight+vo_panscan_y-1, 1); + flip_page(); } } return VO_TRUE; diff --git a/libvo/x11_common.c b/libvo/x11_common.c index ce5005fc91..d885e77e6d 100644 --- a/libvo/x11_common.c +++ b/libvo/x11_common.c @@ -623,6 +623,7 @@ void vo_x11_classhint( Display * display,Window window,char *name ){ Window vo_window = None; GC vo_gc = NULL; +GC f_gc = NULL; XSizeHints vo_hint; #ifdef HAVE_NEW_GUI @@ -635,6 +636,8 @@ void vo_x11_uninit() { saver_on(mDisplay); if(vo_window!=None) vo_showcursor( mDisplay,vo_window ); + + if (f_gc) XFreeGC(mDisplay, f_gc); #ifdef HAVE_NEW_GUI /* destroy window only if it's not controlled by GUI */ @@ -810,6 +813,65 @@ static int vo_x11_get_gnome_layer(Display * mDisplay, Window win) return WIN_LAYER_NORMAL; } +// +Window vo_x11_create_smooth_window( Display *mDisplay, Window mRoot, Visual *vis, int x, int y, unsigned int width, unsigned int height, int depth, Colormap col_map) +{ + unsigned long xswamask; + XSetWindowAttributes xswa; + + xswamask=CWBackingStore | CWBorderPixel; + + if (col_map!=CopyFromParent) + { + xswa.colormap = col_map; + xswamask|=CWColormap; + } + xswa.background_pixel = 0; + xswa.border_pixel = 0; + xswa.backing_store = Always; + xswa.bit_gravity = StaticGravity; + + Window ret_win = XCreateWindow(mDisplay, mRootWin, x, y, width, height, 0, depth, + CopyFromParent, vis, xswamask , &xswa); + if (!f_gc) f_gc=XCreateGC (mDisplay, ret_win, 0, 0); + XSetForeground (mDisplay, f_gc, 0); + + return ret_win; +} + + +void vo_x11_clearwindow_part( Display *mDisplay, Window vo_window, int img_wid, int img_hei, int use_fs) +{ + if (!f_gc) return; + int u_dheight = use_fs?vo_screenheight:vo_dheight; + int u_dwidth = use_fs?vo_screenwidth:vo_dwidth; + + if (u_dheight<=img_hei && u_dwidth<=img_wid) return; + + int left_ov = (u_dheight - img_hei)/2; + int left_ov2 = (u_dwidth - img_wid)/2; + + XFillRectangle(mDisplay, vo_window, f_gc, 0, 0, u_dwidth, left_ov); + XFillRectangle(mDisplay, vo_window, f_gc, 0, u_dheight-left_ov-1, u_dwidth, left_ov+1); + + if (u_dwidth>img_wid) + { + XFillRectangle(mDisplay, vo_window, f_gc, 0, left_ov, left_ov2, img_hei); + XFillRectangle(mDisplay, vo_window, f_gc, u_dwidth-left_ov2-1, left_ov, left_ov2, img_hei); + } + + XFlush(mDisplay); +} + +void vo_x11_clearwindow( Display *mDisplay, Window vo_window ) +{ + if (!f_gc) return; + XFillRectangle(mDisplay, vo_window, f_gc, 0, 0, vo_screenwidth, vo_screenheight); + // + XFlush(mDisplay); +} + + void vo_x11_setlayer( Display * mDisplay,Window vo_window,int layer ) { if (WinID >= 0) return; -- cgit v1.2.3