]> git.sesse.net Git - vlc/blobdiff - modules/video_output/sdl.c
Fix memleak in sdl video output. (string passed to setenv have to be freed after).
[vlc] / modules / video_output / sdl.c
index 9aa8f5f3eb8f7e908e542df4848e4b5b96ba574a..0bc7de17d5a14157aef0ac80fd7f454adaded16d 100644 (file)
  *****************************************************************************/
 #include <errno.h>                                                 /* ENOMEM */
 
-#include <vlc/vlc.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
 #include <vlc_interface.h>
 #include <vlc_playlist.h>
 #include <vlc_vout.h>
@@ -59,8 +64,10 @@ struct vout_sys_t
     int i_width;
     int i_height;
 
+#if SDL_VERSION_ATLEAST(1,2,10)
     unsigned int i_desktop_width;
     unsigned int i_desktop_height;
+#endif
 
     /* For YUV output */
     SDL_Overlay * p_overlay;   /* An overlay we keep to grab the XVideo port */
@@ -68,9 +75,10 @@ struct vout_sys_t
     /* For RGB output */
     int i_surfaces;
 
-    vlc_bool_t  b_cursor;
-    vlc_bool_t  b_cursor_autohidden;
+    bool  b_cursor;
+    bool  b_cursor_autohidden;
     mtime_t     i_lastmoved;
+    mtime_t     i_mouse_hide_timeout;
     mtime_t     i_lastpressed;                        /* to track dbl-clicks */
 };
 
@@ -116,10 +124,10 @@ vlc_module_begin();
     set_shortname( "SDL" );
     set_category( CAT_VIDEO );
     set_subcategory( SUBCAT_VIDEO_VOUT );
-    set_description( _("Simple DirectMedia Layer video output") );
+    set_description( N_("Simple DirectMedia Layer video output") );
     set_capability( "video output", 60 );
     add_shortcut( "sdl" );
-    add_string( "sdl-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, VLC_TRUE );
+    add_string( "sdl-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, true );
     set_callbacks( Open, Close );
 #if defined( __i386__ ) || defined( __x86_64__ )
     /* On i386, SDL is linked against svgalib */
@@ -154,6 +162,8 @@ static int Open ( vlc_object_t *p_this )
         return VLC_ENOMEM;
     }
 
+    memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );
+
     /* Check if SDL video module has been initialized */
     if( SDL_WasInit( SDL_INIT_VIDEO ) != 0 )
     {
@@ -171,7 +181,7 @@ static int Open ( vlc_object_t *p_this )
     p_vout->pf_control = NULL;
 
 #ifdef HAVE_SETENV
-    psz_method = config_GetPsz( p_vout, "vout" );
+    char* psz = psz_method = config_GetPsz( p_vout, "vout" );
     if( psz_method )
     {
         while( *psz_method && *psz_method != ':' )
@@ -184,6 +194,7 @@ static int Open ( vlc_object_t *p_this )
             setenv( "SDL_VIDEODRIVER", psz_method + 1, 1 );
         }
     }
+    free( psz );
 #endif
 
     /* Initialize library */
@@ -192,7 +203,7 @@ static int Open ( vlc_object_t *p_this )
     /* Win32 SDL implementation doesn't support SDL_INIT_EVENTTHREAD yet*/
                 | SDL_INIT_EVENTTHREAD
 #endif
-#ifdef DEBUG
+#ifndef NDEBUG
     /* In debug mode you may want vlc to dump a core instead of staying
      * stuck */
                 | SDL_INIT_NOPARACHUTE
@@ -211,13 +222,18 @@ static int Open ( vlc_object_t *p_this )
     SDL_EnableUNICODE(1);
 
     /* Get the desktop resolution */
+#if SDL_VERSION_ATLEAST(1,2,10)
+    /* FIXME: SDL has a problem with virtual desktop */
     p_vout->p_sys->i_desktop_width = SDL_GetVideoInfo()->current_w;
     p_vout->p_sys->i_desktop_height = SDL_GetVideoInfo()->current_h;
+#endif
 
     /* Create the cursor */
     p_vout->p_sys->b_cursor = 1;
     p_vout->p_sys->b_cursor_autohidden = 0;
     p_vout->p_sys->i_lastmoved = p_vout->p_sys->i_lastpressed = mdate();
