]> git.sesse.net Git - vlc/blobdiff - plugins/x11/vout_xvideo.c
* Minor bug fix to aout_directx.c
[vlc] / plugins / x11 / vout_xvideo.c
index 0ac6642a6c8dc853663d7ed19e5f5e24681eadb7..9bb31680cde5388437b4f13ae1e4aababc07de48 100644 (file)
@@ -2,7 +2,7 @@
  * vout_xvideo.c: Xvideo video output display method
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
- * $Id: vout_xvideo.c,v 1.19 2001/06/19 05:51:57 sam Exp $
+ * $Id: vout_xvideo.c,v 1.25 2001/08/05 15:32:46 gbazin Exp $
  *
  * Authors: Shane Harper <shanegh@optusnet.com.au>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -132,6 +132,8 @@ typedef struct vout_sys_s
     /* Mouse pointer properties */
     boolean_t           b_mouse_pointer_visible;
     mtime_t             i_time_mouse_last_moved; /* used to auto-hide pointer*/
+    Cursor              blank_cursor;                   /* the hidden cursor */
+    Pixmap              cursor_pixmap;
 
 } vout_sys_t;
 
@@ -168,7 +170,7 @@ static int  XVideoCreateShmImage     ( Display* dpy, int xv_port,
                                        int i_width, int i_height );
 static void XVideoDestroyShmImage    ( vout_thread_t *, XvImage *,
                                        XShmSegmentInfo * );
-static void XVideoSetMousePointer    ( const vout_thread_t * );
+static void X11ToggleMousePointer    ( vout_thread_t * );
 static void XVideoEnableScreenSaver  ( vout_thread_t * );
 static void XVideoDisableScreenSaver ( vout_thread_t * );
 /*static void XVideoSetAttribute       ( vout_thread_t *, char *, float );*/
@@ -204,12 +206,42 @@ void _M( vout_getfunctions )( function_list_t * p_function_list )
  *****************************************************************************/
 static int vout_Probe( probedata_t *p_data )
 {
+    Display *p_display;                                   /* display pointer */
+    char    *psz_display;
+
+    /* Open display, unsing 'vlc_display' or DISPLAY environment variable */
+    psz_display = XDisplayName( main_GetPszVariable(VOUT_DISPLAY_VAR, NULL) );
+    p_display = XOpenDisplay( psz_display );
+    if( p_display == NULL )                                         /* error */
+    {
+        intf_WarnMsg( 3, "vout: Xvideo cannot open display %s", psz_display );
+        intf_WarnMsg( 3, "vout: Xvideo not supported" );
+        return( 0 );
+    }
+    
+    if( !XVideoCheckForXv( p_display ) )
+    {
+        intf_WarnMsg( 3, "vout: Xvideo not supported" );
+        XCloseDisplay( p_display );
+        return( 0 );
+    }
+
+    if( XVideoGetPort( p_display ) < 0 )
+    {
+        intf_WarnMsg( 3, "vout: Xvideo not supported" );
+        XCloseDisplay( p_display );
+        return( 0 );
+    }
+
+    /* Clean-up everyting */
+    XCloseDisplay( p_display );
+
     if( TestMethod( VOUT_METHOD_VAR, "xvideo" ) )
     {
         return( 999 );
     }
 
-    return( 60 );
+    return( 150 );
 }
 
 /*****************************************************************************
@@ -222,6 +254,7 @@ static int vout_Probe( probedata_t *p_data )
 static int vout_Create( vout_thread_t *p_vout )
 {
     char *psz_display;
+    XColor cursor_color;
 
     /* Allocate structure */
     p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
@@ -254,6 +287,40 @@ static int vout_Create( vout_thread_t *p_vout )
         return( 1 );
     }
 
