1
0
mirror of https://github.com/mpv-player/mpv synced 2025-03-05 13:47:39 +00:00

Avoid flickering during resizes. Keep video contents even when paused. Fix by Tomas Simonaitis <haden@homelan.lt>

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@10758 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
mosu 2003-08-31 22:27:10 +00:00
parent e479f2bb26
commit 908e6a761d
5 changed files with 123 additions and 53 deletions

View File

@ -47,6 +47,8 @@ static uint32_t image_width;
static uint32_t image_height; static uint32_t image_height;
static uint32_t image_bytes; static uint32_t image_bytes;
static int int_pause;
static uint32_t texture_width; static uint32_t texture_width;
static uint32_t texture_height; 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; XEvent xev;
// XGCValues xgcv; // XGCValues xgcv;
XSetWindowAttributes xswa;
unsigned long xswamask;
image_height = height; image_height = height;
image_width = width; image_width = width;
int_pause = 0;
aspect_save_orig(width,height); aspect_save_orig(width,height);
aspect_save_prescale(d_width,d_height); aspect_save_prescale(d_width,d_height);
aspect_save_screenres(vo_screenwidth,vo_screenheight); 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; 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 ) if ( vo_window == None )
{ {
vo_window = XCreateWindow(mDisplay, mRootWin, vo_window = vo_x11_create_smooth_window(mDisplay, mRootWin, vinfo->visual, hint.x, hint.y, hint.width, hint.height,
hint.x, hint.y, hint.width, hint.height, 4, vinfo->depth,CopyFromParent,vinfo->visual,xswamask,&xswa); vinfo->depth, XCreateColormap(mDisplay, mRootWin, vinfo->visual, AllocNone));
vo_x11_classhint( mDisplay,vo_window,"gl" ); vo_x11_classhint( mDisplay,vo_window,"gl" );
vo_hidecursor(mDisplay,vo_window); 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); XSync(mDisplay, False);
vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PointerMotionMask vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PointerMotionMask
| ButtonPressMask | ButtonReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask
); );
texture_width=32; texture_width=32;
@ -213,6 +212,7 @@ static void check_events(void)
{ {
int e=vo_x11_check_events(mDisplay); int e=vo_x11_check_events(mDisplay);
if(e&VO_EVENT_RESIZE) resize(vo_dwidth,vo_dheight); if(e&VO_EVENT_RESIZE) resize(vo_dwidth,vo_dheight);
if(e&VO_EVENT_EXPOSE && int_pause) flip_page();
} }
static void draw_osd(void) 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, ...) static uint32_t control(uint32_t request, void *data, ...)
{ {
switch (request) { switch (request) {
case VOCTRL_PAUSE: return (int_pause=1);
case VOCTRL_RESUME: return (int_pause=0);
case VOCTRL_QUERY_FORMAT: case VOCTRL_QUERY_FORMAT:
return query_format(*((uint32_t*)data)); return query_format(*((uint32_t*)data));
case VOCTRL_FULLSCREEN: case VOCTRL_FULLSCREEN:

View File

@ -64,6 +64,8 @@ static uint32_t image_bpp;
static int image_mode; static int image_mode;
static uint32_t image_bytes; static uint32_t image_bytes;
static int int_pause;
static uint32_t texture_width; static uint32_t texture_width;
static uint32_t texture_height; static uint32_t texture_height;
static int texnumx, texnumy, memory_x_len, memory_x_start_offset, raw_line_len; 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) static void (*draw_alpha_fnc)
(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride); (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 */ /* The squares that are tiled to make up the game screen polygon */
struct TexSquare struct TexSquare
@ -642,14 +645,14 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
XEvent xev; XEvent xev;
// XGCValues xgcv; // XGCValues xgcv;
XSetWindowAttributes xswa;
unsigned long xswamask;
const unsigned char * glVersion; const unsigned char * glVersion;
image_height = height; image_height = height;
image_width = width; image_width = width;
image_format = format; image_format = format;
int_pause = 0;
aspect_save_orig(width,height); aspect_save_orig(width,height);
aspect_save_prescale(d_width,d_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; 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 ) 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 ); if ( flags&0x01 ) vo_x11_decoration( mDisplay,vo_window,0 );
XSelectInput(mDisplay, vo_window, StructureNotifyMask); 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); // !!!! //XSelectInput(mDisplay, vo_window, StructureNotifyMask); // !!!!
vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PointerMotionMask vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PointerMotionMask
| ButtonPressMask | ButtonReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask
); );
glVersion = glGetString(GL_VERSION); glVersion = glGetString(GL_VERSION);
@ -965,7 +963,7 @@ static void check_events(void)
int key; int key;
static XComposeStatus stat; static XComposeStatus stat;
int e; int e;
while ( XPending( mDisplay ) ) while ( XPending( mDisplay ) )
{ {
XNextEvent( mDisplay,&Event ); XNextEvent( mDisplay,&Event );
@ -983,8 +981,9 @@ static void check_events(void)
break; 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_RESIZE) resize(vo_dwidth,vo_dheight);
if(e&VO_EVENT_EXPOSE && int_pause) flip_page();
} }
static void draw_osd(void) 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, ...) static uint32_t control(uint32_t request, void *data, ...)
{ {
switch (request) { switch (request) {
case VOCTRL_PAUSE: return (int_pause=1);
case VOCTRL_RESUME: return (int_pause=0);
case VOCTRL_QUERY_FORMAT: case VOCTRL_QUERY_FORMAT:
return query_format(*((uint32_t*)data)); return query_format(*((uint32_t*)data));
case VOCTRL_FULLSCREEN: case VOCTRL_FULLSCREEN:

View File

@ -56,6 +56,8 @@ static XImage *myximage = NULL;
static int depth,bpp,mode; static int depth,bpp,mode;
static XWindowAttributes attribs; static XWindowAttributes attribs;
static int int_pause;
static int Flip_Flag; static int Flip_Flag;
static int zoomFlag; static int zoomFlag;
@ -88,12 +90,15 @@ static int old_vo_dheight=-1;
static void check_events(){ static void check_events(){
int ret = vo_x11_check_events(mDisplay); int ret = vo_x11_check_events(mDisplay);
/* clear the old window */ /* clear left over borders and redraw frame if we are paused */
if ( (ret & VO_EVENT_RESIZE)||(ret & VO_EVENT_EXPOSE) ) if ( ret & VO_EVENT_EXPOSE && int_pause)
{ {
XSetBackground(mDisplay, vo_gc, 0); vo_x11_clearwindow_part(mDisplay, vo_window, myximage->width, myximage->height, 0);
XClearWindow(mDisplay, vo_window); 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){ 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&0x02 ) vm = 1;
if( flags&0x08 ) Flip_Flag = 1; if( flags&0x08 ) Flip_Flag = 1;
zoomFlag = flags&0x04; zoomFlag = flags&0x04;
int_pause = 0;
// if(!fullscreen) zoomFlag=1; //it makes no sense to avoid zooming on windowd mode // 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 ); //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 ) if ( vo_window == None )
{ {
vo_window=XCreateWindow( mDisplay,mRootWin, vo_window=vo_x11_create_smooth_window( mDisplay,mRootWin,vinfo.visual, vo_dx, vo_dy, vo_dwidth, vo_dheight, depth, theCmap );
vo_dx,vo_dy,
vo_dwidth,vo_dheight,
xswa.border_pixel,depth,CopyFromParent,vinfo.visual,xswamask,&xswa );
vo_x11_classhint( mDisplay,vo_window,"x11" ); vo_x11_classhint( mDisplay,vo_window,"x11" );
vo_hidecursor(mDisplay,vo_window); 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, ...) static uint32_t control(uint32_t request, void *data, ...)
{ {
switch (request) { switch (request) {
case VOCTRL_PAUSE: return (int_pause=1);
case VOCTRL_RESUME: return (int_pause=0);
case VOCTRL_QUERY_FORMAT: case VOCTRL_QUERY_FORMAT:
return query_format(*((uint32_t*)data)); return query_format(*((uint32_t*)data));
case VOCTRL_GUISUPPORT: case VOCTRL_GUISUPPORT:
@ -652,7 +658,10 @@ static uint32_t control(uint32_t request, void *data, ...)
return vo_x11_get_equalizer(data, value); return vo_x11_get_equalizer(data, value);
} }
case VOCTRL_FULLSCREEN: case VOCTRL_FULLSCREEN:
vo_x11_fullscreen(); {
vo_x11_fullscreen();
vo_x11_clearwindow(mDisplay, vo_window);
}
return VO_TRUE; return VO_TRUE;
} }
return VO_NOTIMPL; return VO_NOTIMPL;

View File

@ -81,6 +81,8 @@ static uint32_t image_height;
static uint32_t image_format; static uint32_t image_format;
static int flip_flag; static int flip_flag;
static int int_pause;
static Window mRoot; static Window mRoot;
static uint32_t drwX,drwY,drwBorderWidth,drwDepth; static uint32_t drwX,drwY,drwBorderWidth,drwDepth;
static uint32_t dwidth,dheight; 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; vo_mouse_autohide=1;
int_pause=0;
vo_dx=( vo_screenwidth - d_width ) / 2; vo_dy=( vo_screenheight - d_height ) / 2; 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); geometry(&vo_dx, &vo_dy, &d_width, &d_height, vo_screenwidth, vo_screenheight);
vo_dwidth=d_width; vo_dheight=d_height; 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 { drwX=vo_dx; drwY=vo_dy; }
} else } else
if ( vo_window == None ){ if ( vo_window == None ){
vo_window = XCreateWindow(mDisplay, mRootWin, vo_window = vo_x11_create_smooth_window(mDisplay, mRootWin, vinfo.visual, hint.x, hint.y, hint.width, hint.height, depth, CopyFromParent);
hint.x, hint.y, hint.width, hint.height,
0, depth,CopyFromParent,vinfo.visual,xswamask,&xswa);
vo_x11_classhint( mDisplay,vo_window,"xv" ); vo_x11_classhint( mDisplay,vo_window,"xv" );
vo_hidecursor(mDisplay,vo_window); vo_hidecursor(mDisplay,vo_window);
vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PropertyChangeMask | vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PropertyChangeMask |
((WinID==0) ? 0 : (PointerMotionMask ((WinID==0) ? 0 : (PointerMotionMask
| ButtonPressMask | ButtonReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask
))); )));
XSetStandardProperties(mDisplay, vo_window, hello, hello, None, NULL, 0, &hint); XSetStandardProperties(mDisplay, vo_window, hello, hello, None, NULL, 0, &hint);
XSetWMNormalHints( mDisplay,vo_window,&hint ); XSetWMNormalHints( mDisplay,vo_window,&hint );
@ -401,6 +403,10 @@ static void deallocate_xvimage(int foo)
static void check_events(void) static void check_events(void)
{ {
int e=vo_x11_check_events(mDisplay); 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(e&VO_EVENT_RESIZE)
{ {
if (vo_fs) { 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 ); 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 )
{ if ( (e&VO_EVENT_EXPOSE || e&VO_EVENT_RESIZE) && int_pause)
#ifdef HAVE_SHM flip_page();
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));
}
}
} }
static void draw_osd(void) 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, ...) static uint32_t control(uint32_t request, void *data, ...)
{ {
switch (request) { switch (request) {
case VOCTRL_PAUSE: return (int_pause=1);
case VOCTRL_RESUME: return (int_pause=0);
case VOCTRL_QUERY_FORMAT: case VOCTRL_QUERY_FORMAT:
return query_format(*((uint32_t*)data)); return query_format(*((uint32_t*)data));
case VOCTRL_GET_IMAGE: case VOCTRL_GET_IMAGE:
@ -688,8 +684,8 @@ static uint32_t control(uint32_t request, void *data, ...)
if(old_y != vo_panscan_y) if(old_y != vo_panscan_y)
{ {
XClearWindow(mDisplay, vo_window); vo_x11_clearwindow_part(mDisplay, vo_window, vo_dwidth+vo_panscan_x-1, vo_dheight+vo_panscan_y-1, 1);
XFlush(mDisplay); flip_page();
} }
} }
return VO_TRUE; return VO_TRUE;

View File

@ -623,6 +623,7 @@ void vo_x11_classhint( Display * display,Window window,char *name ){
Window vo_window = None; Window vo_window = None;
GC vo_gc = NULL; GC vo_gc = NULL;
GC f_gc = NULL;
XSizeHints vo_hint; XSizeHints vo_hint;
#ifdef HAVE_NEW_GUI #ifdef HAVE_NEW_GUI
@ -635,6 +636,8 @@ void vo_x11_uninit()
{ {
saver_on(mDisplay); saver_on(mDisplay);
if(vo_window!=None) vo_showcursor( mDisplay,vo_window ); if(vo_window!=None) vo_showcursor( mDisplay,vo_window );
if (f_gc) XFreeGC(mDisplay, f_gc);
#ifdef HAVE_NEW_GUI #ifdef HAVE_NEW_GUI
/* destroy window only if it's not controlled by 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; 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 ) void vo_x11_setlayer( Display * mDisplay,Window vo_window,int layer )
{ {
if (WinID >= 0) return; if (WinID >= 0) return;