]> git.sesse.net Git - vlc/blobdiff - src/interface/interface.c
Set intf-add before loading the interface module
[vlc] / src / interface / interface.c
index 7975a38e42364e4d793377e8c0ad644f345c698c..766c521690be68dc1b81de0a110172cda28d7366 100644 (file)
@@ -43,6 +43,9 @@
 #include <vlc_vout.h>
 
 #include "vlc_interface.h"
+#if defined( __APPLE__ ) || defined( WIN32 )
+#include "../control/libvlc_internal.h"
+#endif
 #include "libvlc.h"
 
 /*****************************************************************************
@@ -64,32 +67,56 @@ static void intf_Destroy( vlc_object_t *obj )
 {
     intf_thread_t *p_intf = (intf_thread_t *)obj;
 
-    /* Unlock module if present (a switch may have failed) */
-    if( p_intf->p_module )
-        module_unneed( p_intf, p_intf->p_module );
-
     free( p_intf->psz_intf );
     config_ChainDestroy( p_intf->p_cfg );
-    vlc_mutex_destroy( &p_intf->change_lock );
 }
 
 
+#undef intf_Create
 /**
- * Create the interface, and prepare it for main loop. It opens ouput device
- * and creates specific interfaces. Sends its own error messages.
+ * Create and start an interface.
  *
  * @param p_this the calling vlc_object_t
  * @param psz_module a preferred interface module
- * @return a pointer to the created interface thread, NULL on error
+ * @return VLC_SUCCESS or an error code
  */
-intf_thread_t* __intf_Create( vlc_object_t *p_this, const char *psz_module )
+int intf_Create( vlc_object_t *p_this, const char *psz_module )
 {
     intf_thread_t * p_intf;
 
     /* Allocate structure */
     p_intf = vlc_object_create( p_this, VLC_OBJECT_INTF );
     if( !p_intf )
-        return NULL;
+        return VLC_ENOMEM;
+
+    /* Variable used for interface spawning */
+    vlc_value_t val, text;
+    var_Create( p_intf, "intf-add", VLC_VAR_STRING |
+                VLC_VAR_HASCHOICE | VLC_VAR_ISCOMMAND );
+    text.psz_string = _("Add Interface");
+    var_Change( p_intf, "intf-add", VLC_VAR_SETTEXT, &text, NULL );
+
+    val.psz_string = (char *)"rc";
+    text.psz_string = (char *)_("Console");
+    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
+    val.psz_string = (char *)"telnet";
+    text.psz_string = (char *)_("Telnet Interface");
+    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
+    val.psz_string = (char *)"http";
+    text.psz_string = (char *)_("Web Interface");
+    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
+    val.psz_string = (char *)"logger";
+    text.psz_string = (char *)_("Debug logging");
+    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
+    val.psz_string = (char *)"gestures";
+    text.psz_string = (char *)_("Mouse Gestures");
+    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
+
+    var_AddCallback( p_intf, "intf-add", AddIntfCallback, NULL );
+
+    /* Attach interface to its parent object */
+    vlc_object_attach( p_intf, p_this );
+    vlc_object_set_destructor( p_intf, intf_Destroy );
 #if defined( __APPLE__ ) || defined( WIN32 )
     p_intf->b_should_run_on_first_thread = false;
 #endif
@@ -104,34 +131,13 @@ intf_thread_t* __intf_Create( vlc_object_t *p_this, const char *psz_module )
     free( psz_tmp );
     free( psz_parser );
     p_intf->p_module = module_need( p_intf, "interface", p_intf->psz_intf, true );
-
     if( p_intf->p_module == NULL )
     {
         msg_Err( p_intf, "no suitable interface module" );
-        free( p_intf->psz_intf );
         vlc_object_release( p_intf );
-        return NULL;
+        return VLC_EGENERIC;
     }
 
-    /* Initialize mutexes */
-    vlc_mutex_init( &p_intf->change_lock );
-
-    /* Attach interface to its parent object */
-    vlc_object_attach( p_intf, p_this );
-    vlc_object_set_destructor( p_intf, intf_Destroy );
-
-    return p_intf;
-}
-
-
-/**
- * Starts and runs the interface thread.
- *
- * @param p_intf the interface thread
- * @return VLC_SUCCESS on success, an error number else
- */
-int intf_RunThread( intf_thread_t *p_intf )
-{
 #if defined( __APPLE__ ) || defined( WIN32 )
     /* Hack to get Mac OS X Cocoa runtime running
      * (it needs access to the main thread) */
@@ -141,7 +147,8 @@ int intf_RunThread( intf_thread_t *p_intf )
                                VLC_THREAD_PRIORITY_LOW ) )
         {
             msg_Err( p_intf, "cannot spawn libvlc death monitoring thread" );
-            return VLC_EGENERIC;
+            vlc_object_release( p_intf );
+            return VLC_ENOMEM;
         }
         RunInterface( VLC_OBJECT(p_intf) );
 