+    /* Check we have access to a video port */
+    if( (p_vout->p_sys->xv_port = XVideoGetPort(p_vout->p_sys->p_display)) <0 )
+    {
+        intf_ErrMsg( "vout error: cannot get XVideo port" );
+        XCloseDisplay( p_vout->p_sys->p_display );
+        free( p_vout->p_sys );
+        return 1;
+    }
+    intf_DbgMsg( "Using xv port %d" , p_vout->p_sys->xv_port );
+
+    /* Create blank cursor (for mouse cursor autohiding) */
+    p_vout->p_sys->b_mouse_pointer_visible = 1;
+    p_vout->p_sys->cursor_pixmap = XCreatePixmap( p_vout->p_sys->p_display,
+                                                  DefaultRootWindow(
+                                                     p_vout->p_sys->p_display),
+                                                  1, 1, 1 );
+    
+    XParseColor( p_vout->p_sys->p_display,
+                 XCreateColormap( p_vout->p_sys->p_display,
+                                  DefaultRootWindow(
+                                                    p_vout->p_sys->p_display ),
+                                  DefaultVisual(
+                                                p_vout->p_sys->p_display,
+                                                p_vout->p_sys->i_screen ),
+                                  AllocNone ),
+                 "black", &cursor_color );
+    
+    p_vout->p_sys->blank_cursor = XCreatePixmapCursor(
+                                      p_vout->p_sys->p_display,
+                                      p_vout->p_sys->cursor_pixmap,
+                                      p_vout->p_sys->cursor_pixmap,
+                                      &cursor_color,
+                                      &cursor_color, 1, 1 );    
+
     /* Spawn base window - this window will include the video output window,
      * but also command buttons, subtitles and other indicators */
     if( XVideoCreateWindow( p_vout ) )
@@ -264,9 +331,7 @@ static int vout_Create( vout_thread_t *p_vout )
         return( 1 );
     }
 
-    if( (p_vout->p_sys->xv_port = XVideoGetPort( p_vout->p_sys->p_display ))<0 )
-        return 1;
-    intf_DbgMsg( "Using xv port %d" , p_vout->p_sys->xv_port );
+    /* p_vout->pf_setbuffers( p_vout, NULL, NULL ); */
 
 #if 0
     /* XXX The brightness and contrast values should be read from environment
@@ -275,8 +340,6 @@ static int vout_Create( vout_thread_t *p_vout )
     XVideoSetAttribute( p_vout, "XV_CONTRAST",   0.5 );
 #endif
 
-    p_vout->p_sys->b_mouse_pointer_visible = 1;
-
     /* Disable screen saver and return */
     XVideoDisableScreenSaver( p_vout );
 