+    p_vout->p_sys->i_mouse_hide_timeout =
+        var_GetInteger(p_vout, "mouse-hide-timeout") * 1000;
 
     if( OpenDisplay( p_vout ) )
     {
@@ -394,7 +410,7 @@ static int Manage( vout_thread_t *p_vout )
 
             var_Set( p_vout, "mouse-y", val );
 
-            val.b_bool = VLC_TRUE;
+            val.b_bool = true;
             var_Set( p_vout, "mouse-moved", val );
 
             if( p_vout->p_sys->b_cursor )
@@ -416,39 +432,35 @@ static int Manage( vout_thread_t *p_vout )
             switch( event.button.button )
             {
             case SDL_BUTTON_LEFT:
-                var_Get( p_vout, "mouse-button-down", &val );
-                val.i_int &= ~1;
-                var_Set( p_vout, "mouse-button-down", val );
+                {
+                    var_Get( p_vout, "mouse-button-down", &val );
+                    val.i_int &= ~1;
+                    var_Set( p_vout, "mouse-button-down", val );
+
+                    val.b_bool = true;
+                    var_Set( p_vout, "mouse-clicked", val );
 
-                val.b_bool = VLC_TRUE;
-                var_Set( p_vout, "mouse-clicked", val );
+                    val.b_bool = false;
+                    var_Set( p_vout->p_libvlc, "intf-popupmenu", val );
+                }
                 break;
 
             case SDL_BUTTON_MIDDLE:
                 {
-                    playlist_t *p_playlist;
-
                     var_Get( p_vout, "mouse-button-down", &val );
                     val.i_int &= ~2;
                     var_Set( p_vout, "mouse-button-down", val );
 
-                    p_playlist = vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST,
-                                              FIND_ANYWHERE );
-                    if( p_playlist != NULL )
-                    {
-                        vlc_value_t val;
-                        var_Get( p_playlist, "intf-show", &val );
-                        val.b_bool = !val.b_bool;
-                        var_Set( p_playlist, "intf-show", val );
-                        vlc_object_release( p_playlist );
-                    }
+                    vlc_value_t val;
+                    var_Get( p_vout->p_libvlc, "intf-show", &val );
+                    val.b_bool = !val.b_bool;
+                    var_Set( p_vout->p_libvlc, "intf-show", val );
                 }
                 break;
 
             case SDL_BUTTON_RIGHT:
                 {
                     intf_thread_t *p_intf;
-                    playlist_t *p_playlist;
 
                     var_Get( p_vout, "mouse-button-down", &val );
                     val.i_int &= ~4;
@@ -461,16 +473,8 @@ static int Manage( vout_thread_t *p_vout )
                         vlc_object_release( p_intf );
                     }
 
-                    p_playlist = vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST,
-                                                FIND_ANYWHERE );
-
-                    if( p_playlist != NULL )
-                    {
-                        vlc_value_t val;
-                        val.b_bool = VLC_TRUE;
-                        var_Set( p_playlist, "intf-popupmenu", val );
-                        vlc_object_release( p_playlist );
-                    }
+                    val.b_bool = true;
+                    var_Set( p_vout->p_libvlc, "intf-popupmenu", val );
                 }
                 break;
             }
@@ -509,12 +513,16 @@ static int Manage( vout_thread_t *p_vout )
         /* Quit event (close the window) */
         case SDL_QUIT:
             {
-                playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+#if 0
+                playlist_t *p_playlist = pl_Yield( p_vout );
                 if( p_playlist != NULL )
                 {
                     playlist_Stop( p_playlist );
-                    vlc_object_release( p_playlist );
+                    pl_Release( p_vout );
                 }
+#else
+#warning FIXME FIXME ?
+#endif
             }
             break;
 