@@ -161,6 +168,7 @@ int intf_RunThread( intf_thread_t *p_intf )
                            VLC_THREAD_PRIORITY_LOW ) )
     {
         msg_Err( p_intf, "cannot spawn interface thread" );
+        vlc_object_release( p_intf );
         return VLC_EGENERIC;
     }
 
@@ -179,6 +187,8 @@ void intf_StopThread( intf_thread_t *p_intf )
     /* Tell the interface to die */
     vlc_object_kill( p_intf );
     vlc_thread_join( p_intf );
+
+    module_unneed( p_intf, p_intf->p_module );
 }
 
 
@@ -193,33 +203,6 @@ void intf_StopThread( intf_thread_t *p_intf )
 static void* RunInterface( vlc_object_t *p_this )
 {
     intf_thread_t *p_intf = (intf_thread_t *)p_this;
-    vlc_value_t val, text;
-    int canc = vlc_savecancel ();
-
-    /* Variable used for interface spawning */
-    var_Create( p_intf, "intf-add", VLC_VAR_STRING |
-                VLC_VAR_HASCHOICE | VLC_VAR_ISCOMMAND );
-    text.psz_string = _("Add Interface");
-    var_Change( p_intf, "intf-add", VLC_VAR_SETTEXT, &text, NULL );
-
-    val.psz_string = (char *)"rc";
-    text.psz_string = (char *)_("Console");
-    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
-    val.psz_string = (char *)"telnet";
-    text.psz_string = (char *)_("Telnet Interface");
-    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
-    val.psz_string = (char *)"http";
-    text.psz_string = (char *)_("Web Interface");
-    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
-    val.psz_string = (char *)"logger";
-    text.psz_string = (char *)_("Debug logging");
-    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
-    val.psz_string = (char *)"gestures";
-    text.psz_string = (char *)_("Mouse Gestures");
-    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
-
-    var_AddCallback( p_intf, "intf-add", AddIntfCallback, NULL );
-    vlc_restorecancel (canc);
 
     /* Give control to the interface */
     if( p_intf->pf_run )
@@ -253,30 +236,16 @@ static int AddIntfCallback( vlc_object_t *p_this, char const *psz_cmd,
                          vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
     (void)psz_cmd; (void)oldval; (void)p_data;
-    intf_thread_t *p_intf;
     char* psz_intf;
 
     /* Try to create the interface */
     if( asprintf( &psz_intf, "%s,none", newval.psz_string ) == -1 )
         return VLC_ENOMEM;
 
-    p_intf = intf_Create( p_this->p_libvlc, psz_intf );
+    int ret = intf_Create( p_this->p_libvlc, psz_intf );
     free( psz_intf );
-    if( p_intf == NULL )
-    {
+    if( ret )
         msg_Err( p_this, "interface \"%s\" initialization failed",
                  newval.psz_string );
-        return VLC_EGENERIC;
-    }
-
-    /* Try to run the interface */
-    if( intf_RunThread( p_intf ) != VLC_SUCCESS )
-    {
-        vlc_object_detach( p_intf );
-        vlc_object_release( p_intf );
-        return VLC_EGENERIC;
-    }
-
-    return VLC_SUCCESS;
+    return ret;
 }
-