@@ -288,7 +351,7 @@ static int vout_Create( vout_thread_t *p_vout )
  *****************************************************************************/
 static int vout_Init( vout_thread_t *p_vout )
 {
-#ifdef SYS_DARWIN1_3
+#ifdef SYS_DARWIN
     /* FIXME : As of 2001-03-16, XFree4 for MacOS X does not support Xshm. */
     p_vout->p_sys->b_shm = 0;
 #endif
@@ -317,6 +380,13 @@ static void vout_End( vout_thread_t *p_vout )
  *****************************************************************************/
 static void vout_Destroy( vout_thread_t *p_vout )
 {
+    /* Restore cursor if it was blanked */
+    if( !p_vout->p_sys->b_mouse_pointer_visible )
+        X11ToggleMousePointer( p_vout );
+
+    /* Destroy blank cursor pixmap */
+    XFreePixmap( p_vout->p_sys->p_display, p_vout->p_sys->cursor_pixmap );
+
     XVideoEnableScreenSaver( p_vout );
     XVideoDestroyWindow( p_vout );
     XCloseDisplay( p_vout->p_sys->p_display );
@@ -479,8 +549,8 @@ static int vout_Manage( vout_thread_t *p_vout )
         else if( xevent.type == MotionNotify )
         {
             p_vout->p_sys->i_time_mouse_last_moved = mdate();
-            p_vout->p_sys->b_mouse_pointer_visible = 1; 
-            XVideoSetMousePointer( p_vout ); 
+            if( !p_vout->p_sys->b_mouse_pointer_visible )
+                X11ToggleMousePointer( p_vout ); 
         }
         /* Other event */
         else
@@ -568,8 +638,7 @@ static int vout_Manage( vout_thread_t *p_vout )
     if( p_vout->p_sys->b_mouse_pointer_visible &&
         mdate() - p_vout->p_sys->i_time_mouse_last_moved > 2000000 )
     {
-        p_vout->p_sys->b_mouse_pointer_visible = 0; 
-        XVideoSetMousePointer( p_vout );
+        X11ToggleMousePointer( p_vout );
     }
     
     return 0;
@@ -672,7 +741,6 @@ static int XVideoUpdateImgSizeIfRequired( vout_thread_t *p_vout )
             (p_vout->p_sys->p_xvimage->data_size) /
             (p_vout->p_sys->p_xvimage->height);
 
-        /* p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_xvimage->data ); */
     }
 
     return( 0 );
@@ -691,15 +759,15 @@ static int XVideoCheckForXv( Display *dpy )
             return( 1 );
 
         case XvBadExtension:
-            intf_ErrMsg( "vout error: XvBadExtension" );
+            intf_WarnMsg( 3, "vout error: XvBadExtension" );
             return( 0 );
 
         case XvBadAlloc:
-            intf_ErrMsg( "vout error: XvBadAlloc" );
+            intf_WarnMsg( 3, "vout error: XvBadAlloc" );
             return( 0 );
 
         default:
-            intf_ErrMsg( "vout error: XvQueryExtension failed" );
+            intf_WarnMsg( 3, "vout error: XvQueryExtension failed" );
             return( 0 );
     }
 }
@@ -869,8 +937,12 @@ static int XVideoCreateWindow( vout_thread_t *p_vout )
     XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->yuv_window,
                   ExposureMask );
 
-
-    XVideoSetMousePointer( p_vout );
+    /* If the cursor was formerly blank than blank it again */
+    if( !p_vout->p_sys->b_mouse_pointer_visible )
+    {
+        X11ToggleMousePointer( p_vout );
+        X11ToggleMousePointer( p_vout );
+    }
 
     return( 0 );
 }
@@ -1012,45 +1084,24 @@ void XVideoDisableScreenSaver( vout_thread_t *p_vout )
 }
 
 /*****************************************************************************
- * XVideoSetMousePointer: hide or show the mouse pointer
+ * X11ToggleMousePointer: hide or show the mouse pointer
  *****************************************************************************
  * This function hides the X pointer if requested.
  *****************************************************************************/
-void XVideoSetMousePointer( const vout_thread_t *p_vout )
+void X11ToggleMousePointer( vout_thread_t *p_vout )
 {
-    static Cursor blank_cursor;
-    static boolean_t b_created_blank_cursor = 0;
 
-    if( !p_vout->p_sys->b_mouse_pointer_visible )
+    if( p_vout->p_sys->b_mouse_pointer_visible )
     {
-        if( !b_created_blank_cursor )
-        {
-            XColor color;
-            Pixmap blank = XCreatePixmap( p_vout->p_sys->p_display,
-                               DefaultRootWindow(p_vout->p_sys->p_display),
-                               1, 1, 1 );
-
-            XParseColor( p_vout->p_sys->p_display,
-                         XCreateColormap( p_vout->p_sys->p_display,
-                                          DefaultRootWindow(
-                                                  p_vout->p_sys->p_display ),
-                                          DefaultVisual(
-                                                  p_vout->p_sys->p_display,
-                                                  p_vout->p_sys->i_screen ),
-                                          AllocNone ),
-                         "black", &color );
-
-            blank_cursor = XCreatePixmapCursor( p_vout->p_sys->p_display,
-                           blank, blank, &color, &color, 1, 1 );
-
-            b_created_blank_cursor = 1;
-        }
         XDefineCursor( p_vout->p_sys->p_display,
-                       p_vout->p_sys->window, blank_cursor );
+                       p_vout->p_sys->window,
+                       p_vout->p_sys->blank_cursor );
+        p_vout->p_sys->b_mouse_pointer_visible = 0;
     }
     else
     {
         XUndefineCursor( p_vout->p_sys->p_display, p_vout->p_sys->window );
+        p_vout->p_sys->b_mouse_pointer_visible = 1;
     }
 }
 
