changeset 10757:3aea64e0d6d9

Avoid flickering during resizes. Keep video contents even when paused. Fix by Tomas Simonaitis <haden@homelan.lt>
author mosu
date Sun, 31 Aug 2003 22:27:10 +0000
parents e40dee59f3ba
children 45d37ee04091
files libvo/vo_gl.c libvo/vo_gl2.c libvo/vo_x11.c libvo/vo_xv.c libvo/x11_common.c
diffstat 5 files changed, 123 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/vo_gl.c	Sun Aug 31 22:18:27 2003 +0000
+++ b/libvo/vo_gl.c	Sun Aug 31 22:27:10 2003 +0000
@@ -47,6 +47,8 @@
 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 @@
 	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 @@
     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 @@
 	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 @@
 {
     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 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:
--- a/libvo/vo_gl2.c	Sun Aug 31 22:18:27 2003 +0000
+++ b/libvo/vo_gl2.c	Sun Aug 31 22:27:10 2003 +0000
@@ -64,6 +64,8 @@
 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 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 @@
 	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 @@
     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 @@
 
 	//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 @@
 	 int            key;
 	 static XComposeStatus stat;
 	 int e;
-
+         
 	 while ( XPending( mDisplay ) )
 	 {
 	      XNextEvent( mDisplay,&Event );
@@ -983,8 +981,9 @@
 	               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 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:
--- a/libvo/vo_x11.c	Sun Aug 31 22:18:27 2003 +0000
+++ b/libvo/vo_x11.c	Sun Aug 31 22:27:10 2003 +0000
@@ -56,6 +56,8 @@
 static int depth,bpp,mode;
 static XWindowAttributes attribs;
 
+static int int_pause;
+
 static int Flip_Flag;
 static int zoomFlag;
 
@@ -88,12 +90,15 @@
 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 @@
  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 @@
      {
       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 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 @@
       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;
--- a/libvo/vo_xv.c	Sun Aug 31 22:18:27 2003 +0000
+++ b/libvo/vo_xv.c	Sun Aug 31 22:27:10 2003 +0000
@@ -81,6 +81,8 @@
 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 @@
  
  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 @@
        } 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 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 @@
      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 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 @@
       
       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;
--- a/libvo/x11_common.c	Sun Aug 31 22:18:27 2003 +0000
+++ b/libvo/x11_common.c	Sun Aug 31 22:27:10 2003 +0000
@@ -623,6 +623,7 @@
 
 Window     vo_window = None;
 GC         vo_gc = NULL;
+GC         f_gc  = NULL;
 XSizeHints vo_hint;
 
 #ifdef HAVE_NEW_GUI
@@ -635,6 +636,8 @@
 {
     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 @@
  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;