@@ -616,7 +624,8 @@ static int Manage( vout_thread_t *p_vout )
 
     /* Pointer change */
     if( ! p_vout->p_sys->b_cursor_autohidden &&
-        ( mdate() - p_vout->p_sys->i_lastmoved > 2000000 ) )
+        ( mdate() - p_vout->p_sys->i_lastmoved >
+            p_vout->p_sys->i_mouse_hide_timeout ) )
     {
         /* Hide the mouse automatically */
         p_vout->p_sys->b_cursor_autohidden = 1;
@@ -741,11 +750,20 @@ static int OpenDisplay( vout_thread_t *p_vout )
     char *psz_chroma = NULL;
     uint32_t i_chroma = 0;
 
+    bool b_overlay = config_GetInt( p_vout, "overlay" );
+
     /* Set main window's size */
+#if SDL_VERSION_ATLEAST(1,2,10)
     p_vout->p_sys->i_width = p_vout->b_fullscreen ? p_vout->p_sys->i_desktop_width :
                                                     p_vout->i_window_width;
     p_vout->p_sys->i_height = p_vout->b_fullscreen ? p_vout->p_sys->i_desktop_height :
                                                      p_vout->i_window_height;
+#else
+    p_vout->p_sys->i_width = p_vout->b_fullscreen ? p_vout->output.i_width :
+                                                    p_vout->i_window_width;
+    p_vout->p_sys->i_height = p_vout->b_fullscreen ? p_vout->output.i_height :
+                                                     p_vout->i_window_height;
+#endif
 
     /* Initialize flags and cursor */
     i_flags = SDL_ANYFORMAT | SDL_HWPALETTE | SDL_HWSURFACE | SDL_DOUBLEBUF;
@@ -785,75 +803,82 @@ static int OpenDisplay( vout_thread_t *p_vout )
         }
     }
 
-    /* Choose the chroma we will try first. */
-    do
+    if( b_overlay )
     {
-        if( !psz_chroma ) i_chroma = 0;
-        switch( i_chroma ? i_chroma : p_vout->render.i_chroma )
+        /* Choose the chroma we will try first. */
+        do
         {
-            case VLC_FOURCC('Y','U','Y','2'):
-            case VLC_FOURCC('Y','U','N','V'):
-                p_vout->output.i_chroma = VLC_FOURCC('Y','U','Y','2');
-                i_sdl_chroma = SDL_YUY2_OVERLAY;
-                break;
-            case VLC_FOURCC('U','Y','V','Y'):
-            case VLC_FOURCC('U','Y','N','V'):
-            case VLC_FOURCC('Y','4','2','2'):
-                p_vout->output.i_chroma = VLC_FOURCC('U','Y','V','Y');
-                i_sdl_chroma = SDL_UYVY_OVERLAY;
-                break;
-            case VLC_FOURCC('Y','V','Y','U'):
-                p_vout->output.i_chroma = VLC_FOURCC('Y','V','Y','U');
-                i_sdl_chroma = SDL_YVYU_OVERLAY;
-                break;
-            case VLC_FOURCC('Y','V','1','2'):
-            case VLC_FOURCC('I','4','2','0'):
-            case VLC_FOURCC('I','Y','U','V'):
-            default:
-                p_vout->output.i_chroma = VLC_FOURCC('Y','V','1','2');
-                i_sdl_chroma = SDL_YV12_OVERLAY;
-                break;
-        }
-        free( psz_chroma ); psz_chroma = NULL;
+            if( !psz_chroma ) i_chroma = 0;
+            switch( i_chroma ? i_chroma : p_vout->render.i_chroma )
+            {
+                case VLC_FOURCC('Y','U','Y','2'):
+                case VLC_FOURCC('Y','U','N','V'):
+                    p_vout->output.i_chroma = VLC_FOURCC('Y','U','Y','2');
+                    i_sdl_chroma = SDL_YUY2_OVERLAY;
+                    break;
+                case VLC_FOURCC('U','Y','V','Y'):
+                case VLC_FOURCC('U','Y','N','V'):
+                case VLC_FOURCC('Y','4','2','2'):
+                    p_vout->output.i_chroma = VLC_FOURCC('U','Y','V','Y');
+                    i_sdl_chroma = SDL_UYVY_OVERLAY;
+                    break;
+                case VLC_FOURCC('Y','V','Y','U'):
+                    p_vout->output.i_chroma = VLC_FOURCC('Y','V','Y','U');
+                    i_sdl_chroma = SDL_YVYU_OVERLAY;
+                    break;
+                case VLC_FOURCC('Y','V','1','2'):
+                case VLC_FOURCC('I','4','2','0'):
+                case VLC_FOURCC('I','Y','U','V'):
+                default:
+                    p_vout->output.i_chroma = VLC_FOURCC('Y','V','1','2');
+                    i_sdl_chroma = SDL_YV12_OVERLAY;
+                    break;
+            }
+            free( psz_chroma ); psz_chroma = NULL;
 
-        p_vout->p_sys->p_overlay =
-            SDL_CreateYUVOverlay( 32, 32, i_sdl_chroma,
-                                  p_vout->p_sys->p_display );
-        /* FIXME: if the first overlay we find is software, don't stop,
-         * because we may find a hardware one later ... */
-    }
-    while( i_chroma && !p_vout->p_sys->p_overlay );
+            p_vout->p_sys->p_overlay =
+                SDL_CreateYUVOverlay( 32, 32, i_sdl_chroma,
+                                      p_vout->p_sys->p_display );
+            /* FIXME: if the first overlay we find is software, don't stop,
+             * because we may find a hardware one later ... */
+        }
+        while( i_chroma && !p_vout->p_sys->p_overlay );
 
 
-    /* If this best choice failed, fall back to other chromas */
-    if( p_vout->p_sys->p_overlay == NULL )
-    {
-        p_vout->output.i_chroma = VLC_FOURCC('I','Y','U','V');
-        p_vout->p_sys->p_overlay =
-            SDL_CreateYUVOverlay( 32, 32, SDL_IYUV_OVERLAY,
-                                  p_vout->p_sys->p_display );
-    }
+        /* If this best choice failed, fall back to other chromas */
+        if( p_vout->p_sys->p_overlay == NULL )
+        {
+            p_vout->output.i_chroma = VLC_FOURCC('I','Y','U','V');
+            p_vout->p_sys->p_overlay =
+                SDL_CreateYUVOverlay( 32, 32, SDL_IYUV_OVERLAY,
+                                      p_vout->p_sys->p_display );
+        }
 
