Web lists-archives.org

Re: [MPlayer-dev-eng] libvo changes




Here are the latest libvo changes. They add the basics of a new VO
driver API and convert vo_xv to use it.
Change VOCTRL_[GET|SET]_EQUALIZER argument passing

These were the only voctrl types with more than one argument. The
second argument was passed using variable arguments. Change them to
use a single argument (address of a struct containing both old
arguments). This makes forwarding the arguments to other functions
easier and allows simplifying code.
---
 libmpcodecs/vf_vo.c  |    6 ++-
 libvo/mga_common.c   |   25 ++++++----------
 libvo/video_out.h    |    8 +++++
 libvo/vo_aa.c        |   31 ++++++--------------
 libvo/vo_cvidix.c    |   18 ------------
 libvo/vo_dfbmga.c    |   20 ++----------
 libvo/vo_directfb2.c |   20 ++----------
 libvo/vo_directx.c   |   18 ++---------
 libvo/vo_dxr3.c      |   38 +++++++++----------------
 libvo/vo_fbdev.c     |   21 +-------------
 libvo/vo_gl.c        |   76 ++++++++++++++++++++++---------------------------
 libvo/vo_gl2.c       |   18 ++---------
 libvo/vo_svga.c      |   27 +-----------------
 libvo/vo_vesa.c      |   27 +-----------------
 libvo/vo_winvidix.c  |   22 --------------
 libvo/vo_x11.c       |   20 ++----------
 libvo/vo_xv.c        |   22 ++------------
 libvo/vo_xvidix.c    |   24 ----------------
 libvo/vo_xvmc.c      |   20 ++----------
 libvo/vosub_vidix.c  |   47 ++++++++++++------------------
 20 files changed, 130 insertions(+), 378 deletions(-)

diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c
index f0daa59..877826e 100644
--- a/libmpcodecs/vf_vo.c
+++ b/libmpcodecs/vf_vo.c
@@ -103,13 +103,15 @@ static int control(struct vf_instance_s* vf, int request, void* data)
     {
 	vf_equalizer_t *eq=data;
 	if(!vo_config_count) return CONTROL_FALSE; // vo not configured?
-	return((video_out->control(VOCTRL_SET_EQUALIZER, eq->item, eq->value) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE);
+	struct voctrl_set_equalizer_args param = {eq->item, eq->value};
+	return video_out->control(VOCTRL_SET_EQUALIZER, &param) == VO_TRUE;
     }
     case VFCTRL_GET_EQUALIZER:
     {
 	vf_equalizer_t *eq=data;
 	if(!vo_config_count) return CONTROL_FALSE; // vo not configured?
-	return((video_out->control(VOCTRL_GET_EQUALIZER, eq->item, &eq->value) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE);
+	struct voctrl_get_equalizer_args param = {eq->item, &eq->value};
+	return video_out->control(VOCTRL_GET_EQUALIZER, &param) == VO_TRUE;
     }
 #ifdef USE_ASS
     case VFCTRL_INIT_EOSD:
diff --git a/libvo/mga_common.c b/libvo/mga_common.c
index b150b18..600e4e7 100644
--- a/libvo/mga_common.c
+++ b/libvo/mga_common.c
@@ -240,11 +240,12 @@ static int control(uint32_t request, void *data, ...)
     return draw_image(data);
   case VOCTRL_SET_EQUALIZER:
     {
-     va_list ap;
      short value;
      uint32_t luma,prev;
+     struct voctrl_get_equalizer_args *args = data;
 
-     if ( strcmp( data,"brightness" ) && strcmp( data,"contrast" ) ) return VO_FALSE;
+     if (strcmp(args->name, "brightness") && strcmp(args->name, "contrast"))
+	return VO_FALSE;
 
      if (ioctl(f,MGA_VID_GET_LUMA,&prev)) {
 	perror("Error in mga_vid_config ioctl()");
@@ -254,15 +255,13 @@ static int control(uint32_t request, void *data, ...)
 
 //     printf("GET: 0x%4X 0x%4X  \n",(prev>>16),(prev&0xffff));
 
-     va_start(ap, data);
-     value = va_arg(ap, int);
-     va_end(ap);
+     value = args->value;
      
 //     printf("value: %d -> ",value);
      value=((value+100)*255)/200-128; // maps -100=>-128 and +100=>127
 //     printf("%d  \n",value);
 
-     if(!strcmp(data,"contrast"))
+     if (!strcmp(args->name, "contrast"))
          luma = (prev&0xFFFF0000)|(value&0xFFFF);
      else
          luma = (prev&0xFFFF)|(value<<16);
@@ -278,12 +277,12 @@ static int control(uint32_t request, void *data, ...)
 
   case VOCTRL_GET_EQUALIZER:
     {
-     va_list ap;
-     int * value;
      short val;
      uint32_t luma;
+     struct voctrl_get_equalizer_args *args = data;
      
-     if ( strcmp( data,"brightness" ) && strcmp( data,"contrast" ) ) return VO_FALSE;
+     if (strcmp(args->name, "brightness") && strcmp(args->name, "contrast"))
+        return VO_FALSE;
 
      if (ioctl(f,MGA_VID_GET_LUMA,&luma)) {
 	perror("Error in mga_vid_config ioctl()");
@@ -291,16 +290,12 @@ static int control(uint32_t request, void *data, ...)
 	return VO_FALSE;
      }
      
-     if ( !strcmp( data,"contrast" ) )
+     if (!strcmp(args->name, "contrast"))
 	 val=(luma & 0xFFFF);
      else
 	 val=(luma >> 16);
 	 
-     va_start(ap, data);
-     value = va_arg(ap, int*);
-     va_end(ap);
-
-     *value = (val*200)/255;
+     *args->valueptr = (val*200)/255;
 
      return VO_TRUE;
     }
diff --git a/libvo/video_out.h b/libvo/video_out.h
index 48799c4..ae9a1c3 100644
--- a/libvo/video_out.h
+++ b/libvo/video_out.h
@@ -47,7 +47,15 @@
 #define VOCTRL_SET_PANSCAN 16
 /* equalizer controls */
 #define VOCTRL_SET_EQUALIZER 17
+struct voctrl_set_equalizer_args {
+    const char *name;
+    int value;
+};
 #define VOCTRL_GET_EQUALIZER 18
+struct voctrl_get_equalizer_args {
+    const char *name;
+    int *valueptr;
+};
 //#define VOCTRL_GUI_NOWINDOW 19
 /* Frame duplication */
 #define VOCTRL_DUPLICATE_FRAME 20
diff --git a/libvo/vo_aa.c b/libvo/vo_aa.c
index 77c545b..8ba01d6 100644
--- a/libvo/vo_aa.c
+++ b/libvo/vo_aa.c
@@ -724,31 +724,20 @@ static int control(uint32_t request, void *data, ...)
   case VOCTRL_QUERY_FORMAT:
     return query_format(*((uint32_t*)data));
   case VOCTRL_SET_EQUALIZER: {
-    va_list ap;
-    int val;
-
-    va_start(ap, data);
-    val = va_arg(ap, int);
-    va_end(ap);
-
-    if(strcmp((char*)data,"contrast") == 0)
-      p->contrast = ( val + 100 ) * 64 / 100;
-    else if(strcmp((char*)data,"brightness") == 0)
-      p->bright = ( val + 100) * 128 / 100;
+    struct voctrl_set_equalizer_args *args = data;
+    if (strcmp(args->name, "contrast") == 0)
+      p->contrast = (args->value + 100) * 64 / 100;
+    else if (strcmp(args->name, "brightness") == 0)
+      p->bright = (args->value + 100) * 128 / 100;
     return VO_TRUE;
   }
   case VOCTRL_GET_EQUALIZER: {
-    va_list ap;
-    int* val;
-
-    va_start(ap, data);
-    val = va_arg(ap, int*);
-    va_end(ap);
+    struct voctrl_get_equalizer_args *args = data;
 
-    if(strcmp((char*)data,"contrast") == 0)
-      *val = (p->contrast - 64) * 100 / 64;
-    else if(strcmp((char*)data,"brightness") == 0)
-      *val = (p->bright - 128) * 100 / 128;
+    if (strcmp(args->name, "contrast") == 0)
+      *args->valueptr = (p->contrast - 64) * 100 / 64;
+    else if (strcmp(args->name, "brightness") == 0)
+      *args->valueptr = (p->bright - 128) * 100 / 128;
 
     return VO_TRUE;
   }
diff --git a/libvo/vo_cvidix.c b/libvo/vo_cvidix.c
index 7dd74ee..9b6c593 100644
--- a/libvo/vo_cvidix.c
+++ b/libvo/vo_cvidix.c
@@ -165,24 +165,6 @@ static int control(uint32_t request, void *data, ...){
     else vo_fs=1;
     setup_vidix();
     return VO_TRUE;      
-  case VOCTRL_SET_EQUALIZER:
-    {
-      va_list ap;
-      int value;
-      va_start(ap, data);
-      value = va_arg(ap, int);
-      va_end(ap);
-      return vidix_control(request, data, value);
-    }
-  case VOCTRL_GET_EQUALIZER:
-    {
-      va_list ap;
-      int *value;
-      va_start(ap, data);
-      value = va_arg(ap, int *);
-      va_end(ap);
-      return vidix_control(request, data, value);
-    }
   }  
   return vidix_control(request, data);
 }
diff --git a/libvo/vo_dfbmga.c b/libvo/vo_dfbmga.c
index ee381d0..ee3bf74 100644
--- a/libvo/vo_dfbmga.c
+++ b/libvo/vo_dfbmga.c
@@ -1399,25 +1399,13 @@ control( uint32_t request, void *data, ... )
 
      case VOCTRL_SET_EQUALIZER:
           {
-               va_list ap;
-               int value;
-
-               va_start( ap, data );
-               value = va_arg( ap, int );
-               va_end( ap );
-
-               return set_equalizer( data, value );
+               struct voctrl_set_equalizer_args *args = data;
+               return set_equalizer(args->name, args->value);
           }
      case VOCTRL_GET_EQUALIZER:
           {
-               va_list ap;
-               int *value;
-
-               va_start( ap, data );
-               value = va_arg( ap, int* );
-               va_end( ap );
-
-               return get_equalizer( data, value );
+               struct voctrl_get_equalizer_args *args = data;
+               return get_equalizer(args->name, args->valueptr);
           }
      }
 
diff --git a/libvo/vo_directfb2.c b/libvo/vo_directfb2.c
index a211cad..a9bc40c 100644
--- a/libvo/vo_directfb2.c
+++ b/libvo/vo_directfb2.c
@@ -1422,25 +1422,13 @@ static int control(uint32_t request, void *data, ...)
 	return put_image(data);    
     case VOCTRL_SET_EQUALIZER:
       {
-        va_list ap;
-	int value;
-    
-        va_start(ap, data);
-	value = va_arg(ap, int);
-        va_end(ap);
-    
-	return(directfb_set_video_eq(data, value));
+	struct voctrl_set_equalizer_args *args = data;
+	return directfb_set_video_eq(args->name, args->value);
       }
     case VOCTRL_GET_EQUALIZER:
       {
-	va_list ap;
-        int *value;
-    
-        va_start(ap, data);
-        value = va_arg(ap, int*);
-        va_end(ap);
-    
-	return(directfb_get_video_eq(data, value));
+	struct voctrl_get_equalizer_args *args = data;
+	return directfb_get_video_eq(args->name, args->valueptr);
       }
   };
   return VO_NOTIMPL;
diff --git a/libvo/vo_directx.c b/libvo/vo_directx.c
index 356304c..a110c48 100644
--- a/libvo/vo_directx.c
+++ b/libvo/vo_directx.c
@@ -1564,22 +1564,12 @@ static int control(uint32_t request, void *data, ...)
 		    return VO_TRUE;
 		}
 	case VOCTRL_SET_EQUALIZER: {
-		va_list	ap;
-		int	value;
-		
-		va_start(ap, data);
-		value = va_arg(ap, int);
-		va_end(ap);
-		return color_ctrl_set(data, value);
+		struct voctrl_set_equalizer_args *args = data;
+		return color_ctrl_set(args->name, args->value);
 	}
 	case VOCTRL_GET_EQUALIZER: {
-		va_list	ap;
-		int	*value;
-		
-		va_start(ap, data);
-		value = va_arg(ap, int*);
-		va_end(ap);
-		return color_ctrl_get(data, value);
+		struct voctrl_get_equalizer_args *args = data;
+		return color_ctrl_get(args->name, args->valueptr);
 	}
     case VOCTRL_UPDATE_SCREENINFO:
         if (vidmode) {
diff --git a/libvo/vo_dxr3.c b/libvo/vo_dxr3.c
index 288a7a7..a48c7be 100644
--- a/libvo/vo_dxr3.c
+++ b/libvo/vo_dxr3.c
@@ -240,22 +240,17 @@ static int control(uint32_t request, void *data, ...)
 	    }
 	case VOCTRL_SET_EQUALIZER:
 	    {
-		va_list ap;
-		int value;
 		em8300_bcs_t bcs;
-		
-		va_start(ap, data);
-		value = va_arg(ap, int);
-		va_end(ap);
+		struct voctrl_set_equalizer_args *args = data;
 
 		if (ioctl(fd_control, EM8300_IOCTL_GETBCS, &bcs) < 0)
 		    return VO_FALSE;
-		if (!strcasecmp(data, "brightness"))
-		    bcs.brightness = (value+100)*5;
-		else if (!strcasecmp(data, "contrast"))
-		    bcs.contrast = (value+100)*5;
-		else if (!strcasecmp(data, "saturation"))
-		    bcs.saturation = (value+100)*5;
+		if (!strcasecmp(args->name, "brightness"))
+		    bcs.brightness = (args->value+100)*5;
+		else if (!strcasecmp(args->name, "contrast"))
+		    bcs.contrast = (args->value+100)*5;
+		else if (!strcasecmp(args->name, "saturation"))
+		    bcs.saturation = (args->value+100)*5;
 		else return VO_FALSE;
         
 		if (ioctl(fd_control, EM8300_IOCTL_SETBCS, &bcs) < 0)
@@ -264,23 +259,18 @@ static int control(uint32_t request, void *data, ...)
 	    }
 	case VOCTRL_GET_EQUALIZER:
 	    {
-		va_list ap;
-		int *value;
 		em8300_bcs_t bcs;
+		struct voctrl_get_equalizer_args *args = data;
 		
-		va_start(ap, data);
-		value = va_arg(ap, int*);
-		va_end(ap);
-
 		if (ioctl(fd_control, EM8300_IOCTL_GETBCS, &bcs) < 0)
 		    return VO_FALSE;
 		
-		if (!strcasecmp(data, "brightness"))
-		    *value = (bcs.brightness/5)-100;
-		else if (!strcasecmp(data, "contrast"))
-		    *value = (bcs.contrast/5)-100;
-		else if (!strcasecmp(data, "saturation"))
-		    *value = (bcs.saturation/5)-100;
+		if (!strcasecmp(args->name, "brightness"))
+		    *args->valueptr = (bcs.brightness/5)-100;
+		else if (!strcasecmp(args->name, "contrast"))
+		    *args->valueptr = (bcs.contrast/5)-100;
+		else if (!strcasecmp(args->name, "saturation"))
+		    *args->valueptr = (bcs.saturation/5)-100;
 		else return VO_FALSE;
         
 		return VO_TRUE;
diff --git a/libvo/vo_fbdev.c b/libvo/vo_fbdev.c
index 82e6344..12f48fd 100644
--- a/libvo/vo_fbdev.c
+++ b/libvo/vo_fbdev.c
@@ -1176,27 +1176,8 @@ static int control(uint32_t request, void *data, ...)
   if (vidix_name) {
       switch (request) {
       case VOCTRL_SET_EQUALIZER:
-	  {
-	      va_list ap;
-	      int value;
-	      
-	      va_start(ap, data);
-	      value = va_arg(ap, int);
-	      va_end(ap);
-	      
-	      return vidix_control(request, data, value);
-         }
       case VOCTRL_GET_EQUALIZER:
-	  {
-	      va_list ap;
-	      int *value;
-	      
-	      va_start(ap, data);
-	      value = va_arg(ap, int*);
-	      va_end(ap);
-	      
-	      return vidix_control(request, data, value);
-	  }
+	  return vidix_control(request, data);
       }
   }
 #endif
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index 500bb0d..36fbff4 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -941,35 +941,31 @@ static int control(uint32_t request, void *data, ...)
     return VO_TRUE;
   case VOCTRL_GET_EQUALIZER:
     if (image_format == IMGFMT_YV12) {
-      va_list va;
-      int *value;
-      va_start(va, data);
-      value = va_arg(va, int *);
-      va_end(va);
-      if (strcasecmp(data, "brightness") == 0) {
-        *value = eq_bri;
+      struct voctrl_get_equalizer_args *args = data;
+      if (strcasecmp(args->name, "brightness") == 0) {
+        *args->valueptr = eq_bri;
         if (use_yuv == YUV_CONVERSION_COMBINERS) break; // not supported
-      } else if (strcasecmp(data, "contrast") == 0) {
-        *value = eq_cont;
+      } else if (strcasecmp(args->name, "contrast") == 0) {
+        *args->valueptr = eq_cont;
         if (use_yuv == YUV_CONVERSION_COMBINERS) break; // not supported
-      } else if (strcasecmp(data, "saturation") == 0) {
-        *value = eq_sat;
-      } else if (strcasecmp(data, "hue") == 0) {
-        *value = eq_hue;
-      } else if (strcasecmp(data, "gamma") ==  0) {
-        *value = eq_rgamma;
+      } else if (strcasecmp(args->name, "saturation") == 0) {
+        *args->valueptr = eq_sat;
+      } else if (strcasecmp(args->name, "hue") == 0) {
+        *args->valueptr = eq_hue;
+      } else if (strcasecmp(args->name, "gamma") ==  0) {
+        *args->valueptr = eq_rgamma;
         if (use_yuv == YUV_CONVERSION_COMBINERS ||
             use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported
-      } else if (strcasecmp(data, "red_gamma") ==  0) {
-        *value = eq_rgamma;
+      } else if (strcasecmp(args->name, "red_gamma") ==  0) {
+        *args->valueptr = eq_rgamma;
         if (use_yuv == YUV_CONVERSION_COMBINERS ||
             use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported
-      } else if (strcasecmp(data, "green_gamma") ==  0) {
-        *value = eq_ggamma;
+      } else if (strcasecmp(args->name, "green_gamma") ==  0) {
+        *args->valueptr = eq_ggamma;
         if (use_yuv == YUV_CONVERSION_COMBINERS ||
             use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported
-      } else if (strcasecmp(data, "blue_gamma") ==  0) {
-        *value = eq_bgamma;
+      } else if (strcasecmp(args->name, "blue_gamma") ==  0) {
+        *args->valueptr = eq_bgamma;
         if (use_yuv == YUV_CONVERSION_COMBINERS ||
             use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported
       }
@@ -978,35 +974,31 @@ static int control(uint32_t request, void *data, ...)
     break;
   case VOCTRL_SET_EQUALIZER:
     if (image_format == IMGFMT_YV12) {
-      va_list va;
-      int value;
-      va_start(va, data);
-      value = va_arg(va, int);
-      va_end(va);
-      if (strcasecmp(data, "brightness") == 0) {
-        eq_bri = value;
+      struct voctrl_set_equalizer_args *args = data;
+      if (strcasecmp(args->name, "brightness") == 0) {
+        eq_bri = args->value;
         if (use_yuv == YUV_CONVERSION_COMBINERS) break; // not supported
-      } else if (strcasecmp(data, "contrast") == 0) {
-        eq_cont = value;
+      } else if (strcasecmp(args->name, "contrast") == 0) {
+        eq_cont = args->value;
         if (use_yuv == YUV_CONVERSION_COMBINERS) break; // not supported
-      } else if (strcasecmp(data, "saturation") == 0) {
-        eq_sat = value;
-      } else if (strcasecmp(data, "hue") == 0) {
-        eq_hue = value;
-      } else if (strcasecmp(data, "gamma") ==  0) {
-        eq_rgamma = eq_ggamma = eq_bgamma = value;
+      } else if (strcasecmp(args->name, "saturation") == 0) {
+        eq_sat = args->value;
+      } else if (strcasecmp(args->name, "hue") == 0) {
+        eq_hue = args->value;
+      } else if (strcasecmp(args->name, "gamma") ==  0) {
+        eq_rgamma = eq_ggamma = eq_bgamma = args->value;
         if (use_yuv == YUV_CONVERSION_COMBINERS ||
             use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported
-      } else if (strcasecmp(data, "red_gamma") ==  0) {
-        eq_rgamma = value;
+      } else if (strcasecmp(args->name, "red_gamma") ==  0) {
+        eq_rgamma = args->value;
         if (use_yuv == YUV_CONVERSION_COMBINERS ||
             use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported
-      } else if (strcasecmp(data, "green_gamma") ==  0) {
-        eq_ggamma = value;
+      } else if (strcasecmp(args->name, "green_gamma") ==  0) {
+        eq_ggamma = args->value;
         if (use_yuv == YUV_CONVERSION_COMBINERS ||
             use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported
-      } else if (strcasecmp(data, "blue_gamma") ==  0) {
-        eq_bgamma = value;
+      } else if (strcasecmp(args->name, "blue_gamma") ==  0) {
+        eq_bgamma = args->value;
         if (use_yuv == YUV_CONVERSION_COMBINERS ||
             use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported
       }
diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c
index aa198cd..d83c5a3 100644
--- a/libvo/vo_gl2.c
+++ b/libvo/vo_gl2.c
@@ -898,23 +898,13 @@ static int control(uint32_t request, void *data, ...)
 #ifndef GL_WIN32
     case VOCTRL_SET_EQUALIZER:
     {
-      va_list ap;
-      int value;
-
-      va_start(ap, data);
-      value = va_arg(ap, int);
-      va_end(ap);
-      return vo_x11_set_equalizer(data, value);
+      struct voctrl_set_equalizer_args *args = data;
+      return vo_x11_set_equalizer(args->name, args->value);
     }
     case VOCTRL_GET_EQUALIZER:
     {
-      va_list ap;
-      int *value;
-
-      va_start(ap, data);
-      value = va_arg(ap, int *);
-      va_end(ap);
-      return vo_x11_get_equalizer(data, value);
+      struct voctrl_get_equalizer_args *args = data;
+      return vo_x11_get_equalizer(args->name, args->valueptr);
     }
 #endif
     case VOCTRL_UPDATE_SCREENINFO:
diff --git a/libvo/vo_svga.c b/libvo/vo_svga.c
index e68dbf3..9d38c8d 100644
--- a/libvo/vo_svga.c
+++ b/libvo/vo_svga.c
@@ -362,33 +362,8 @@ static int control(uint32_t request, void *data, ...)
   }
 
 #ifdef CONFIG_VIDIX
-  if (vidix_name[0]) {
-    switch (request) {
-    case VOCTRL_SET_EQUALIZER:
-    {
-      va_list ap;
-      int value;
-    
-      va_start(ap, data);
-      value = va_arg(ap, int);
-      va_end(ap);
-
-      return vidix_control(request, data, value);
-    }
-    case VOCTRL_GET_EQUALIZER:
-    {
-      va_list ap;
-      int *value;
-    
-      va_start(ap, data);
-      value = va_arg(ap, int*);
-      va_end(ap);
-
-      return vidix_control(request, data, value);
-    }
-    }
+  if (vidix_name[0])
     return vidix_control(request, data);
-  }
 #endif
 
   return VO_NOTIMPL;
diff --git a/libvo/vo_vesa.c b/libvo/vo_vesa.c
index 0eaa47b..f5eb0e1 100644
--- a/libvo/vo_vesa.c
+++ b/libvo/vo_vesa.c
@@ -1098,33 +1098,8 @@ static int control(uint32_t request, void *data, ...)
   }
 
 #ifdef CONFIG_VIDIX
-  if (vidix_name) {
-    switch (request) {
-    case VOCTRL_SET_EQUALIZER:
-    {
-      va_list ap;
-      int value;
-    
-      va_start(ap, data);
-      value = va_arg(ap, int);
-      va_end(ap);
-
-      return vidix_control(request, data, (int *)value);
-    }
-    case VOCTRL_GET_EQUALIZER:
-    {
-      va_list ap;
-      int *value;
-    
-      va_start(ap, data);
-      value = va_arg(ap, int*);
-      va_end(ap);
-
-      return vidix_control(request, data, value);
-    }
-    }
+  if (vidix_name)
     return vidix_control(request, data);
-  }
 #endif
 
   return VO_NOTIMPL;
diff --git a/libvo/vo_winvidix.c b/libvo/vo_winvidix.c
index e471696..97ff41d 100644
--- a/libvo/vo_winvidix.c
+++ b/libvo/vo_winvidix.c
@@ -337,28 +337,6 @@ static int control(uint32_t request, void *data, ...){
     break;
   case VOCTRL_QUERY_FORMAT:
     return query_format(*((uint32_t*)data));
-  case VOCTRL_SET_EQUALIZER:
-  {
-    va_list ap;
-    int value;
-    
-    va_start(ap, data);
-    value = va_arg(ap, int);
-    va_end(ap);
-
-    return vidix_control(request, data, (int *)value);
-  }
-  case VOCTRL_GET_EQUALIZER:
-  {
-    va_list ap;
-    int *value;
-    
-    va_start(ap, data);
-    value = va_arg(ap, int*);
-    va_end(ap);
-
-    return vidix_control(request, data, value);
-  }
   }
   return vidix_control(request, data);
 //  return VO_NOTIMPL;
diff --git a/libvo/vo_x11.c b/libvo/vo_x11.c
index ca79dab..2b56ee4 100644
--- a/libvo/vo_x11.c
+++ b/libvo/vo_x11.c
@@ -764,25 +764,13 @@ static int control(uint32_t request, void *data, ...)
             return get_image(data);
         case VOCTRL_SET_EQUALIZER:
             {
-                va_list ap;
-                int value;
-
-                va_start(ap, data);
-                value = va_arg(ap, int);
-
-                va_end(ap);
-                return vo_x11_set_equalizer(data, value);
+                struct voctrl_set_equalizer_args *args = data;
+                return vo_x11_set_equalizer(args->name, args->value);
             }
         case VOCTRL_GET_EQUALIZER:
             {
-                va_list ap;
-                int *value;
-
-                va_start(ap, data);
-                value = va_arg(ap, int *);
-
-                va_end(ap);
-                return vo_x11_get_equalizer(data, value);
+                struct voctrl_get_equalizer_args *args = data;
+                return vo_x11_get_equalizer(args->name, args->valueptr);
             }
         case VOCTRL_ONTOP:
             vo_x11_ontop();
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index 2a38988..36d4d67 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -886,27 +886,13 @@ static int control(uint32_t request, void *data, ...)
             return VO_TRUE;
         case VOCTRL_SET_EQUALIZER:
             {
-                va_list ap;
-                int value;
-
-                va_start(ap, data);
-                value = va_arg(ap, int);
-
-                va_end(ap);
-
-                return (vo_xv_set_eq(xv_port, data, value));
+                struct voctrl_set_equalizer_args *args = data;
+                return vo_xv_set_eq(xv_port, args->name, args->value);
             }
         case VOCTRL_GET_EQUALIZER:
             {
-                va_list ap;
-                int *value;
-
-                va_start(ap, data);
-                value = va_arg(ap, int *);
-
-                va_end(ap);
-
-                return (vo_xv_get_eq(xv_port, data, value));
+                struct voctrl_get_equalizer_args *args = data;
+                return vo_xv_get_eq(xv_port, args->name, args->valueptr);
             }
         case VOCTRL_ONTOP:
             vo_x11_ontop();
diff --git a/libvo/vo_xvidix.c b/libvo/vo_xvidix.c
index 7a455dd..fdd82d8 100644
--- a/libvo/vo_xvidix.c
+++ b/libvo/vo_xvidix.c
@@ -494,30 +494,6 @@ static int control(uint32_t request, void *data, ...)
                 set_window(0);
             }
             return VO_TRUE;
-        case VOCTRL_SET_EQUALIZER:
-            {
-                va_list ap;
-                int value;
-
-                va_start(ap, data);
-                value = va_arg(ap, int);
-
-                va_end(ap);
-
-                return vidix_control(request, data, value);
-            }
-        case VOCTRL_GET_EQUALIZER:
-            {
-                va_list ap;
-                int *value;
-
-                va_start(ap, data);
-                value = va_arg(ap, int *);
-
-                va_end(ap);
-
-                return vidix_control(request, data, value);
-            }
         case VOCTRL_UPDATE_SCREENINFO:
             aspect_save_screenres(vo_screenwidth, vo_screenheight);
             return VO_TRUE;
diff --git a/libvo/vo_xvmc.c b/libvo/vo_xvmc.c
index e04fbd1..efa4e5d 100644
--- a/libvo/vo_xvmc.c
+++ b/libvo/vo_xvmc.c
@@ -1397,26 +1397,14 @@ static int control(uint32_t request, void *data, ... )
          return VO_TRUE;
       case VOCTRL_SET_EQUALIZER:
       {
-      va_list ap;
-      int value;
-
-         va_start(ap, data);
-         value = va_arg(ap, int);
-         va_end(ap);
-
-         return(vo_xv_set_eq(xv_port, data, value));
+	 struct voctrl_set_equalizer_args *args = data;
+	 return vo_xv_set_eq(xv_port, args->name, args->value);
       }
 
       case VOCTRL_GET_EQUALIZER:
       {
-      va_list ap;
-      int *value;
-
-         va_start(ap, data);
-         value = va_arg(ap, int*);
-         va_end(ap);
-
-         return(vo_xv_get_eq(xv_port, data, value));
+	 struct voctrl_get_equalizer_args *args = data;
+	 return vo_xv_get_eq(xv_port, args->name, args->valueptr);
       }
       case VOCTRL_UPDATE_SCREENINFO:
          update_xinerama_info();
diff --git a/libvo/vosub_vidix.c b/libvo/vosub_vidix.c
index 0357fe3..83a7fcc 100644
--- a/libvo/vosub_vidix.c
+++ b/libvo/vosub_vidix.c
@@ -553,36 +553,31 @@ uint32_t vidix_control(uint32_t request, void *data, ...)
 	return VO_TRUE;
   case VOCTRL_SET_EQUALIZER:
   {
-    va_list ap;
-    int value;
     vidix_video_eq_t info;
 
     if(!video_on) return VO_FALSE;
-    va_start(ap, data);
-    value = va_arg(ap, int);
-    va_end(ap);
-    
-//    printf("vidix seteq %s -> %d  \n",data,value);
+
+    struct voctrl_set_equalizer_args *args = data;
     
     /* vidix eq ranges are -1000..1000 */
-    if (!strcasecmp(data, "brightness"))
+    if (!strcasecmp(args->name, "brightness"))
     {
-	info.brightness = value*10;
+	info.brightness = args->value*10;
 	info.cap = VEQ_CAP_BRIGHTNESS;
     }
-    else if (!strcasecmp(data, "contrast"))
+    else if (!strcasecmp(args->name, "contrast"))
     {
-	info.contrast = value*10;
+	info.contrast = args->value*10;
 	info.cap = VEQ_CAP_CONTRAST;
     }
-    else if (!strcasecmp(data, "saturation"))
+    else if (!strcasecmp(args->name, "saturation"))
     {
-	info.saturation = value*10;
+	info.saturation = args->value*10;
 	info.cap = VEQ_CAP_SATURATION;
     }
-    else if (!strcasecmp(data, "hue"))
+    else if (!strcasecmp(args->name, "hue"))
     {
-	info.hue = value*10;
+	info.hue = args->value*10;
 	info.cap = VEQ_CAP_HUE;
     }
 
@@ -592,38 +587,34 @@ uint32_t vidix_control(uint32_t request, void *data, ...)
   }
   case VOCTRL_GET_EQUALIZER:
   {
-    va_list ap;
-    int *value;
     vidix_video_eq_t info;
 
     if(!video_on) return VO_FALSE;
     if (vdlPlaybackGetEq(vidix_handler, &info) != 0)
 	return VO_FALSE;
 
-    va_start(ap, data);
-    value = va_arg(ap, int*);
-    va_end(ap);
+    struct voctrl_get_equalizer_args *args = data;
     
     /* vidix eq ranges are -1000..1000 */
-    if (!strcasecmp(data, "brightness"))
+    if (!strcasecmp(args->name, "brightness"))
     {
 	if (info.cap & VEQ_CAP_BRIGHTNESS)
-	    *value = info.brightness/10;
+	    *args->valueptr = info.brightness/10;
     }
-    else if (!strcasecmp(data, "contrast"))
+    else if (!strcasecmp(args->name, "contrast"))
     {
 	if (info.cap & VEQ_CAP_CONTRAST)
-	    *value = info.contrast/10;
+	    *args->valueptr = info.contrast/10;
     }
-    else if (!strcasecmp(data, "saturation"))
+    else if (!strcasecmp(args->name, "saturation"))
     {
 	if (info.cap & VEQ_CAP_SATURATION)
-	    *value = info.saturation/10;
+	    *args->valueptr = info.saturation/10;
     }
-    else if (!strcasecmp(data, "hue"))
+    else if (!strcasecmp(args->name, "hue"))
     {
 	if (info.cap & VEQ_CAP_HUE)
-	    *value = info.hue/10;
+	    *args->valueptr = info.hue/10;
     }
 
     return VO_TRUE;
-- 
1.5.4.5

Remove variable arguments from vo control() functions

No voctrl uses them any more, and using them would not be a good idea
because it makes forwarding arguments to other functions harder.
---
 libvo/mga_common.c         |    2 +-
 libvo/vesa_lvo.c           |    4 ++--
 libvo/video_out.h          |    2 +-
 libvo/video_out_internal.h |    2 +-
 libvo/vo_3dfx.c            |    2 +-
 libvo/vo_aa.c              |    2 +-
 libvo/vo_bl.c              |    2 +-
 libvo/vo_caca.c            |    2 +-
 libvo/vo_cvidix.c          |    2 +-
 libvo/vo_dfbmga.c          |    2 +-
 libvo/vo_dga.c             |    2 +-
 libvo/vo_directfb2.c       |    2 +-
 libvo/vo_directx.c         |    2 +-
 libvo/vo_dxr2.c            |    2 +-
 libvo/vo_dxr3.c            |    2 +-
 libvo/vo_fbdev.c           |    2 +-
 libvo/vo_fbdev2.c          |    2 +-
 libvo/vo_ggi.c             |    2 +-
 libvo/vo_gif89a.c          |    2 +-
 libvo/vo_gl.c              |    2 +-
 libvo/vo_gl2.c             |    2 +-
 libvo/vo_ivtv.c            |    2 +-
 libvo/vo_jpeg.c            |    2 +-
 libvo/vo_md5sum.c          |    2 +-
 libvo/vo_mpegpes.c         |    2 +-
 libvo/vo_null.c            |    2 +-
 libvo/vo_png.c             |    2 +-
 libvo/vo_pnm.c             |    2 +-
 libvo/vo_quartz.c          |    2 +-
 libvo/vo_s3fb.c            |    2 +-
 libvo/vo_sdl.c             |    2 +-
 libvo/vo_svga.c            |    2 +-
 libvo/vo_tdfx_vid.c        |    2 +-
 libvo/vo_tdfxfb.c          |    2 +-
 libvo/vo_tga.c             |    2 +-
 libvo/vo_v4l2.c            |    2 +-
 libvo/vo_vesa.c            |    2 +-
 libvo/vo_winvidix.c        |    2 +-
 libvo/vo_x11.c             |    2 +-
 libvo/vo_xover.c           |    3 +--
 libvo/vo_xv.c              |    2 +-
 libvo/vo_xvidix.c          |    2 +-
 libvo/vo_xvmc.c            |    2 +-
 libvo/vo_xvr100.c          |    2 +-
 libvo/vo_yuv4mpeg.c        |    2 +-
 libvo/vo_zr.c              |    2 +-
 libvo/vo_zr2.c             |    2 +-
 libvo/vosub_vidix.c        |    2 +-
 libvo/vosub_vidix.h        |    2 +-
 49 files changed, 50 insertions(+), 51 deletions(-)

diff --git a/libvo/mga_common.c b/libvo/mga_common.c
index 600e4e7..a95f690 100644
--- a/libvo/mga_common.c
+++ b/libvo/mga_common.c
@@ -229,7 +229,7 @@ static void mga_fullscreen()
 }
 #endif
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vesa_lvo.c b/libvo/vesa_lvo.c
index ea5ecc9..cbb4e80 100644
--- a/libvo/vesa_lvo.c
+++ b/libvo/vesa_lvo.c
@@ -43,7 +43,7 @@ static uint8_t *lvo_mem = NULL;
 static uint8_t next_frame;
 static mga_vid_config_t mga_vid_config;
 static unsigned image_bpp,image_height,image_width,src_format;
-uint32_t vlvo_control(uint32_t request, void *data, ...);
+uint32_t vlvo_control(uint32_t request, void *data);
 
 #define PIXEL_SIZE() ((video_mode_info.BitsPerPixel+7)/8)
 #define SCREEN_LINE_SIZE(pixel_size) (video_mode_info.XResolution*(pixel_size) )
@@ -303,7 +303,7 @@ uint32_t vlvo_query_info(uint32_t format)
   return VFCAP_CSP_SUPPORTED;
 }
 
-uint32_t vlvo_control(uint32_t request, void *data, ...)
+uint32_t vlvo_control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/video_out.h b/libvo/video_out.h
index ae9a1c3..06f9381 100644
--- a/libvo/video_out.h
+++ b/libvo/video_out.h
@@ -142,7 +142,7 @@ typedef struct vo_functions_s
 	/*
 	 * Control interface
 	 */
-	int (*control)(uint32_t request, void *data, ...);
+	int (*control)(uint32_t request, void *data);
 
         /*
          * Display a new RGB/BGR frame of the video to the screen.
diff --git a/libvo/video_out_internal.h b/libvo/video_out_internal.h
index 83f38d5..1bfb91d 100644
--- a/libvo/video_out_internal.h
+++ b/libvo/video_out_internal.h
@@ -30,7 +30,7 @@
 #include "libmpcodecs/mp_image.h"
 #include "geometry.h"
 
-static int control(uint32_t request, void *data, ...);
+static int control(uint32_t request, void *data);
 static int config(uint32_t width, uint32_t height, uint32_t d_width,
 		     uint32_t d_height, uint32_t fullscreen, char *title,
 		     uint32_t format);
diff --git a/libvo/vo_3dfx.c b/libvo/vo_3dfx.c
index d4612e7..dcb58d3 100644
--- a/libvo/vo_3dfx.c
+++ b/libvo/vo_3dfx.c
@@ -497,7 +497,7 @@ static int preinit(const char *arg)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_aa.c b/libvo/vo_aa.c
index 8ba01d6..f297e01 100644
--- a/libvo/vo_aa.c
+++ b/libvo/vo_aa.c
@@ -718,7 +718,7 @@ static int preinit(const char *arg)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_bl.c b/libvo/vo_bl.c
index f99599f..1aaa5c8 100644
--- a/libvo/vo_bl.c
+++ b/libvo/vo_bl.c
@@ -465,7 +465,7 @@ static int preinit(const char *arg) {
 	return 0;
 }
 
-static int control(uint32_t request, void *data, ...) {
+static int control(uint32_t request, void *data) {
 	switch (request) {
 		case VOCTRL_QUERY_FORMAT:
 			return query_format(*((uint32_t*)data));
diff --git a/libvo/vo_caca.c b/libvo/vo_caca.c
index 3fd1fcd..46dab1d 100644
--- a/libvo/vo_caca.c
+++ b/libvo/vo_caca.c
@@ -322,7 +322,7 @@ static int query_format(uint32_t format)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
     switch(request)
     {
diff --git a/libvo/vo_cvidix.c b/libvo/vo_cvidix.c
index 9b6c593..3e54616 100644
--- a/libvo/vo_cvidix.c
+++ b/libvo/vo_cvidix.c
@@ -156,7 +156,7 @@ static int preinit(const char *arg){
   return 0;
 }
 
-static int control(uint32_t request, void *data, ...){
+static int control(uint32_t request, void *data){
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
     return query_format(*((uint32_t*)data));
diff --git a/libvo/vo_dfbmga.c b/libvo/vo_dfbmga.c
index ee3bf74..d829dc2 100644
--- a/libvo/vo_dfbmga.c
+++ b/libvo/vo_dfbmga.c
@@ -1381,7 +1381,7 @@ get_equalizer( char *data, int *value )
 }
 
 static int
-control( uint32_t request, void *data, ... )
+control( uint32_t request, void *data)
 {
      switch (request) {
      case VOCTRL_GUISUPPORT:
diff --git a/libvo/vo_dga.c b/libvo/vo_dga.c
index 1a2d510..b4e5483 100644
--- a/libvo/vo_dga.c
+++ b/libvo/vo_dga.c
@@ -973,7 +973,7 @@ static uint32_t get_image(mp_image_t * mpi)
     return (VO_FALSE);
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
     switch (request)
     {
diff --git a/libvo/vo_directfb2.c b/libvo/vo_directfb2.c
index a9bc40c..b8acb74 100644
--- a/libvo/vo_directfb2.c
+++ b/libvo/vo_directfb2.c
@@ -1411,7 +1411,7 @@ static uint32_t put_image(mp_image_t *mpi){
 
 
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
     case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_directx.c b/libvo/vo_directx.c
index a110c48..a241631 100644
--- a/libvo/vo_directx.c
+++ b/libvo/vo_directx.c
@@ -1472,7 +1472,7 @@ static uint32_t color_ctrl_get(char *what, int *value)
 	return r;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
     switch (request) {
    
diff --git a/libvo/vo_dxr2.c b/libvo/vo_dxr2.c
index 93ad86f..4b0d473 100644
--- a/libvo/vo_dxr2.c
+++ b/libvo/vo_dxr2.c
@@ -906,7 +906,7 @@ static int preinit(const char *arg) {
   return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_dxr3.c b/libvo/vo_dxr3.c
index a48c7be..0a5e2b4 100644
--- a/libvo/vo_dxr3.c
+++ b/libvo/vo_dxr3.c
@@ -162,7 +162,7 @@ static overlay_t *overlay_data;
 /* Functions for working with the em8300's internal clock */
 /* End of internal clock functions */
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
 	switch (request) {
 	case VOCTRL_GUISUPPORT:
diff --git a/libvo/vo_fbdev.c b/libvo/vo_fbdev.c
index 12f48fd..1f99ef0 100644
--- a/libvo/vo_fbdev.c
+++ b/libvo/vo_fbdev.c
@@ -1163,7 +1163,7 @@ static uint32_t get_image(mp_image_t *mpi)
     return(VO_TRUE);
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_GET_IMAGE:
diff --git a/libvo/vo_fbdev2.c b/libvo/vo_fbdev2.c
index 30bbc35..0b6fda1 100644
--- a/libvo/vo_fbdev2.c
+++ b/libvo/vo_fbdev2.c
@@ -398,7 +398,7 @@ static void uninit(void)
 	fb_preinit(1); // so that later calls to preinit don't fail
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_ggi.c b/libvo/vo_ggi.c
index ad28aeb..009c3c2 100644
--- a/libvo/vo_ggi.c
+++ b/libvo/vo_ggi.c
@@ -452,7 +452,7 @@ static void uninit(void)
     ggiExit();
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
     switch (request) {
     case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_gif89a.c b/libvo/vo_gif89a.c
index 6422ec7..58da54e 100644
--- a/libvo/vo_gif89a.c
+++ b/libvo/vo_gif89a.c
@@ -336,7 +336,7 @@ static int query_format(uint32_t format)
 	return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
 	if (request == VOCTRL_QUERY_FORMAT) {
 		return query_format(*((uint32_t*)data));
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index 36fbff4..036974c 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -887,7 +887,7 @@ static int preinit(const char *arg)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_PAUSE: return (int_pause=1);
diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c
index d83c5a3..735e291 100644
--- a/libvo/vo_gl2.c
+++ b/libvo/vo_gl2.c
@@ -867,7 +867,7 @@ static int preinit(const char *arg)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
     case VOCTRL_PAUSE: return (int_pause=1);
diff --git a/libvo/vo_ivtv.c b/libvo/vo_ivtv.c
index 4396dc1..36efe18 100644
--- a/libvo/vo_ivtv.c
+++ b/libvo/vo_ivtv.c
@@ -282,7 +282,7 @@ query_format (uint32_t format)
 }
 
 static int
-control (uint32_t request, void *data, ...)
+control (uint32_t request, void *data)
 {
   switch (request)
   {
diff --git a/libvo/vo_jpeg.c b/libvo/vo_jpeg.c
index e8ac699..e103f87 100644
--- a/libvo/vo_jpeg.c
+++ b/libvo/vo_jpeg.c
@@ -405,7 +405,7 @@ static int preinit(const char *arg)
 
 /* ------------------------------------------------------------------------- */
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
     switch (request) {
         case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_md5sum.c b/libvo/vo_md5sum.c
index 29f54a9..8c4aca2 100644
--- a/libvo/vo_md5sum.c
+++ b/libvo/vo_md5sum.c
@@ -263,7 +263,7 @@ static int query_format(uint32_t format)
 
 /* ------------------------------------------------------------------------- */
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
     switch (request) {
         case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_mpegpes.c b/libvo/vo_mpegpes.c
index d251ff7..27f002e 100644
--- a/libvo/vo_mpegpes.c
+++ b/libvo/vo_mpegpes.c
@@ -255,7 +255,7 @@ static void check_events(void)
 {
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_null.c b/libvo/vo_null.c
index c56a265..6f45af0 100644
--- a/libvo/vo_null.c
+++ b/libvo/vo_null.c
@@ -98,7 +98,7 @@ static int preinit(const char *arg)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_png.c b/libvo/vo_png.c
index 791dfd5..3c5f109 100644
--- a/libvo/vo_png.c
+++ b/libvo/vo_png.c
@@ -223,7 +223,7 @@ static int preinit(const char *arg)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_DRAW_IMAGE:
diff --git a/libvo/vo_pnm.c b/libvo/vo_pnm.c
index df1a070..878f063 100644
--- a/libvo/vo_pnm.c
+++ b/libvo/vo_pnm.c
@@ -543,7 +543,7 @@ static int query_format(uint32_t format)
 
 /* ------------------------------------------------------------------------- */
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
     switch (request) {
         case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_quartz.c b/libvo/vo_quartz.c
index 240291b..40e7049 100644
--- a/libvo/vo_quartz.c
+++ b/libvo/vo_quartz.c
@@ -1232,7 +1232,7 @@ static uint32_t get_yuv_image(mp_image_t *mpi)
 	return VO_FALSE;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
 	switch (request)
 	{
diff --git a/libvo/vo_s3fb.c b/libvo/vo_s3fb.c
index 778374e..e36348e 100644
--- a/libvo/vo_s3fb.c
+++ b/libvo/vo_s3fb.c
@@ -504,7 +504,7 @@ static uint32_t get_image(mp_image_t *mpi)
   return VO_TRUE;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch(request) {
   case VOCTRL_GET_IMAGE:
diff --git a/libvo/vo_sdl.c b/libvo/vo_sdl.c
index 5d4b157..ca05ba4 100644
--- a/libvo/vo_sdl.c
+++ b/libvo/vo_sdl.c
@@ -1660,7 +1660,7 @@ static uint32_t get_image(mp_image_t *mpi)
     return VO_FALSE;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   struct sdl_priv_s *priv = &sdl_priv;
   switch (request) {
diff --git a/libvo/vo_svga.c b/libvo/vo_svga.c
index 9d38c8d..31b103f 100644
--- a/libvo/vo_svga.c
+++ b/libvo/vo_svga.c
@@ -350,7 +350,7 @@ static int find_best_svga_mode(int req_w,int req_h, int req_bpp){
   return bestmode;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
     case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_tdfx_vid.c b/libvo/vo_tdfx_vid.c
index 522f5e9..501017f 100644
--- a/libvo/vo_tdfx_vid.c
+++ b/libvo/vo_tdfx_vid.c
@@ -646,7 +646,7 @@ static uint32_t set_colorkey(mp_colorkey_t* colork) {
   return VO_TRUE;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_tdfxfb.c b/libvo/vo_tdfxfb.c
index 6cdb075..fb825c3 100644
--- a/libvo/vo_tdfxfb.c
+++ b/libvo/vo_tdfxfb.c
@@ -478,7 +478,7 @@ static uint32_t get_image(mp_image_t *mpi)
 	return VO_TRUE;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
 	switch(request) {
 	case VOCTRL_GET_IMAGE:
diff --git a/libvo/vo_tga.c b/libvo/vo_tga.c
index 0977f91..3a1d1fb 100644
--- a/libvo/vo_tga.c
+++ b/libvo/vo_tga.c
@@ -242,7 +242,7 @@ static int preinit(const char *arg)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
       case VOCTRL_DRAW_IMAGE:
diff --git a/libvo/vo_v4l2.c b/libvo/vo_v4l2.c
index cb09d3f..bce01f5 100644
--- a/libvo/vo_v4l2.c
+++ b/libvo/vo_v4l2.c
@@ -250,7 +250,7 @@ query_format (uint32_t format)
 }
 
 static int
-control (uint32_t request, void *data, ...)
+control (uint32_t request, void *data)
 {
   switch (request)
   {
diff --git a/libvo/vo_vesa.c b/libvo/vo_vesa.c
index f5eb0e1..f5a40d2 100644
--- a/libvo/vo_vesa.c
+++ b/libvo/vo_vesa.c
@@ -1090,7 +1090,7 @@ static int preinit(const char *arg)
   return pre_init_err;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_winvidix.c b/libvo/vo_winvidix.c
index 97ff41d..a66b062 100644
--- a/libvo/vo_winvidix.c
+++ b/libvo/vo_winvidix.c
@@ -329,7 +329,7 @@ static int preinit(const char *arg){
     return(0);
 }
 
-static int control(uint32_t request, void *data, ...){
+static int control(uint32_t request, void *data){
   switch (request) {
   case VOCTRL_FULLSCREEN:
     if(!vo_fs){vo_fs=1;ShowWindow(hWndFS,SW_SHOW);SetForegroundWindow(hWndFS);}  
diff --git a/libvo/vo_x11.c b/libvo/vo_x11.c
index 2b56ee4..cc9ca02 100644
--- a/libvo/vo_x11.c
+++ b/libvo/vo_x11.c
@@ -748,7 +748,7 @@ static int preinit(const char *arg)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
     switch (request)
     {
diff --git a/libvo/vo_xover.c b/libvo/vo_xover.c
index 46f8f83..77d8306 100644
--- a/libvo/vo_xover.c
+++ b/libvo/vo_xover.c
@@ -427,7 +427,7 @@ static int preinit(const char *arg)
   return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   if(!sub_vo) return VO_ERROR;
   switch (request) {
@@ -449,7 +449,6 @@ static int control(uint32_t request, void *data, ...)
       }
     return VO_TRUE;
   default:
-    // Safe atm bcs nothing use more than 1 arg
     return sub_vo->control(request,data);
   }
   return VO_NOTIMPL;
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index 36d4d67..bdb4d6b 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -839,7 +839,7 @@ static int preinit(const char *arg)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
     switch (request)
     {
diff --git a/libvo/vo_xvidix.c b/libvo/vo_xvidix.c
index fdd82d8..260cdc9 100644
--- a/libvo/vo_xvidix.c
+++ b/libvo/vo_xvidix.c
@@ -470,7 +470,7 @@ static int preinit(const char *arg)
     return (0);
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
     switch (request)
     {
diff --git a/libvo/vo_xvmc.c b/libvo/vo_xvmc.c
index efa4e5d..d287510 100644
--- a/libvo/vo_xvmc.c
+++ b/libvo/vo_xvmc.c
@@ -1355,7 +1355,7 @@ assert(rndr->next_free_data_block_num == 0);
 return VO_TRUE;   
 }
 
-static int control(uint32_t request, void *data, ... )
+static int control(uint32_t request, void *data)
 {
    switch (request){
       case VOCTRL_GET_DEINTERLACE:
diff --git a/libvo/vo_xvr100.c b/libvo/vo_xvr100.c
index ff92018..a22a655 100644
--- a/libvo/vo_xvr100.c
+++ b/libvo/vo_xvr100.c
@@ -429,7 +429,7 @@ static int query_format(uint32_t format)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
     switch (request) {
         case VOCTRL_GET_IMAGE:
diff --git a/libvo/vo_yuv4mpeg.c b/libvo/vo_yuv4mpeg.c
index 2858462..759f053 100644
--- a/libvo/vo_yuv4mpeg.c
+++ b/libvo/vo_yuv4mpeg.c
@@ -538,7 +538,7 @@ static int preinit(const char *arg)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_zr.c b/libvo/vo_zr.c
index 26d868f..3f67d94 100644
--- a/libvo/vo_zr.c
+++ b/libvo/vo_zr.c
@@ -814,7 +814,7 @@ static int preinit(const char *arg)
     return 0;
 }
 
-static int control(uint32_t request, void *data, ...)
+static int control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vo_zr2.c b/libvo/vo_zr2.c
index 362ae49..c50e95c 100644
--- a/libvo/vo_zr2.c
+++ b/libvo/vo_zr2.c
@@ -433,7 +433,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
 	return 0;
 }
 
-static int control(uint32_t request, void *data, ...) {
+static int control(uint32_t request, void *data) {
 	switch (request) {
   		case VOCTRL_QUERY_FORMAT:
 			return query_format(*((uint32_t*)data));
diff --git a/libvo/vosub_vidix.c b/libvo/vosub_vidix.c
index 83a7fcc..2291814 100644
--- a/libvo/vosub_vidix.c
+++ b/libvo/vosub_vidix.c
@@ -533,7 +533,7 @@ static uint32_t vidix_get_image(mp_image_t *mpi)
     return VO_FALSE;
 }
 
-uint32_t vidix_control(uint32_t request, void *data, ...)
+uint32_t vidix_control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vosub_vidix.h b/libvo/vosub_vidix.h
index c6427be..0c2e30d 100644
--- a/libvo/vosub_vidix.h
+++ b/libvo/vosub_vidix.h
@@ -24,7 +24,7 @@ int      vidix_init(unsigned src_width,unsigned src_height,
 int	 vidix_start(void);
 int	 vidix_stop(void);
 void     vidix_term( void );
-uint32_t vidix_control(uint32_t request, void *data, ...);
+uint32_t vidix_control(uint32_t request, void *data);
 uint32_t vidix_query_fourcc(uint32_t fourcc);
 
 uint32_t vidix_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y);
-- 
1.5.4.5

video_out.c: Clean up some code

No functionality changes.
---
 libvo/video_out.c |  123 +++++++++++++++++++++++++++--------------------------
 1 files changed, 63 insertions(+), 60 deletions(-)

diff --git a/libvo/video_out.c b/libvo/video_out.c
index 762ef7c..3057502 100644
--- a/libvo/video_out.c
+++ b/libvo/video_out.c
@@ -1,5 +1,5 @@
 
-/* this file contains libvo's common functions, variables used by 
+/* this file contains libvo's common functions, variables used by
    many/all drivers. */
 
 #include <stdio.h>
@@ -153,7 +153,7 @@ const vo_functions_t* const video_out_drivers[] =
         &video_out_xover,
 #endif
 #ifdef HAVE_GL
-	        &video_out_gl,
+        &video_out_gl,
         &video_out_gl2,
 #endif
 #ifdef HAVE_DGA
@@ -224,7 +224,7 @@ const vo_functions_t* const video_out_drivers[] =
 	&video_out_yuv4mpeg,
 #ifdef HAVE_PNG
 	&video_out_png,
-#endif	
+#endif
 #ifdef HAVE_JPEG
 	&video_out_jpeg,
 #endif
@@ -243,54 +243,56 @@ const vo_functions_t* const video_out_drivers[] =
         NULL
 };
 
-void list_video_out(void){
-      int i=0;
-      mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_AvailableVideoOutputDrivers);
-      mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_OUTPUTS\n");
-      while (video_out_drivers[i]) {
+void list_video_out(void)
+{
+    int i = 0;
+    mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_AvailableVideoOutputDrivers);
+    mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_OUTPUTS\n");
+    while (video_out_drivers[i]) {
         const vo_info_t *info = video_out_drivers[i++]->info;
-      	mp_msg(MSGT_GLOBAL, MSGL_INFO,"\t%s\t%s\n", info->short_name, info->name);
-      }
-      mp_msg(MSGT_GLOBAL, MSGL_INFO,"\n");
+        mp_msg(MSGT_GLOBAL, MSGL_INFO,"\t%s\t%s\n", info->short_name, info->name);
+    }
+    mp_msg(MSGT_GLOBAL, MSGL_INFO,"\n");
 }
 
-const vo_functions_t* init_best_video_out(char** vo_list){
+const vo_functions_t *init_best_video_out(char **vo_list)
+{
     int i;
     // first try the preferred drivers, with their optional subdevice param:
-    if(vo_list && vo_list[0])
-      while(vo_list[0][0]){
-        char* vo=strdup(vo_list[0]);
-	vo_subdevice=strchr(vo,':');
-	if (!strcmp(vo, "pgm"))
-	    mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_VO_PGM_HasBeenReplaced);
-	if (!strcmp(vo, "md5"))
-	    mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_VO_MD5_HasBeenReplaced);
-	if(vo_subdevice){
-	    vo_subdevice[0]=0;
-	    ++vo_subdevice;
-	}
-	for(i=0;video_out_drivers[i];i++){
-	    const vo_functions_t* video_driver=video_out_drivers[i];
-	    const vo_info_t *info = video_driver->info;
-	    if(!strcmp(info->short_name,vo)){
-		// name matches, try it
-		if(!video_driver->preinit(vo_subdevice))
-		{
-		    free(vo);
-		    return video_driver; // success!
+    if (vo_list && vo_list[0])
+        while (vo_list[0][0]) {
+            char *name = strdup(vo_list[0]);
+            vo_subdevice = strchr(name,':');
+            if (!strcmp(name, "pgm"))
+                mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_VO_PGM_HasBeenReplaced);
+            if (!strcmp(name, "md5"))
+                mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_VO_MD5_HasBeenReplaced);
+            if (vo_subdevice) {
+                vo_subdevice[0] = 0;
+                ++vo_subdevice;
+            }
+            for (i = 0; video_out_drivers[i]; i++) {
+                const vo_functions_t *video_driver = video_out_drivers[i];
+                const vo_info_t *info = video_driver->info;
+                if (!strcmp(info->short_name, name)) {
+                    // name matches, try it
+                    if (!video_driver->preinit(vo_subdevice)) {
+                        free(name);
+                        return video_driver; // success!
+                    }
 		}
 	    }
+            // continue...
+            free(name);
+            ++vo_list;
+            if (!(vo_list[0]))
+                return NULL; // do NOT fallback to others
 	}
-        // continue...
-	free(vo);
-	++vo_list;
-	if(!(vo_list[0])) return NULL; // do NOT fallback to others
-      }
     // now try the rest...
-    vo_subdevice=NULL;
-    for(i=0;video_out_drivers[i];i++){
-	const vo_functions_t* video_driver=video_out_drivers[i];
-	if(!video_driver->preinit(vo_subdevice))
+    vo_subdevice = NULL;
+    for (i = 0; video_out_drivers[i]; i++) {
+        const vo_functions_t *video_driver = video_out_drivers[i];
+        if (!video_driver->preinit(vo_subdevice))
 	    return video_driver; // success!
     }
     return NULL;
@@ -298,28 +300,29 @@ const vo_functions_t* init_best_video_out(char** vo_list){
 
 int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height,
                      uint32_t d_width, uint32_t d_height, uint32_t flags,
-                     char *title, uint32_t format) {
-  panscan_init();
-  aspect_save_orig(width,height);
-  aspect_save_prescale(d_width,d_height);
-
-  if (vo->control(VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) {
-  aspect(&d_width,&d_height,A_NOZOOM);
-  vo_dx = (int)(vo_screenwidth - d_width) / 2;
-  vo_dy = (int)(vo_screenheight - d_height) / 2;
-  geometry(&vo_dx, &vo_dy, &d_width, &d_height,
-           vo_screenwidth, vo_screenheight);
-  vo_dx += xinerama_x;
-  vo_dy += xinerama_y;
-  vo_dwidth = d_width;
-  vo_dheight = d_height;
-  }
-
-  return vo->config(width, height, d_width, d_height, flags, title, format);
+                     char *title, uint32_t format)
+{
+    panscan_init();
+    aspect_save_orig(width, height);
+    aspect_save_prescale(d_width, d_height);
+
+    if (vo->control(VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) {
+        aspect(&d_width, &d_height, A_NOZOOM);
+        vo_dx = (int)(vo_screenwidth - d_width) / 2;
+        vo_dy = (int)(vo_screenheight - d_height) / 2;
+        geometry(&vo_dx, &vo_dy, &d_width, &d_height,
+                 vo_screenwidth, vo_screenheight);
+        vo_dx += xinerama_x;
+        vo_dy += xinerama_y;
+        vo_dwidth = d_width;
+        vo_dheight = d_height;
+    }
+
+    return vo->config(width, height, d_width, d_height, flags, title, format);
 }
 
-#if defined(HAVE_FBDEV)||defined(HAVE_VESA)  
-/* Borrowed from vo_fbdev.c 
+#if defined(HAVE_FBDEV)||defined(HAVE_VESA)
+/* Borrowed from vo_fbdev.c
 Monitor ranges related functions*/
 
 char *monitor_hfreq_str = NULL;
-- 
1.5.4.5

Add new video driver API

Create new video driver API that has a per-instance context structure
and does not rely on keeping status in global or static variables.
Existing drivers are not yet converted to this API; instead there is a
wrapper which translates calls to them.

In the new API, an old API call vo_functions->xyz(args) is generally
replaced by vo_xyz(vo_instance, args).

The changes to keep the vesa, dxr2, xover and vidix drivers compiling
have not been tested.
---
 command.c                  |   10 ++--
 libmenu/vf_menu.c          |    4 +-
 libmpcodecs/vf_vo.c        |   44 +++++-------
 libvo/Makefile             |    1 +
 libvo/old_vo_wrapper.c     |   80 +++++++++++++++++++++
 libvo/old_vo_wrapper.h     |   15 ++++
 libvo/vesa_lvo.c           |   12 ++--
 libvo/vesa_lvo.h           |    4 +-
 libvo/video_out.c          |  170 ++++++++++++++++++++++++++++---------------
 libvo/video_out.h          |   69 ++++++++++++++----
 libvo/video_out_internal.h |   19 ++++-
 libvo/vo_dxr2.c            |   12 ++--
 libvo/vo_xover.c           |   41 ++++++-----
 libvo/vosub_vidix.c        |   15 ++--
 libvo/vosub_vidix.h        |    6 +-
 mencoder.c                 |   15 +++--
 mp_core.h                  |    2 +-
 mplayer.c                  |   19 +++--
 spudec.c                   |   10 ++--
 spudec.h                   |    2 +-
 20 files changed, 378 insertions(+), 172 deletions(-)
 create mode 100644 libvo/old_vo_wrapper.c
 create mode 100644 libvo/old_vo_wrapper.h

diff --git a/command.c b/command.c
index 7ccd0ec..4461984 100644
--- a/command.c
+++ b/command.c
@@ -976,7 +976,7 @@ static int mp_property_fullscreen(m_option_t * prop, int action, void *arg,
 	else
 #endif
 	if (vo_config_count)
-	    mpctx->video_out->control(VOCTRL_FULLSCREEN, 0);
+	    vo_control(mpctx->video_out, VOCTRL_FULLSCREEN, 0);
 	return M_PROPERTY_OK;
     default:
 	return m_property_flag(prop, action, arg, &vo_fs);
@@ -1019,7 +1019,7 @@ static int mp_property_panscan(m_option_t * prop, int action, void *arg,
 {
 
     if (!mpctx->video_out
-	|| mpctx->video_out->control(VOCTRL_GET_PANSCAN, NULL) != VO_TRUE)
+	|| vo_control(mpctx->video_out, VOCTRL_GET_PANSCAN, NULL) != VO_TRUE)
 	return M_PROPERTY_UNAVAILABLE;
 
     switch (action) {
@@ -1028,7 +1028,7 @@ static int mp_property_panscan(m_option_t * prop, int action, void *arg,
 	    return M_PROPERTY_ERROR;
 	M_PROPERTY_CLAMP(prop, *(float *) arg);
 	vo_panscan = *(float *) arg;
-	mpctx->video_out->control(VOCTRL_SET_PANSCAN, NULL);
+	vo_control(mpctx->video_out, VOCTRL_SET_PANSCAN, NULL);
 	return M_PROPERTY_OK;
     case M_PROPERTY_STEP_UP:
     case M_PROPERTY_STEP_DOWN:
@@ -1038,7 +1038,7 @@ static int mp_property_panscan(m_option_t * prop, int action, void *arg,
 	    vo_panscan = 1;
 	else if (vo_panscan < 0)
 	    vo_panscan = 0;
-	mpctx->video_out->control(VOCTRL_SET_PANSCAN, NULL);
+	vo_control(mpctx->video_out, VOCTRL_SET_PANSCAN, NULL);
 	return M_PROPERTY_OK;
     default:
 	return m_property_float_range(prop, action, arg, &vo_panscan);
@@ -1065,7 +1065,7 @@ static int mp_property_vo_flag(m_option_t * prop, int action, void *arg,
     case M_PROPERTY_STEP_UP:
     case M_PROPERTY_STEP_DOWN:
 	if (vo_config_count)
-	    mpctx->video_out->control(vo_ctrl, 0);
+	    vo_control(mpctx->video_out, vo_ctrl, 0);
 	return M_PROPERTY_OK;
     default:
 	return m_property_flag(prop, action, arg, vo_var);
diff --git a/libmenu/vf_menu.c b/libmenu/vf_menu.c
index b2ba92e..ea63527 100644
--- a/libmenu/vf_menu.c
+++ b/libmenu/vf_menu.c
@@ -44,12 +44,12 @@ struct vf_priv_s {
 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts);
 
 void vf_menu_pause_update(struct vf_instance_s* vf) {
-  const vo_functions_t *video_out = mpctx_get_video_out(vf->priv->current->ctx);
+  const struct vo *video_out = mpctx_get_video_out(vf->priv->current->ctx);
   if(pause_mpi) {
     put_image(vf,pause_mpi, MP_NOPTS_VALUE);
     // Don't draw the osd atm
     //vf->control(vf,VFCTRL_DRAW_OSD,NULL);
-    video_out->flip_page();
+    vo_flip_page(video_out);
   }
 }
 
diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c
index 877826e..5074148 100644
--- a/libmpcodecs/vf_vo.c
+++ b/libmpcodecs/vf_vo.c
@@ -23,7 +23,7 @@ extern float sub_delay;
 
 struct vf_priv_s {
     double pts;
-    const vo_functions_t *vo;
+    struct vo *vo;
 #ifdef USE_ASS
     ass_renderer_t* ass_priv;
     int prev_visibility;
@@ -43,8 +43,7 @@ static int config(struct vf_instance_s* vf,
 	return 0;
     }
 
-  if(video_out->info)
-  { const vo_info_t *info = video_out->info;
+    const vo_info_t *info = video_out->driver->info;
     mp_msg(MSGT_CPLAYER,MSGL_INFO,"VO: [%s] %dx%d => %dx%d %s %s%s%s%s\n",info->short_name,
          width, height,
          d_width, d_height,
@@ -57,12 +56,11 @@ static int config(struct vf_instance_s* vf,
     mp_msg(MSGT_CPLAYER,MSGL_V,"VO: Author: %s\n", info->author);
     if(info->comment && strlen(info->comment) > 0)
         mp_msg(MSGT_CPLAYER,MSGL_V,"VO: Comment: %s\n", info->comment);
-  }
 
     // save vo's stride capability for the wanted colorspace:
     vf->default_caps=query_format(vf,outfmt);
 
-    if(config_video_out(video_out,width,height,d_width,d_height,flags,"MPlayer",outfmt))
+    if (vo_config(video_out, width, height, d_width, d_height, flags, "MPlayer", outfmt))
 	return 0;
 
 #ifdef USE_ASS
@@ -80,23 +78,21 @@ static int control(struct vf_instance_s* vf, int request, void* data)
     case VFCTRL_GET_DEINTERLACE:
     {
         if(!video_out) return CONTROL_FALSE; // vo not configured?
-        return(video_out->control(VOCTRL_GET_DEINTERLACE, data)
-                == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE;
+        return vo_control(video_out, VOCTRL_GET_DEINTERLACE, data) == VO_TRUE;
     }
     case VFCTRL_SET_DEINTERLACE:
     {
         if(!video_out) return CONTROL_FALSE; // vo not configured?
-        return(video_out->control(VOCTRL_SET_DEINTERLACE, data)
-                == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE;
+        return vo_control(video_out, VOCTRL_SET_DEINTERLACE, data) == VO_TRUE;
     }
     case VFCTRL_DRAW_OSD:
 	if(!vo_config_count) return CONTROL_FALSE; // vo not configured?
-	video_out->draw_osd();
+	vo_draw_osd(video_out);
 	return CONTROL_TRUE;
     case VFCTRL_FLIP_PAGE:
     {
 	if(!vo_config_count) return CONTROL_FALSE; // vo not configured?
-	video_out->flip_page();
+	vo_flip_page(video_out);
 	return CONTROL_TRUE;
     }
     case VFCTRL_SET_EQUALIZER:
@@ -104,14 +100,14 @@ static int control(struct vf_instance_s* vf, int request, void* data)
 	vf_equalizer_t *eq=data;
 	if(!vo_config_count) return CONTROL_FALSE; // vo not configured?
 	struct voctrl_set_equalizer_args param = {eq->item, eq->value};
-	return video_out->control(VOCTRL_SET_EQUALIZER, &param) == VO_TRUE;
+	return vo_control(video_out, VOCTRL_SET_EQUALIZER, &param) == VO_TRUE;
     }
     case VFCTRL_GET_EQUALIZER:
     {
 	vf_equalizer_t *eq=data;
 	if(!vo_config_count) return CONTROL_FALSE; // vo not configured?
 	struct voctrl_get_equalizer_args param = {eq->item, &eq->value};
-	return video_out->control(VOCTRL_GET_EQUALIZER, &param) == VO_TRUE;
+	return vo_control(video_out, VOCTRL_GET_EQUALIZER, &param) == VO_TRUE;
     }
 #ifdef USE_ASS
     case VFCTRL_INIT_EOSD:
@@ -130,7 +126,7 @@ static int control(struct vf_instance_s* vf, int request, void* data)
         if (sub_visibility && vf->priv->ass_priv && ass_track && (pts != MP_NOPTS_VALUE)) {
             mp_eosd_res_t res;
             memset(&res, 0, sizeof(res));
-            if (video_out->control(VOCTRL_GET_EOSD_RES, &res) == VO_TRUE) {
+            if (vo_control(video_out, VOCTRL_GET_EOSD_RES, &res) == VO_TRUE) {
                 ass_set_frame_size(vf->priv->ass_priv, res.w, res.h);
                 ass_set_margins(vf->priv->ass_priv, res.mt, res.mb, res.ml, res.mr);
                 ass_set_aspect_ratio(vf->priv->ass_priv, (double)res.w / res.h);
@@ -143,7 +139,7 @@ static int control(struct vf_instance_s* vf, int request, void* data)
         } else
             vf->priv->prev_visibility = 0;
         vf->priv->prev_visibility = sub_visibility;
-        return (video_out->control(VOCTRL_DRAW_EOSD, &images) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE;
+        return vo_control(video_out, VOCTRL_DRAW_EOSD, &images) == VO_TRUE;
     }
 #endif
     case VFCTRL_GET_PTS:
@@ -152,12 +148,11 @@ static int control(struct vf_instance_s* vf, int request, void* data)
 	return CONTROL_TRUE;
     }
     }
-    // return video_out->control(request,data);
     return CONTROL_UNKNOWN;
 }
 
 static int query_format(struct vf_instance_s* vf, unsigned int fmt){
-    int flags=video_out->control(VOCTRL_QUERY_FORMAT,&fmt);
+    int flags = vo_control(video_out, VOCTRL_QUERY_FORMAT, &fmt);
     // draw_slice() accepts stride, draw_frame() doesn't:
     if(flags)
 	if(fmt==IMGFMT_YV12 || fmt==IMGFMT_I420 || fmt==IMGFMT_IYUV)
@@ -168,7 +163,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){
 static void get_image(struct vf_instance_s* vf,
         mp_image_t *mpi){
     if(vo_directrendering && vo_config_count)
-	video_out->control(VOCTRL_GET_IMAGE,mpi);
+	vo_control(video_out, VOCTRL_GET_IMAGE, mpi);
 }
 
 static int put_image(struct vf_instance_s* vf,
@@ -177,15 +172,15 @@ static int put_image(struct vf_instance_s* vf,
   // record pts (potentially modified by filters) for main loop
   vf->priv->pts = pts;
   // first check, maybe the vo/vf plugin implements draw_image using mpi:
-  if(video_out->control(VOCTRL_DRAW_IMAGE,mpi)==VO_TRUE) return 1; // done.
+  if (vo_control(video_out, VOCTRL_DRAW_IMAGE,mpi)==VO_TRUE) return 1; // done.
   // nope, fallback to old draw_frame/draw_slice:
   if(!(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK))){
     // blit frame:
 //    if(mpi->flags&MP_IMGFLAG_PLANAR)
     if(vf->default_caps&VFCAP_ACCEPT_STRIDE)
-        video_out->draw_slice(mpi->planes,mpi->stride,mpi->w,mpi->h,mpi->x,mpi->y);
+        vo_draw_slice(video_out, mpi->planes,mpi->stride,mpi->w,mpi->h,mpi->x,mpi->y);
     else
-        video_out->draw_frame(mpi->planes);
+        vo_draw_frame(video_out, mpi->planes);
   }
   return 1;
 }
@@ -193,13 +188,13 @@ static int put_image(struct vf_instance_s* vf,
 static void start_slice(struct vf_instance_s* vf,
 		       mp_image_t *mpi) {
     if(!vo_config_count) return; // vo not configured?
-    video_out->control(VOCTRL_START_SLICE,mpi);
+    vo_control(video_out, VOCTRL_START_SLICE,mpi);
 }
 
 static void draw_slice(struct vf_instance_s* vf,
         unsigned char** src, int* stride, int w,int h, int x, int y){
     if(!vo_config_count) return; // vo not configured?
-    video_out->draw_slice(src,stride,w,h,x,y);
+    vo_draw_slice(video_out, src,stride,w,h,x,y);
 }
 
 static void uninit(struct vf_instance_s* vf)
@@ -224,9 +219,8 @@ static int open(vf_instance_t *vf, char* args){
     vf->start_slice=start_slice;
     vf->uninit=uninit;
     vf->priv=calloc(1, sizeof(struct vf_priv_s));
-    vf->priv->vo = (const vo_functions_t *)args;
+    vf->priv->vo = (struct vo *)args;
     if(!video_out) return 0; // no vo ?
-//    if(video_out->preinit(args)) return 0; // preinit failed
     return 1;
 }
 
diff --git a/libvo/Makefile b/libvo/Makefile
index cada614..cb82441 100644
--- a/libvo/Makefile
+++ b/libvo/Makefile
@@ -5,6 +5,7 @@ LIBNAME_MPLAYER = libvo.a
 
 SRCS_MPLAYER = aspect.c \
                geometry.c \
+               old_vo_wrapper.c \
                spuenc.c \
                video_out.c \
                vo_mpegpes.c \
diff --git a/libvo/old_vo_wrapper.c b/libvo/old_vo_wrapper.c
new file mode 100644
index 0000000..b526223
--- /dev/null
+++ b/libvo/old_vo_wrapper.c
@@ -0,0 +1,80 @@
+/*
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include <stdint.h>
+#include "old_vo_wrapper.h"
+#include "video_out.h"
+
+int old_vo_preinit(struct vo *vo, const char *arg)
+{
+    return vo->driver->old_functions->preinit(arg);
+}
+
+
+int old_vo_config(struct vo *vo, uint32_t width, uint32_t height,
+                         uint32_t d_width, uint32_t d_height,
+                         uint32_t flags, char *title, uint32_t format)
+{
+    return vo->driver->old_functions->config(width, height, d_width,
+                                             d_height, flags, title, format);
+}
+
+
+int old_vo_control(struct vo *vo, uint32_t request, void *data)
+{
+    return vo->driver->old_functions->control(request, data);
+}
+
+
+int old_vo_draw_frame(struct vo *vo, uint8_t *src[])
+{
+    return vo->driver->old_functions->draw_frame(src);
+}
+
+
+int old_vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[],
+                             int w, int h, int x, int y)
+{
+    return vo->driver->old_functions->draw_slice(src, stride, w, h, x, y);
+}
+
+
+void old_vo_draw_osd(struct vo *vo)
+{
+    vo->driver->old_functions->draw_osd();
+}
+
+
+void old_vo_flip_page(struct vo *vo)
+{
+    vo->driver->old_functions->flip_page();
+}
+
+
+void old_vo_check_events(struct vo *vo)
+{
+    vo->driver->old_functions->check_events();
+}
+
+
+void old_vo_uninit(struct vo *vo)
+{
+    vo->driver->old_functions->uninit();
+}
+
diff --git a/libvo/old_vo_wrapper.h b/libvo/old_vo_wrapper.h
new file mode 100644
index 0000000..e7ac158
--- /dev/null
+++ b/libvo/old_vo_wrapper.h
@@ -0,0 +1,15 @@
+#include <stdint.h>
+#include "video_out.h"
+
+int old_vo_preinit(struct vo *vo, const char *);
+int old_vo_config(struct vo *vo, uint32_t width, uint32_t height,
+                  uint32_t d_width, uint32_t d_height,
+                  uint32_t flags, char *title, uint32_t format);
+int old_vo_control(struct vo *vo, uint32_t request, void *data);
+int old_vo_draw_frame(struct vo *vo, uint8_t *src[]);
+int old_vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[],
+                      int w, int h, int x, int y);
+void old_vo_draw_osd(struct vo *vo);
+void old_vo_flip_page(struct vo *vo);
+void old_vo_check_events(struct vo *vo);
+void old_vo_uninit(struct vo *vo);
diff --git a/libvo/vesa_lvo.c b/libvo/vesa_lvo.c
index cbb4e80..fc15733 100644
--- a/libvo/vesa_lvo.c
+++ b/libvo/vesa_lvo.c
@@ -43,13 +43,13 @@ static uint8_t *lvo_mem = NULL;
 static uint8_t next_frame;
 static mga_vid_config_t mga_vid_config;
 static unsigned image_bpp,image_height,image_width,src_format;
-uint32_t vlvo_control(uint32_t request, void *data);
+int vlvo_control(uint32_t request, void *data);
 
 #define PIXEL_SIZE() ((video_mode_info.BitsPerPixel+7)/8)
 #define SCREEN_LINE_SIZE(pixel_size) (video_mode_info.XResolution*(pixel_size) )
 #define IMAGE_LINE_SIZE(pixel_size) (image_width*(pixel_size))
 
-extern vo_functions_t video_out_vesa;
+extern struct vo_old_functions video_out_vesa;
 
 int vlvo_preinit(const char *drvname)
 {
@@ -155,7 +155,7 @@ void vlvo_term( void )
 	if(lvo_handler != -1) close(lvo_handler);
 }
 
-uint32_t vlvo_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y)
+int vlvo_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y)
 {
     uint8_t *src;
     uint8_t *dest;
@@ -195,7 +195,7 @@ uint32_t vlvo_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,i
     return 0;
 }
 
-uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y)
+int vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y)
 {
  if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) {
    mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_draw_slice() was called\n");}
@@ -213,7 +213,7 @@ uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y
  return 0;
 }
 
-uint32_t vlvo_draw_frame(uint8_t *image[])
+int vlvo_draw_frame(uint8_t *image[])
 {
 /* Note it's very strange but sometime for YUY2 draw_frame is called */
   fast_memcpy(lvo_mem,image[0],mga_vid_config.frame_size);
@@ -303,7 +303,7 @@ uint32_t vlvo_query_info(uint32_t format)
   return VFCAP_CSP_SUPPORTED;
 }
 
-uint32_t vlvo_control(uint32_t request, void *data)
+int vlvo_control(uint32_t request, void *data)
 {
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
diff --git a/libvo/vesa_lvo.h b/libvo/vesa_lvo.h
index 67a9ee0..2581ace 100644
--- a/libvo/vesa_lvo.h
+++ b/libvo/vesa_lvo.h
@@ -21,8 +21,8 @@ int      vlvo_init(unsigned src_width,unsigned src_height,
 void     vlvo_term( void );
 uint32_t vlvo_query_info(uint32_t format);
 
-uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y);
-uint32_t vlvo_draw_frame(uint8_t *src[]);
+int vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y);
+int vlvo_draw_frame(uint8_t *src[]);
 void     vlvo_flip_page(void);
 void     vlvo_draw_osd(void);
 
diff --git a/libvo/video_out.c b/libvo/video_out.c
index 3057502..27472b1 100644
--- a/libvo/video_out.c
+++ b/libvo/video_out.c
@@ -66,54 +66,54 @@ int vo_colorkey = 0x0000ff00; // default colorkey is green
 //
 // Externally visible list of all vo drivers
 //
-extern vo_functions_t video_out_mga;
-extern vo_functions_t video_out_xmga;
-extern vo_functions_t video_out_x11;
-extern vo_functions_t video_out_xover;
-extern vo_functions_t video_out_xvmc;
-extern vo_functions_t video_out_xv;
-extern vo_functions_t video_out_gl;
-extern vo_functions_t video_out_gl2;
-extern vo_functions_t video_out_dga;
-extern vo_functions_t video_out_sdl;
-extern vo_functions_t video_out_3dfx;
-extern vo_functions_t video_out_tdfxfb;
-extern vo_functions_t video_out_s3fb;
-extern vo_functions_t video_out_null;
-extern vo_functions_t video_out_zr;
-extern vo_functions_t video_out_zr2;
-extern vo_functions_t video_out_bl;
-extern vo_functions_t video_out_fbdev;
-extern vo_functions_t video_out_fbdev2;
-extern vo_functions_t video_out_svga;
-extern vo_functions_t video_out_png;
-extern vo_functions_t video_out_ggi;
-extern vo_functions_t video_out_aa;
-extern vo_functions_t video_out_caca;
-extern vo_functions_t video_out_mpegpes;
-extern vo_functions_t video_out_yuv4mpeg;
-extern vo_functions_t video_out_directx;
-extern vo_functions_t video_out_dxr2;
-extern vo_functions_t video_out_dxr3;
-extern vo_functions_t video_out_ivtv;
-extern vo_functions_t video_out_v4l2;
-extern vo_functions_t video_out_jpeg;
-extern vo_functions_t video_out_gif89a;
-extern vo_functions_t video_out_vesa;
-extern vo_functions_t video_out_directfb;
-extern vo_functions_t video_out_dfbmga;
-extern vo_functions_t video_out_xvidix;
-extern vo_functions_t video_out_winvidix;
-extern vo_functions_t video_out_cvidix;
-extern vo_functions_t video_out_tdfx_vid;
-extern vo_functions_t video_out_xvr100;
-extern vo_functions_t video_out_tga;
-extern vo_functions_t video_out_macosx;
-extern vo_functions_t video_out_quartz;
-extern vo_functions_t video_out_pnm;
-extern vo_functions_t video_out_md5sum;
-
-const vo_functions_t* const video_out_drivers[] =
+extern struct vo_driver video_out_mga;
+extern struct vo_driver video_out_xmga;
+extern struct vo_driver video_out_x11;
+extern struct vo_driver video_out_xover;
+extern struct vo_driver video_out_xvmc;
+extern struct vo_driver video_out_xv;
+extern struct vo_driver video_out_gl;
+extern struct vo_driver video_out_gl2;
+extern struct vo_driver video_out_dga;
+extern struct vo_driver video_out_sdl;
+extern struct vo_driver video_out_3dfx;
+extern struct vo_driver video_out_tdfxfb;
+extern struct vo_driver video_out_s3fb;
+extern struct vo_driver video_out_null;
+extern struct vo_driver video_out_zr;
+extern struct vo_driver video_out_zr2;
+extern struct vo_driver video_out_bl;
+extern struct vo_driver video_out_fbdev;
+extern struct vo_driver video_out_fbdev2;
+extern struct vo_driver video_out_svga;
+extern struct vo_driver video_out_png;
+extern struct vo_driver video_out_ggi;
+extern struct vo_driver video_out_aa;
+extern struct vo_driver video_out_caca;
+extern struct vo_driver video_out_mpegpes;
+extern struct vo_driver video_out_yuv4mpeg;
+extern struct vo_driver video_out_directx;
+extern struct vo_driver video_out_dxr2;
+extern struct vo_driver video_out_dxr3;
+extern struct vo_driver video_out_ivtv;
+extern struct vo_driver video_out_v4l2;
+extern struct vo_driver video_out_jpeg;
+extern struct vo_driver video_out_gif89a;
+extern struct vo_driver video_out_vesa;
+extern struct vo_driver video_out_directfb;
+extern struct vo_driver video_out_dfbmga;
+extern struct vo_driver video_out_xvidix;
+extern struct vo_driver video_out_winvidix;
+extern struct vo_driver video_out_cvidix;
+extern struct vo_driver video_out_tdfx_vid;
+extern struct vo_driver video_out_xvr100;
+extern struct vo_driver video_out_tga;
+extern struct vo_driver video_out_macosx;
+extern struct vo_driver video_out_quartz;
+extern struct vo_driver video_out_pnm;
+extern struct vo_driver video_out_md5sum;
+
+const struct vo_driver *video_out_drivers[] =
 {
 #ifdef HAVE_XVR100
         &video_out_xvr100,
@@ -150,7 +150,7 @@ const vo_functions_t* const video_out_drivers[] =
 #endif
 #ifdef HAVE_X11
         &video_out_x11,
-        &video_out_xover,
+//        &video_out_xover,
 #endif
 #ifdef HAVE_GL
         &video_out_gl,
@@ -243,6 +243,51 @@ const vo_functions_t* const video_out_drivers[] =
         NULL
 };
 
+
+static int vo_preinit(struct vo *vo, const char *arg)
+{
+    return vo->driver->preinit(vo, arg);
+}
+
+int vo_control(struct vo *vo, uint32_t request, void *data)
+{
+    if (vo->driver->is_new)
+	return vo->driver->control(vo, request, data);
+    else
+	return vo->driver->old_functions->control(request, data);
+}
+
+int vo_draw_frame(struct vo *vo, uint8_t *src[])
+{
+    return vo->driver->draw_frame(vo, src);
+}
+
+int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y)
+{
+    return vo->driver->draw_slice(vo, src, stride, w, h, x, y);
+}
+
+void vo_draw_osd(struct vo *vo)
+{
+    vo->driver->draw_osd(vo);
+}
+
+void vo_flip_page(struct vo *vo)
+{
+    vo->driver->flip_page(vo);
+}
+
+void vo_check_events(struct vo *vo)
+{
+    vo->driver->check_events(vo);
+}
+
+void vo_destroy(struct vo *vo)
+{
+    vo->driver->uninit(vo);
+    free(vo);
+}
+
 void list_video_out(void)
 {
     int i = 0;
@@ -255,9 +300,10 @@ void list_video_out(void)
     mp_msg(MSGT_GLOBAL, MSGL_INFO,"\n");
 }
 
-const vo_functions_t *init_best_video_out(char **vo_list)
+struct vo *init_best_video_out(char **vo_list)
 {
     int i;
+    struct vo *vo = malloc(sizeof *vo);
     // first try the preferred drivers, with their optional subdevice param:
     if (vo_list && vo_list[0])
         while (vo_list[0][0]) {
@@ -272,13 +318,15 @@ const vo_functions_t *init_best_video_out(char **vo_list)
                 ++vo_subdevice;
             }
             for (i = 0; video_out_drivers[i]; i++) {
-                const vo_functions_t *video_driver = video_out_drivers[i];
+                const struct vo_driver *video_driver = video_out_drivers[i];
                 const vo_info_t *info = video_driver->info;
                 if (!strcmp(info->short_name, name)) {
                     // name matches, try it
-                    if (!video_driver->preinit(vo_subdevice)) {
+                    memset(vo, 0, sizeof *vo);
+                    vo->driver = video_driver;
+                    if (!vo_preinit(vo, vo_subdevice)) {
                         free(name);
-                        return video_driver; // success!
+                        return vo; // success!
                     }
 		}
 	    }
@@ -291,14 +339,17 @@ const vo_functions_t *init_best_video_out(char **vo_list)
     // now try the rest...
     vo_subdevice = NULL;
     for (i = 0; video_out_drivers[i]; i++) {
-        const vo_functions_t *video_driver = video_out_drivers[i];
-        if (!video_driver->preinit(vo_subdevice))
-	    return video_driver; // success!
+        const struct vo_driver *video_driver = video_out_drivers[i];
+        memset(vo, 0, sizeof *vo);
+        vo->driver = video_driver;
+        if (!vo_preinit(vo, vo_subdevice))
+            return vo; // success!
     }
+    free(vo);
     return NULL;
 }
 
-int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height,
+int vo_config(struct vo *vo, uint32_t width, uint32_t height,
                      uint32_t d_width, uint32_t d_height, uint32_t flags,
                      char *title, uint32_t format)
 {
@@ -306,7 +357,7 @@ int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height,
     aspect_save_orig(width, height);
     aspect_save_prescale(d_width, d_height);
 
-    if (vo->control(VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) {
+    if (vo_control(vo, VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) {
         aspect(&d_width, &d_height, A_NOZOOM);
         vo_dx = (int)(vo_screenwidth - d_width) / 2;
         vo_dy = (int)(vo_screenheight - d_height) / 2;
@@ -318,7 +369,8 @@ int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height,
         vo_dheight = d_height;
     }
 
-    return vo->config(width, height, d_width, d_height, flags, title, format);
+    return vo->driver->config(vo, width, height, d_width, d_height, flags,
+				  title, format);
 }
 
 #if defined(HAVE_FBDEV)||defined(HAVE_VESA)
diff --git a/libvo/video_out.h b/libvo/video_out.h
index 06f9381..05a2e94 100644
--- a/libvo/video_out.h
+++ b/libvo/video_out.h
@@ -116,15 +116,23 @@ typedef struct vo_info_s
         const char *comment;
 } vo_info_t;
 
-typedef struct vo_functions_s
-{
+struct vo;
+
+struct vo_driver {
+	// Driver uses new API
+	int is_new;
+
+	// This is set if the driver is not new and contains pointers to
+	// old-API functions to be used instead of the ones below.
+	struct vo_old_functions *old_functions;
+
 	const vo_info_t *info;
 	/*
 	 * Preinitializes driver (real INITIALIZATION)
 	 *   arg - currently it's vo_subdevice
 	 *   returns: zero on successful initialization, non-zero on error.
 	 */
-	int (*preinit)(const char *arg);
+	int (*preinit)(struct vo *vo, const char *arg);
         /*
          * Initialize (means CONFIGURE) the display driver.
 	 * params:
@@ -135,21 +143,21 @@ typedef struct vo_functions_s
 	 *   format: fourcc of pixel format
          * returns : zero on successful initialization, non-zero on error.
          */
-        int (*config)(uint32_t width, uint32_t height, uint32_t d_width,
-			 uint32_t d_height, uint32_t fullscreen, char *title,
-			 uint32_t format);
+        int (*config)(struct vo *vo, uint32_t width, uint32_t height,
+	              uint32_t d_width, uint32_t d_height, uint32_t fullscreen,
+		      char *title, uint32_t format);
 
 	/*
 	 * Control interface
 	 */
-	int (*control)(uint32_t request, void *data);
+	int (*control)(struct vo *vo, uint32_t request, void *data);
 
         /*
          * Display a new RGB/BGR frame of the video to the screen.
          * params:
 	 *   src[0] - pointer to the image
          */
-        int (*draw_frame)(uint8_t *src[]);
+        int (*draw_frame)(struct vo *vo, uint8_t *src[]);
 
         /*
          * Draw a planar YUV slice to the buffer:
@@ -159,39 +167,68 @@ typedef struct vo_functions_s
 	 *   w,h = width*height of area to be copied (in Y pixels)
          *   x,y = position at the destination image (in Y pixels)
          */
-        int (*draw_slice)(uint8_t *src[], int stride[], int w,int h, int x,int y);
+        int (*draw_slice)(struct vo *vo, uint8_t *src[], int stride[], int w,
+			  int h, int x, int y);
 
    	/*
          * Draws OSD to the screen buffer
          */
-        void (*draw_osd)(void);
+        void (*draw_osd)(struct vo *vo);
 
         /*
          * Blit/Flip buffer to the screen. Must be called after each frame!
          */
-        void (*flip_page)(void);
+        void (*flip_page)(struct vo *vo);
 
         /*
          * This func is called after every frames to handle keyboard and
 	 * other events. It's called in PAUSE mode too!
          */
-        void (*check_events)(void);
+        void (*check_events)(struct vo *vo);
 
         /*
          * Closes driver. Should restore the original state of the system.
          */
+        void (*uninit)(struct vo *vo);
+};
+
+struct vo_old_functions {
+	int (*preinit)(const char *arg);
+        int (*config)(uint32_t width, uint32_t height, uint32_t d_width,
+			 uint32_t d_height, uint32_t fullscreen, char *title,
+			 uint32_t format);
+	int (*control)(uint32_t request, void *data);
+        int (*draw_frame)(uint8_t *src[]);
+        int (*draw_slice)(uint8_t *src[], int stride[], int w,int h, int x,int y);
+        void (*draw_osd)(void);
+        void (*flip_page)(void);
+        void (*check_events)(void);
         void (*uninit)(void);
+};
 
-} vo_functions_t;
+struct vo {
+    int is_new;
+    const struct vo_driver *driver;
+    void *priv;
+};
 
-const vo_functions_t* init_best_video_out(char** vo_list);
-int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height,
+struct vo *init_best_video_out(char **vo_list);
+int vo_config(struct vo *vo, uint32_t width, uint32_t height,
                      uint32_t d_width, uint32_t d_height, uint32_t flags,
                      char *title, uint32_t format);
 void list_video_out(void);
 
+int vo_control(struct vo *vo, uint32_t request, void *data);
+int vo_draw_frame(struct vo *vo, uint8_t *src[]);
+int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y);
+void vo_draw_osd(struct vo *vo);
+void vo_flip_page(struct vo *vo);
+void vo_check_events(struct vo *vo);
+void vo_destroy(struct vo *vo);
+
+
 // NULL terminated array of all drivers
-extern const vo_functions_t* const video_out_drivers[];
+extern const struct vo_driver *video_out_drivers[];
 
 extern int vo_flags;
 
diff --git a/libvo/video_out_internal.h b/libvo/video_out_internal.h
index 1bfb91d..ba37f9e 100644
--- a/libvo/video_out_internal.h
+++ b/libvo/video_out_internal.h
@@ -29,6 +29,7 @@
 #include "libmpcodecs/vfcap.h"
 #include "libmpcodecs/mp_image.h"
 #include "geometry.h"
+#include "old_vo_wrapper.h"
 
 static int control(uint32_t request, void *data);
 static int config(uint32_t width, uint32_t height, uint32_t d_width,
@@ -43,9 +44,20 @@ static void uninit(void);
 static int query_format(uint32_t format);
 static int preinit(const char *);
 
-#define LIBVO_EXTERN(x) vo_functions_t video_out_##x =\
+#define LIBVO_EXTERN(x) struct vo_driver video_out_##x =\
 {\
-	&info,\
+    .is_new = 0,\
+    .info = &info,\
+    .preinit = old_vo_preinit,\
+    .config = old_vo_config,\
+    .control = old_vo_control,\
+    .draw_frame = old_vo_draw_frame,\
+    .draw_slice = old_vo_draw_slice,\
+    .draw_osd = old_vo_draw_osd,\
+    .flip_page = old_vo_flip_page,\
+    .check_events = old_vo_check_events,\
+    .uninit = old_vo_uninit,\
+    .old_functions = &(struct vo_old_functions){\
 	preinit,\
 	config,\
 	control,\
@@ -54,7 +66,8 @@ static int preinit(const char *);
      	draw_osd,\
 	flip_page,\
 	check_events,\
-	uninit\
+        uninit,\
+    }\
 };
 
 #include "osd.h"
diff --git a/libvo/vo_dxr2.c b/libvo/vo_dxr2.c
index 4b0d473..75e0ca1 100644
--- a/libvo/vo_dxr2.c
+++ b/libvo/vo_dxr2.c
@@ -37,7 +37,8 @@ static int movie_w,movie_h;
 static int playing = 0;
 
 // vo device used to blank the screen for the overlay init
-static const vo_functions_t* sub_vo = NULL;
+static const struct vo_old_functions *sub_vo = NULL;
+static const struct vo_info_s *sub_info;
 
 static uint8_t* sub_img = NULL;
 static int sub_x,sub_y,sub_w,sub_h;
@@ -432,7 +433,7 @@ static int dxr2_load_vga_params(dxr2_vgaParams_t* vga,char* name) {
 }
 
 static int dxr2_setup_vga_params(void) {
-  const vo_info_t* vi = sub_vo->info;
+  const vo_info_t* vi = sub_info;
   dxr2_vgaParams_t vga;
 
   int loaded = dxr2_load_vga_params(&vga,(char*)vi->short_name);
@@ -646,7 +647,7 @@ static int config(uint32_t s_width, uint32_t s_height, uint32_t width, uint32_t
     }
     // Does the sub vo support the x11 stuff
     // Fix me : test the other x11 vo's and enable them
-    if(strcmp(sub_vo->info->short_name,"x11") == 0)
+    if(strcmp(sub_info->short_name,"x11") == 0)
       sub_vo_win = 1;
     else
       sub_vo_win = 0;
@@ -820,10 +821,11 @@ static int preinit(const char *arg) {
 	const vo_info_t* vi = video_out_drivers[n]->info;
 	if(!vi)
 	  continue;
-	if(strcasecmp(arg,vi->short_name) == 0)
+	if(!video_out_drivers[n]->is_new && strcasecmp(arg,vi->short_name) == 0)
 	  break;
       }
-      sub_vo = video_out_drivers[n];
+      sub_vo = video_out_drivers[n]->old_functions;
+      sub_info = video_out_drivers[n]->info;
     } else {
       mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] We need a sub driver to initialize the overlay\n");
       use_ol = 0;
diff --git a/libvo/vo_xover.c b/libvo/vo_xover.c
index 77d8306..a51e9aa 100644
--- a/libvo/vo_xover.c
+++ b/libvo/vo_xover.c
@@ -67,8 +67,8 @@ static uint32_t window_width, window_height;
 static uint32_t drwX, drwY, drwWidth, drwHeight, drwBorderWidth,
     drwDepth, drwcX, drwcY, dwidth, dheight;
 
-static const vo_functions_t* sub_vo = NULL;
-
+static const struct vo_old_functions *sub_vo = NULL;
+static const struct vo_info_s *sub_info;
 
 static void set_window(int force_update)
 {
@@ -211,7 +211,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
   mp_colorkey_t colork;
   char _title[255];
 
-  sprintf(_title,"MPlayer %s X11 Overlay",sub_vo->info->name);
+  sprintf(_title,"MPlayer %s X11 Overlay", sub_info->name);
   title = _title;
 
   panscan_init();
@@ -384,10 +384,10 @@ static void uninit(void)
   sub_vo = NULL;
   vo_x11_uninit();
   // Restore our callbacks
-  video_out_xover.draw_frame = draw_frame;
-  video_out_xover.draw_slice = draw_slice;
-  video_out_xover.flip_page = flip_page;
-  video_out_xover.draw_osd  = draw_osd;
+  video_out_xover.old_functions->draw_frame = draw_frame;
+  video_out_xover.old_functions->draw_slice = draw_slice;
+  video_out_xover.old_functions->flip_page = flip_page;
+  video_out_xover.old_functions->draw_osd  = draw_osd;
 }
 
 static int preinit(const char *arg)
@@ -399,31 +399,34 @@ static int preinit(const char *arg)
     return 1;
   }
 
-  for(i = 0 ; video_out_drivers[i] != NULL ; i++) {
-    if(!strcmp(video_out_drivers[i]->info->short_name,arg) &&
-       strcmp(video_out_drivers[i]->info->short_name,"xover"))
+  const struct vo_driver *candidate;
+  for(i = 0; (candidate = video_out_drivers[i]) != NULL; i++)
+    if (!candidate->is_new && !strcmp(candidate->info->short_name,arg) &&
+        strcmp(candidate->info->short_name,"xover"))
       break;
-  }
-  if(!video_out_drivers[i]) {
+  if (!candidate) {
     mp_msg(MSGT_VO, MSGL_ERR, "VO XOverlay: Subdriver %s not found\n", arg);
     return 1;
   }
-  if(video_out_drivers[i]->control(VOCTRL_XOVERLAY_SUPPORT,NULL) != VO_TRUE) {
+
+  const struct vo_old_functions *functions = candidate->old_functions;
+  if (functions->control(VOCTRL_XOVERLAY_SUPPORT,NULL) != VO_TRUE) {
     mp_msg(MSGT_VO, MSGL_ERR, "VO XOverlay: %s doesn't support XOverlay\n", arg);
     return 1;
   }
   // X11 init
   if (!vo_init()) return VO_FALSE;
-  if(video_out_drivers[i]->preinit(NULL)) {
+  if(functions->preinit(NULL)) {
     mp_msg(MSGT_VO, MSGL_ERR, "VO XOverlay: Subvo init failed\n");
     return 1;
   }
-  sub_vo = video_out_drivers[i];
+  sub_vo = functions;
+  sub_info = candidate->info;
   // Setup the sub vo callbacks
-  video_out_xover.draw_frame = sub_vo->draw_frame;
-  video_out_xover.draw_slice = sub_vo->draw_slice;
-  video_out_xover.flip_page = sub_vo->flip_page;
-  video_out_xover.draw_osd  = sub_vo->draw_osd;
+  video_out_xover.old_functions->draw_frame = sub_vo->draw_frame;
+  video_out_xover.old_functions->draw_slice = sub_vo->draw_slice;
+  video_out_xover.old_functions->flip_page = sub_vo->flip_page;
+  video_out_xover.old_functions->draw_osd  = sub_vo->draw_osd;
   return 0;
 }
 
diff --git a/libvo/vosub_vidix.c b/libvo/vosub_vidix.c
index 2291814..b9ff829 100644
--- a/libvo/vosub_vidix.c
+++ b/libvo/vosub_vidix.c
@@ -33,6 +33,7 @@
 #include "video_out.h"
 #include "sub.h"
 #include "vosub_vidix.h"
+#include "old_vo_wrapper.h"
 
 #include "libmpcodecs/vfcap.h"
 #include "libmpcodecs/mp_image.h"
@@ -48,7 +49,7 @@ static int video_on=0;
 static vidix_capability_t vidix_cap;
 static vidix_playback_t   vidix_play;
 static vidix_fourcc_t	  vidix_fourcc;
-static vo_functions_t *   vo_server;
+static struct vo_old_functions *vo_server;
 static vidix_yuv_t	  dstrides;
 /*static uint32_t (*server_control)(uint32_t request, void *data, ...);*/
 
@@ -85,7 +86,7 @@ void vidix_term( void )
 //  vo_server->control=server_control;
 }
 
-static uint32_t vidix_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y)
+static int vidix_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y)
 {
     uint8_t *src;
     uint8_t *dest;
@@ -149,7 +150,7 @@ static uint32_t vidix_draw_slice_420(uint8_t *image[], int stride[], int w,int h
     return -1;
 }
 
-static uint32_t vidix_draw_slice_410(uint8_t *image[], int stride[], int w,int h,int x,int y)
+static int vidix_draw_slice_410(uint8_t *image[], int stride[], int w,int h,int x,int y)
 {
     uint8_t *src;
     uint8_t *dest;
@@ -195,7 +196,7 @@ static uint32_t vidix_draw_slice_410(uint8_t *image[], int stride[], int w,int h
     return -1;
 }
 
-static uint32_t vidix_draw_slice_packed(uint8_t *image[], int stride[], int w,int h,int x,int y)
+static int vidix_draw_slice_packed(uint8_t *image[], int stride[], int w,int h,int x,int y)
 {
     uint8_t *src;
     uint8_t *dest;
@@ -212,7 +213,7 @@ static uint32_t vidix_draw_slice_packed(uint8_t *image[], int stride[], int w,in
     return 0;
 }
 
-uint32_t vidix_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y)
+int vidix_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y)
 {
     mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SUB_VIDIX_DummyVidixdrawsliceWasCalled);
     return -1;
@@ -230,7 +231,7 @@ static uint32_t  vidix_draw_image(mp_image_t *mpi){
     return VO_TRUE;
 }
 
-uint32_t vidix_draw_frame(uint8_t *image[])
+int vidix_draw_frame(uint8_t *image[])
 {
   mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SUB_VIDIX_DummyVidixdrawframeWasCalled);
   return -1;
@@ -625,7 +626,7 @@ uint32_t vidix_control(uint32_t request, void *data)
 //  return server_control(request,data); //VO_NOTIMPL;
 }
 
-int vidix_preinit(const char *drvname,vo_functions_t *server)
+int vidix_preinit(const char *drvname, struct vo_old_functions *server)
 {
   int err;
   if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) {
diff --git a/libvo/vosub_vidix.h b/libvo/vosub_vidix.h
index 0c2e30d..d5a96fc 100644
--- a/libvo/vosub_vidix.h
+++ b/libvo/vosub_vidix.h
@@ -16,7 +16,7 @@
 #include "video_out.h"
 
 		    /* drvname can be NULL */
-int	 vidix_preinit(const char *drvname,vo_functions_t *server);
+int	 vidix_preinit(const char *drvname, struct vo_old_functions *server);
 int      vidix_init(unsigned src_width,unsigned src_height,
 		    unsigned dest_x,unsigned dest_y,unsigned dst_width,
 		    unsigned dst_height,unsigned format,unsigned dest_bpp,
@@ -27,8 +27,8 @@ void     vidix_term( void );
 uint32_t vidix_control(uint32_t request, void *data);
 uint32_t vidix_query_fourcc(uint32_t fourcc);
 
-uint32_t vidix_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y);
-uint32_t vidix_draw_frame(uint8_t *src[]);
+int vidix_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y);
+int vidix_draw_frame(uint8_t *src[]);
 void     vidix_flip_page(void);
 void     vidix_draw_osd(void);
 
diff --git a/mencoder.c b/mencoder.c
index f4df17f..ae80958 100644
--- a/mencoder.c
+++ b/mencoder.c
@@ -209,11 +209,16 @@ char *info_sourceform=NULL;
 char *info_comment=NULL;
 
 // Needed by libmpcodecs vf_vo.c
-int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height,
-                     uint32_t d_width, uint32_t d_height, uint32_t flags,
-                     char *title, uint32_t format) {
-  return 1;
-}
+int vo_config(struct vo *vo, uint32_t width, uint32_t height,
+	      uint32_t d_width, uint32_t d_height, uint32_t flags,
+	      char *title, uint32_t format) { abort(); }
+int vo_control(struct vo *vo, uint32_t request, void *data) { abort(); }
+int vo_draw_frame(struct vo *vo, uint8_t *src[]) { abort(); }
+int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y) { abort(); }
+void vo_draw_osd(struct vo *vo) { abort(); }
+void vo_flip_page(struct vo *vo) { abort(); }
+void vo_check_events(struct vo *vo) { abort(); }
+
 // Needed by libmpdemux.
 int mp_input_check_interrupt(int time) {
   usec_sleep(time);
diff --git a/mp_core.h b/mp_core.h
index 57d32ff..e614926 100644
--- a/mp_core.h
+++ b/mp_core.h
@@ -59,7 +59,7 @@ typedef struct MPContext {
     demux_stream_t *d_video;
     demux_stream_t *d_sub;
     mixer_t mixer;
-    const vo_functions_t *video_out;
+    struct vo *video_out;
     // Frames buffered in the vo ready to flip. Currently always 0 or 1.
     // This is really a vo variable but currently there's no suitable vo
     // struct.
diff --git a/mplayer.c b/mplayer.c
index 1a03616..a1194ec 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -626,7 +626,7 @@ void uninit_player(unsigned int mask){
   if(mask&INITIALIZED_VO){
     initialized_flags&=~INITIALIZED_VO;
     current_module="uninit_vo";
-    mpctx->video_out->uninit();
+    vo_destroy(mpctx->video_out);
     mpctx->video_out=NULL;
 #ifdef USE_DVDNAV
     mp_dvdnav_context_free(mpctx);
@@ -2342,7 +2342,7 @@ static void pause_loop(void)
 	guiGetEvent(guiCEvent, (char *)guiSetPause);
 #endif
     if (mpctx->video_out && mpctx->sh_video && vo_config_count)
-	mpctx->video_out->control(VOCTRL_PAUSE, NULL);
+	vo_control(mpctx->video_out, VOCTRL_PAUSE, NULL);
 
     if (mpctx->audio_out && mpctx->sh_audio)
 	mpctx->audio_out->pause();	// pause audio, keep data if possible
@@ -2355,7 +2355,7 @@ static void pause_loop(void)
 	  continue;
 	}
 	if (mpctx->sh_video && mpctx->video_out && vo_config_count)
-	    mpctx->video_out->check_events();
+	    vo_check_events(mpctx->video_out);
 #ifdef HAVE_NEW_GUI
 	if (use_gui) {
 	    guiEventHandling();
@@ -2378,7 +2378,7 @@ static void pause_loop(void)
     if (mpctx->audio_out && mpctx->sh_audio)
         mpctx->audio_out->resume();	// resume audio
     if (mpctx->video_out && mpctx->sh_video && vo_config_count)
-        mpctx->video_out->control(VOCTRL_RESUME, NULL);	// resume video
+        vo_control(mpctx->video_out, VOCTRL_RESUME, NULL);	// resume video
     (void)GetRelativeTime();	// ignore time that passed during pause
 #ifdef HAVE_NEW_GUI
     if (use_gui) {
@@ -2496,7 +2496,7 @@ static int seek(MPContext *mpctx, double amount, int style)
 	current_module = "seek_video_reset";
 	resync_video_stream(mpctx->sh_video);
 	if (vo_config_count)
-	    mpctx->video_out->control(VOCTRL_RESET, NULL);
+	    vo_control(mpctx->video_out, VOCTRL_RESET, NULL);
 	mpctx->sh_video->num_buffered_pts = 0;
 	mpctx->sh_video->last_pts = MP_NOPTS_VALUE;
 	mpctx->num_buffered_frames = 0;
@@ -2993,7 +2993,8 @@ while (player_idle_mode && !filename) {
     play_tree_t * entry = NULL;
     mp_cmd_t * cmd;
     while (!(cmd = mp_input_get_cmd(0,1,0))) { // wait for command
-        if (mpctx->video_out && vo_config_count) mpctx->video_out->check_events();
+        if (mpctx->video_out && vo_config_count)
+	    vo_check_events(mpctx->video_out);
         usec_sleep(20000);
     }
     switch (cmd->id) {
@@ -3728,7 +3729,8 @@ if(!mpctx->sh_video) {
 #endif
 
     current_module="vo_check_events";
-    if (vo_config_count) mpctx->video_out->check_events();
+    if (vo_config_count)
+	vo_check_events(mpctx->video_out);
 
 #ifdef HAVE_X11
     if (stop_xscreensaver) {
@@ -3753,7 +3755,8 @@ if(!mpctx->sh_video) {
         if (!frame_time_remaining && blit_frame) {
 	   unsigned int t2=GetTimer();
 
-	   if(vo_config_count) mpctx->video_out->flip_page();
+	   if(vo_config_count)
+	       vo_flip_page(mpctx->video_out);
 	   mpctx->num_buffered_frames--;
 
 	   vout_time_usage += (GetTimer() - t2) * 0.000001;
diff --git a/spudec.c b/spudec.c
index 78a7865..6e7899b 100644
--- a/spudec.c
+++ b/spudec.c
@@ -86,7 +86,7 @@ typedef struct {
   unsigned char *scaled_aimage;
   int auto_palette; /* 1 if we lack a palette and must use an heuristic. */
   int font_start_level;  /* Darkest value used for the computed font */
-  const vo_functions_t *hw_spu;
+  struct vo *hw_spu;
   int spu_changed;
   unsigned int forced_subs_only;     /* flag: 0=display all subtitle, !0 display only forced subtitles */
   unsigned int is_forced_sub;         /* true if current subtitle is a forced subtitle */
@@ -490,7 +490,7 @@ static void spudec_decode(spudec_handle_t *this, int pts100)
     packet.data = this->packet;
     packet.size = this->packet_size;
     packet.timestamp = pts100;
-    this->hw_spu->draw_frame((uint8_t**)&pkg);
+    vo_draw_frame(this->hw_spu, (uint8_t**)&pkg);
   }
 }
 
@@ -1104,7 +1104,7 @@ void spudec_update_palette(void * this, unsigned int *palette)
   if (spu && palette) {
     memcpy(spu->global_palette, palette, sizeof(spu->global_palette));
     if(spu->hw_spu)
-      spu->hw_spu->control(VOCTRL_SET_SPU_PALETTE,spu->global_palette);
+      vo_control(spu->hw_spu, VOCTRL_SET_SPU_PALETTE, spu->global_palette);
   }
 }
 
@@ -1174,11 +1174,11 @@ void spudec_free(void *this)
   }
 }
 
-void spudec_set_hw_spu(void *this, const vo_functions_t *hw_spu)
+void spudec_set_hw_spu(void *this, struct vo *hw_spu)
 {
   spudec_handle_t *spu = (spudec_handle_t*)this;
   if (!spu)
     return;
   spu->hw_spu = hw_spu;
-  hw_spu->control(VOCTRL_SET_SPU_PALETTE,spu->global_palette);
+  vo_control(hw_spu, VOCTRL_SET_SPU_PALETTE, spu->global_palette);
 }
diff --git a/spudec.h b/spudec.h
index 5cdbec5..f3cafbd 100644
--- a/spudec.h
+++ b/spudec.h
@@ -15,7 +15,7 @@ void spudec_free(void *this);
 void spudec_reset(void *this);	// called after seek
 int spudec_visible(void *this); // check if spu is visible
 void spudec_set_font_factor(void * this, double factor); // sets the equivalent to ffactor
-void spudec_set_hw_spu(void *this, const vo_functions_t *hw_spu);
+void spudec_set_hw_spu(void *this, struct vo *hw_spu);
 int spudec_changed(void *this);
 void spudec_calc_bbox(void *me, unsigned int dxs, unsigned int dys, unsigned int* bbox);
 void spudec_set_forced_subs_only(void * const this, const unsigned int flag);
-- 
1.5.4.5

Add context variable to vo_draw_text callback

Add a context variable and rename the function to osd_draw_text. Create
a new vo_draw_text that is a wrapper for VOs using old API.
---
 libmpcodecs/vf_expand.c |    4 ++--
 libvo/old_vo_wrapper.c  |   16 ++++++++++++++++
 libvo/old_vo_wrapper.h  |    2 ++
 libvo/sub.c             |   17 ++++++++++-------
 libvo/sub.h             |    2 +-
 libvo/vo_directx.c      |    1 -
 libvo/vo_macosx.m       |    1 -
 libvo/vo_quartz.c       |    2 --
 spudec.c                |    6 +++---
 spudec.h                |    2 +-
 10 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/libmpcodecs/vf_expand.c b/libmpcodecs/vf_expand.c
index 44a5549..8c4f144 100644
--- a/libmpcodecs/vf_expand.c
+++ b/libmpcodecs/vf_expand.c
@@ -96,7 +96,7 @@ static void remove_func(int x0,int y0, int w,int h){
     }
 }
 
-static void draw_func(int x0,int y0, int w,int h,unsigned char* src, unsigned char *srca, int stride){
+static void draw_func(void *ctx, int x0,int y0, int w,int h,unsigned char* src, unsigned char *srca, int stride){
     unsigned char* dst;
     if(!vo_osd_changed_flag && vf->dmpi->planes[0]==vf->priv->fb_ptr){
 	// ok, enough to update the area inside the video, leave the black bands
@@ -177,7 +177,7 @@ static void draw_osd(struct vf_instance_s* vf_,int w,int h){
 	    vo_remove_text(vf->priv->exp_w,vf->priv->exp_h,remove_func);
 	}
     }
-    vo_draw_text(vf->priv->exp_w,vf->priv->exp_h,draw_func);
+    osd_draw_text(vf->priv->exp_w,vf->priv->exp_h,draw_func, NULL);
     // save buffer pointer for double buffering detection - yes, i know it's
     // ugly method, but note that codecs with DR support does the same...
     if(vf->dmpi)
diff --git a/libvo/old_vo_wrapper.c b/libvo/old_vo_wrapper.c
index b526223..d4af6fc 100644
--- a/libvo/old_vo_wrapper.c
+++ b/libvo/old_vo_wrapper.c
@@ -20,6 +20,7 @@
 #include <stdint.h>
 #include "old_vo_wrapper.h"
 #include "video_out.h"
+#include "sub.h"
 
 int old_vo_preinit(struct vo *vo, const char *arg)
 {
@@ -78,3 +79,18 @@ void old_vo_uninit(struct vo *vo)
     vo->driver->old_functions->uninit();
 }
 
+
+static void draw_alpha_wrapper(void *ctx, int x0, int y0, int w, int h,
+                               unsigned char *src, unsigned char *srca,
+                               int stride)
+{
+    void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride) = ctx;
+    draw_alpha(x0, y0, w, h, src, srca, stride);
+}
+
+
+void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride))
+{
+    osd_draw_text(dxs, dys, draw_alpha_wrapper, draw_alpha);
+}
+
diff --git a/libvo/old_vo_wrapper.h b/libvo/old_vo_wrapper.h
index e7ac158..a66fe4e 100644
--- a/libvo/old_vo_wrapper.h
+++ b/libvo/old_vo_wrapper.h
@@ -13,3 +13,5 @@ void old_vo_draw_osd(struct vo *vo);
 void old_vo_flip_page(struct vo *vo);
 void old_vo_check_events(struct vo *vo);
 void old_vo_uninit(struct vo *vo);
+
+void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
diff --git a/libvo/sub.c b/libvo/sub.c
index aeb68d2..3330baa 100644
--- a/libvo/sub.c
+++ b/libvo/sub.c
@@ -154,9 +154,11 @@ static void alloc_buf(mp_osd_obj_t* obj)
 }
 
 // renders the buffer
-inline static void vo_draw_text_from_buffer(mp_osd_obj_t* obj,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){
+inline static void vo_draw_text_from_buffer(mp_osd_obj_t* obj,void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx)
+{
     if (obj->allocated > 0) {
-	draw_alpha(obj->bbox.x1,obj->bbox.y1,
+	draw_alpha(ctx,
+		   obj->bbox.x1,obj->bbox.y1,
 		   obj->bbox.x2-obj->bbox.x1,
 		   obj->bbox.y2-obj->bbox.y1,
 		   obj->bitmap_buffer,
@@ -1022,9 +1024,9 @@ inline static void vo_update_spudec_sub(mp_osd_obj_t* obj, int dxs, int dys)
   obj->flags |= OSDFLAG_BBOX;
 }
 
-inline static void vo_draw_spudec_sub(mp_osd_obj_t* obj, void (*draw_alpha)(int x0, int y0, int w, int h, unsigned char* src, unsigned char* srca, int stride))
+inline static void vo_draw_spudec_sub(mp_osd_obj_t* obj, void (*draw_alpha)(void *ctx, int x0, int y0, int w, int h, unsigned char* src, unsigned char* srca, int stride), void *ctx)
 {
-  spudec_draw_scaled(vo_spudec, obj->dxs, obj->dys, draw_alpha);
+    spudec_draw_scaled(vo_spudec, obj->dxs, obj->dys, draw_alpha, ctx);
 }
 
 void *vo_spudec=NULL;
@@ -1223,7 +1225,8 @@ void vo_remove_text(int dxs,int dys,void (*remove)(int x0,int y0, int w,int h)){
     }
 }
 
-void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){
+void osd_draw_text(int dxs,int dys,void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx)
+{
     mp_osd_obj_t* obj=vo_osd_list;
     vo_update_osd(dxs,dys);
     while(obj){
@@ -1231,7 +1234,7 @@ void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h,
 	vo_osd_changed_flag=obj->flags&OSDFLAG_CHANGED;	// temp hack
 	switch(obj->type){
 	case OSDTYPE_SPU:
-	    vo_draw_spudec_sub(obj, draw_alpha); // FIXME
+	    vo_draw_spudec_sub(obj, draw_alpha, ctx); // FIXME
 	    break;
 #ifdef USE_DVDNAV
         case OSDTYPE_DVDNAV:
@@ -1242,7 +1245,7 @@ void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h,
 	case OSDTYPE_OSD:
 	case OSDTYPE_SUBTITLE:
 	case OSDTYPE_PROGBAR:
-	    vo_draw_text_from_buffer(obj,draw_alpha);
+	    vo_draw_text_from_buffer(obj, draw_alpha, ctx);
 	    break;
 	}
 	obj->old_bbox=obj->bbox;
diff --git a/libvo/sub.h b/libvo/sub.h
index f15b4e6..d978935 100644
--- a/libvo/sub.h
+++ b/libvo/sub.h
@@ -116,7 +116,7 @@ extern float spu_gaussvar;
 //extern void vo_draw_text_osd(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
 //extern void vo_draw_text_progbar(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
 //extern void vo_draw_text_sub(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
-extern void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
+extern void osd_draw_text(int dxs,int dys,void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx);
 extern void vo_remove_text(int dxs,int dys,void (*remove)(int x0,int y0, int w,int h));
 
 void vo_init_osd(void);
diff --git a/libvo/vo_directx.c b/libvo/vo_directx.c
index a241631..5d3bd35 100644
--- a/libvo/vo_directx.c
+++ b/libvo/vo_directx.c
@@ -87,7 +87,6 @@ static float window_aspect;
 static BOOL (WINAPI* myGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL;
 static RECT last_rect = {0xDEADC0DE, 0xDEADC0DE, 0xDEADC0DE, 0xDEADC0DE};
 
-extern void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
 extern int vidmode;
 
 /*****************************************************************************
diff --git a/libvo/vo_macosx.m b/libvo/vo_macosx.m
index 04d395a..5039fa3 100644
--- a/libvo/vo_macosx.m
+++ b/libvo/vo_macosx.m
@@ -81,7 +81,6 @@ static vo_info_t info =
 LIBVO_EXTERN(macosx)
 
 extern void mplayer_put_key(int code);
-extern void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
 
 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride)
 {
diff --git a/libvo/vo_quartz.c b/libvo/vo_quartz.c
index 40e7049..ddaedd8 100644
--- a/libvo/vo_quartz.c
+++ b/libvo/vo_quartz.c
@@ -129,8 +129,6 @@ enum
 
 #include "osdep/keycodes.h"
 
-extern void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
-
 //PROTOTYPE/////////////////////////////////////////////////////////////////
 static OSStatus KeyEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);
 static OSStatus MouseEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);
diff --git a/spudec.c b/spudec.c
index 6e7899b..2904908 100644
--- a/spudec.c
+++ b/spudec.c
@@ -767,7 +767,7 @@ void sws_spu_image(unsigned char *d1, unsigned char *d2, int dw, int dh, int ds,
 	sws_freeContext(ctx);
 }
 
-void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride))
+void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx)
 {
   spudec_handle_t *spu = (spudec_handle_t *)me;
   scale_pixel *table_x;
@@ -784,7 +784,7 @@ void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*dra
 	|| (spu->orig_frame_width == dxs && spu->orig_frame_height == dys))) {
       if (spu->image)
       {
-	draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
+	draw_alpha(ctx, spu->start_col, spu->start_row, spu->width, spu->height,
 		   spu->image, spu->aimage, spu->stride);
 	spu->spu_changed = 0;
       }
@@ -1085,7 +1085,7 @@ nothing_to_do:
           spu->scaled_start_row = dys*sub_pos/100 - spu->scaled_height;
 	  break;
 	}
-	draw_alpha(spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height,
+	draw_alpha(ctx, spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height,
 		   spu->scaled_image, spu->scaled_aimage, spu->scaled_stride);
 	spu->spu_changed = 0;
       }
diff --git a/spudec.h b/spudec.h
index f3cafbd..10c9668 100644
--- a/spudec.h
+++ b/spudec.h
@@ -6,7 +6,7 @@
 void spudec_heartbeat(void *this, unsigned int pts100);
 void spudec_assemble(void *this, unsigned char *packet, unsigned int len, int pts100);
 void spudec_draw(void *this, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
-void spudec_draw_scaled(void *this, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
+void spudec_draw_scaled(void *this, unsigned int dxs, unsigned int dys, void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx);
 void spudec_update_palette(void *this, unsigned int *palette);
 void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigned int frame_height);
 void *spudec_new_scaled_vobsub(unsigned int *palette, unsigned int *cuspal, unsigned int custom, unsigned int frame_width, unsigned int frame_height);
-- 
1.5.4.5

Remove #if 0 code

---
 libvo/vo_xv.c |   26 +-------------------------
 1 files changed, 1 insertions(+), 25 deletions(-)

diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index bdb4d6b..511602d 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -254,6 +254,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
             hint.height = modeline_height;
             aspect_save_screenres(modeline_width, modeline_height);
         } else
+#warning This "else" makes no sense
 #endif
         hint.flags = PPosition | PSize /* | PBaseSize */ ;
         hint.base_width = hint.width;
@@ -367,31 +368,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
                         vo_dwidth + vo_panscan_x - 1,
                         vo_dheight + vo_panscan_y - 1);
 
-
-#if 0
-#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));
-    }
-#endif
-
     mp_msg(MSGT_VO, MSGL_V, "[xv] dx: %d dy: %d dw: %d dh: %d\n", drwX,
            drwY, vo_dwidth, vo_dheight);
 
-- 
1.5.4.5

Minor simplification

---
 input/input.c |   32 +++++++++++++++++---------------
 1 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/input/input.c b/input/input.c
index 72db4f9..d2df519 100644
--- a/input/input.c
+++ b/input/input.c
@@ -619,11 +619,12 @@ mp_input_add_cmd_fd(int fd, int select, mp_cmd_func_t read_func, mp_close_func_t
     return 0;
   }
 
-  memset(&cmd_fds[num_cmd_fd],0,sizeof(mp_input_fd_t));
-  cmd_fds[num_cmd_fd].fd = fd;
-  cmd_fds[num_cmd_fd].read_func = read_func ? read_func : mp_input_default_cmd_func;
-  cmd_fds[num_cmd_fd].close_func = close_func;
-  cmd_fds[num_cmd_fd].no_select = !select;
+  cmd_fds[num_cmd_fd] = (struct mp_input_fd){
+      .fd = fd,
+      .read_func = read_func ? read_func : mp_input_default_cmd_func,
+      .close_func = close_func,
+      .no_select = !select
+  };
   num_cmd_fd++;
 
   return 1;
@@ -678,11 +679,12 @@ mp_input_add_key_fd(int fd, int select, mp_key_func_t read_func, mp_close_func_t
     return 0;
   }
 
-  memset(&key_fds[num_key_fd],0,sizeof(mp_input_fd_t));
-  key_fds[num_key_fd].fd = fd;
-  key_fds[num_key_fd].read_func = read_func;
-  key_fds[num_key_fd].close_func = close_func;
-  key_fds[num_key_fd].no_select = !select;
+  key_fds[num_key_fd] = (struct mp_input_fd){
+      .fd = fd,
+      .read_func = read_func,
+      .close_func = close_func,
+      .no_select = !select
+  };
   num_key_fd++;
 
   return 1;
@@ -700,11 +702,11 @@ mp_input_add_event_fd(int fd, void (*read_func)(void))
     return 0;
   }
 
-  memset(&key_fds[num_key_fd],0,sizeof(mp_input_fd_t));
-  key_fds[num_key_fd].fd = fd;
-  key_fds[num_key_fd].read_func = read_func;
-  key_fds[num_key_fd].close_func = NULL;
-  key_fds[num_key_fd].no_readfunc_retval = 1;
+  key_fds[num_key_fd] = (struct mp_input_fd){
+      .fd = fd,
+      .read_func = read_func,
+      .no_readfunc_retval = 1,
+  };
   num_key_fd++;
 
   return 1;
-- 
1.5.4.5

Add a context argument to mp_input_add_event_fd callback

---
 input/input.c |    6 ++++--
 input/input.h |    2 +-
 libvo/vo_xv.c |    6 ++++--
 mplayer.c     |    9 ++++++++-
 4 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/input/input.c b/input/input.c
index d2df519..a49de3c 100644
--- a/input/input.c
+++ b/input/input.c
@@ -507,6 +507,7 @@ typedef struct mp_input_fd {
   int fd;
   void* read_func;
   mp_close_func_t close_func;
+  void *ctx;
   unsigned eof : 1;
   unsigned drop : 1;
   unsigned dead : 1;
@@ -691,7 +692,7 @@ mp_input_add_key_fd(int fd, int select, mp_key_func_t read_func, mp_close_func_t
 }
 
 int
-mp_input_add_event_fd(int fd, void (*read_func)(void))
+mp_input_add_event_fd(int fd, void (*read_func)(void *ctx), void *ctx)
 {
   if(num_key_fd == MP_MAX_KEY_FD) {
     mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantRegister2ManyKeyFds,fd);
@@ -705,6 +706,7 @@ mp_input_add_event_fd(int fd, void (*read_func)(void))
   key_fds[num_key_fd] = (struct mp_input_fd){
       .fd = fd,
       .read_func = read_func,
+      .ctx = ctx,
       .no_readfunc_retval = 1,
   };
   num_key_fd++;
@@ -1230,7 +1232,7 @@ static mp_cmd_t *read_events(int time, int paused)
 #endif
 
 	if (key_fds[i].no_readfunc_retval) {   // getch2 handler special-cased for now
-	    ((void (*)(void))key_fds[i].read_func)();
+	    ((void (*)(void *))key_fds[i].read_func)(key_fds[i].ctx);
 	    if (cmd_queue_length)
 		return NULL;
 	    code = mplayer_get_key(0);
diff --git a/input/input.h b/input/input.h
index e6381b3..27c1bdb 100644
--- a/input/input.h
+++ b/input/input.h
@@ -240,7 +240,7 @@ mp_input_add_key_fd(int fd, int select, mp_key_func_t read_func, mp_close_func_t
 void
 mp_input_rm_key_fd(int fd);
 
-int mp_input_add_event_fd(int fd, void (*read_func)(void));
+int mp_input_add_event_fd(int fd, void (*read_func)(void *ctx), void *ctx);
 
 void mp_input_rm_event_fd(int fd);
 
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index 511602d..4b66392 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -689,7 +689,8 @@ static void uninit(void)
 #ifdef HAVE_XF86VM
     vo_vm_close(mDisplay);
 #endif
-    mp_input_rm_event_fd(ConnectionNumber(mDisplay));
+//  Temporarily disabled until next commit
+//  mp_input_rm_event_fd(ConnectionNumber(mDisplay));
     vo_x11_uninit();
 }
 
@@ -811,7 +812,8 @@ static int preinit(const char *arg)
 
     fo = XvListImageFormats(mDisplay, xv_port, (int *) &formats);
 
-    mp_input_add_event_fd(ConnectionNumber(mDisplay), check_events);
+//  Temporarily disabled until next commit changes check_events parameters
+//    mp_input_add_event_fd(ConnectionNumber(mDisplay), check_events);
     return 0;
 }
 
diff --git a/mplayer.c b/mplayer.c
index a1194ec..a4e25df 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -2532,6 +2532,13 @@ static int seek(MPContext *mpctx, double amount, int style)
     return 0;
 }
 
+
+static void read_keys(void *ctx)
+{
+    getch2();
+}
+
+
 int main(int argc,char* argv[]){
 
 
@@ -2854,7 +2861,7 @@ mp_input_init(use_gui);
 if(slave_mode)
   mp_input_add_cmd_fd(0,USE_SELECT,MP_INPUT_SLAVE_CMD_FUNC,NULL);
 else if(!noconsolecontrols)
-    mp_input_add_event_fd(0, getch2);
+    mp_input_add_event_fd(0, read_keys, NULL);
 
 #ifdef HAVE_MENU
  if(use_menu) {
-- 
1.5.4.5

Change vo_xv to use new API

---
 libvo/vo_xv.c |  513 +++++++++++++++++++++++++++++++--------------------------
 1 files changed, 276 insertions(+), 237 deletions(-)

diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index 4b66392..fa90653 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -19,13 +19,15 @@ Buffer allocation:
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdint.h>
 
 #include "config.h"
 #include "mp_msg.h"
 #include "help_mp.h"
 #include "video_out.h"
-#include "video_out_internal.h"
-
+#include "libmpcodecs/vfcap.h"
+#include "libmpcodecs/mp_image.h"
+#include "osd.h"
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
@@ -54,83 +56,83 @@ static const vo_info_t info = {
     ""
 };
 
-const LIBVO_EXTERN(xv)
 #ifdef HAVE_SHM
 #include <sys/ipc.h>
 #include <sys/shm.h>
 #include <X11/extensions/XShm.h>
-
-static XShmSegmentInfo Shminfo[NUM_BUFFERS];
-static int Shmem_Flag;
 #endif
 
 // Note: depends on the inclusion of X11/extensions/XShm.h
 #include <X11/extensions/Xv.h>
 #include <X11/extensions/Xvlib.h>
 
-// FIXME: dynamically allocate this stuff
-static void allocate_xvimage(int);
-static unsigned int ver, rel, req, ev, err;
-static unsigned int formats, adaptors, xv_format;
-static XvAdaptorInfo *ai = NULL;
-static XvImageFormatValues *fo=NULL;
-
-static int current_buf = 0;
-static int current_ip_buf = 0;
-static int num_buffers = 1;     // default
-static int visible_buf = -1;    // -1 means: no buffer was drawn yet
-static XvImage *xvimage[NUM_BUFFERS];
-
-
-static uint32_t image_width;
-static uint32_t image_height;
-static uint32_t image_format;
-static int flip_flag;
+struct xvctx {
+    unsigned int xv_port;
+    XvAdaptorInfo *ai;
+    XvImageFormatValues *fo;
+    unsigned int formats, adaptors, xv_format;
+    int current_buf;
+    int current_ip_buf;
+    int num_buffers;
+    int visible_buf;
+    XvImage *xvimage[NUM_BUFFERS];
+    uint32_t image_width;
+    uint32_t image_height;
+    uint32_t image_format;
+    int is_paused;
+    uint32_t drwX, drwY;
+    uint32_t max_width, max_height; // zero means: not set
+    void (*draw_alpha_fnc)(void *ctx, int x0, int y0, int w, int h,
+                           unsigned char *src, unsigned char *srca,
+                           int stride);
+#ifdef H