@@ -1131,19 +1182,20 @@ static int XVideoGetPort( Display *dpy )
             break;
 
         case XvBadExtension:
-            intf_ErrMsg( "vout error: XvBadExtension for XvQueryAdaptors" );
+            intf_WarnMsg( 3, "vout error: XvBadExtension for XvQueryAdaptors" );
             return( -1 );
 
         case XvBadAlloc:
-            intf_ErrMsg( "vout error: XvBadAlloc for XvQueryAdaptors" );
+            intf_WarnMsg( 3, "vout error: XvBadAlloc for XvQueryAdaptors" );
             return( -1 );
 
         default:
-            intf_ErrMsg( "vout error: XvQueryAdaptors failed" );
+            intf_WarnMsg( 3, "vout error: XvQueryAdaptors failed" );
             return( -1 );
     }
 
     for( i=0; i < i_adaptors && xv_port == -1; ++i )
+    {
         if( ( adaptor_info[ i ].type & XvInputMask ) &&
             ( adaptor_info[ i ].type & XvImageMask ) )
         {
@@ -1155,24 +1207,37 @@ static int XVideoGetPort( Display *dpy )
             imageFormats = XvListImageFormats( dpy, port, &i_num_formats );
 
             for( i=0; i < i_num_formats && xv_port == -1; ++i )
+            {
                 if( imageFormats[ i ].id == GUID_YUV12_PLANAR )
+                {
                     xv_port = port;
+                }
+            }
 
             if( xv_port == -1 )
+            {
                 intf_WarnMsg( 3, "vout: XVideo image input port %d "
                         "does not support the YUV12 planar format which is "
-                        "currently required by the xvideo output plugin.",
+                        "currently required by the xvideo output plugin",
                         port );
+            }
 
             if( imageFormats )
+            {
                 XFree( imageFormats );
+            }
         }
+    }
 
     if( i_adaptors > 0 )
+    {
         XvFreeAdaptorInfo(adaptor_info);
+    }
 
     if( xv_port == -1 )
-        intf_ErrMsg( "vout error: didn't find a suitable Xvideo image input port." );
+    {
+        intf_WarnMsg( 3, "vout: no suitable Xvideo image input port" );
+    }
 
     return( xv_port );
 }
@@ -1189,7 +1254,10 @@ static void XVideoDisplay( vout_thread_t *p_vout )
 {
     int     i_dest_width, i_dest_height, i_dest_x, i_dest_y;
 
-    if( !p_vout->p_sys->p_xvimage ) return;
+    if( !p_vout->p_sys->p_xvimage )
+    {
+        return;
+    }
 
     XVideoOutputCoords( p_vout->p_rendered_pic, p_vout->b_scale,
                         p_vout->p_sys->i_window_width,
@@ -1204,12 +1272,15 @@ static void XVideoDisplay( vout_thread_t *p_vout )
                    p_vout->p_rendered_pic->i_width,
                    p_vout->p_rendered_pic->i_height,
                    0 /*dest_x*/, 0 /*dest_y*/, i_dest_width, i_dest_height,
-                   True );
+                   False );
+
+    XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->yuv_window,
+                   i_dest_width, i_dest_height );
+    XMoveWindow( p_vout->p_sys->p_display, p_vout->p_sys->yuv_window,
+                 i_dest_x, i_dest_y );
 
-     XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->yuv_window,
-             i_dest_width, i_dest_height );
-     XMoveWindow( p_vout->p_sys->p_display, p_vout->p_sys->yuv_window,
-             i_dest_x, i_dest_y );
+    /* Send the order to the X server */
+    XSync( p_vout->p_sys->p_display, False );
 }
 
 #if 0