-    if( p_vout->p_sys->p_overlay == NULL )
-    {
-        p_vout->output.i_chroma = VLC_FOURCC('Y','V','1','2');
-        p_vout->p_sys->p_overlay =
-            SDL_CreateYUVOverlay( 32, 32, SDL_YV12_OVERLAY,
-                                  p_vout->p_sys->p_display );
-    }
+        if( p_vout->p_sys->p_overlay == NULL )
+        {
+            p_vout->output.i_chroma = VLC_FOURCC('Y','V','1','2');
+            p_vout->p_sys->p_overlay =
+                SDL_CreateYUVOverlay( 32, 32, SDL_YV12_OVERLAY,
+                                      p_vout->p_sys->p_display );
+        }
 
-    if( p_vout->p_sys->p_overlay == NULL )
-    {
-        p_vout->output.i_chroma = VLC_FOURCC('Y','U','Y','2');
-        p_vout->p_sys->p_overlay =
-            SDL_CreateYUVOverlay( 32, 32, SDL_YUY2_OVERLAY,
-                                  p_vout->p_sys->p_display );
+        if( p_vout->p_sys->p_overlay == NULL )
+        {
+            p_vout->output.i_chroma = VLC_FOURCC('Y','U','Y','2');
+            p_vout->p_sys->p_overlay =
+                SDL_CreateYUVOverlay( 32, 32, SDL_YUY2_OVERLAY,
+                                      p_vout->p_sys->p_display );
+        }
     }
 
     if( p_vout->p_sys->p_overlay == NULL )
     {
-        msg_Warn( p_vout, "no SDL overlay for 0x%.8x (%4.4s)",
-                  p_vout->render.i_chroma, (char*)&p_vout->render.i_chroma );
+        if( b_overlay )
+            msg_Warn( p_vout, "no SDL overlay for 0x%.8x (%4.4s)",
+                      p_vout->render.i_chroma,
+                      (char*)&p_vout->render.i_chroma );
+        else
+            msg_Warn( p_vout, "SDL overlay disabled by the user" );
 
         switch( p_vout->p_sys->p_display->format->BitsPerPixel )
         {