]> git.sesse.net Git - vlc/blobdiff - modules/control/rc.c
Find the playlist once *before* starting.
[vlc] / modules / control / rc.c
index d5a345686d4ff62965c3e8b8ec6f3573d827adf3..48ae3bb1788ddffbeb6a14a9cc97ddc1196f7a29 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * rc.c : remote control stdin/stdout module for vlc
  *****************************************************************************
- * Copyright (C) 2004 - 2005 the VideoLAN team
+ * Copyright (C) 2004-2007 the VideoLAN team
  * $Id$
  *
  * Author: Peter Surda <shurdeek@panorama.sth.ac.at>
  *****************************************************************************/
 #include <vlc/vlc.h>
 
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <string.h>
 
 #include <errno.h>                                                 /* ENOMEM */
-#include <stdio.h>
 #include <ctype.h>
 #include <signal.h>
 
@@ -85,8 +82,6 @@ static int  Input        ( vlc_object_t *, char const *,
                            vlc_value_t, vlc_value_t, void * );
 static int  Playlist     ( vlc_object_t *, char const *,
                            vlc_value_t, vlc_value_t, void * );
-static int  Other        ( vlc_object_t *, char const *,
-                           vlc_value_t, vlc_value_t, void * );
 static int  Quit         ( vlc_object_t *, char const *,
                            vlc_value_t, vlc_value_t, void * );
 static int  Intf         ( vlc_object_t *, char const *,
@@ -185,15 +180,16 @@ vlc_module_begin();
     set_subcategory( SUBCAT_INTERFACE_MAIN );
     set_description( _("Remote control interface") );
     add_bool( "rc-show-pos", 0, NULL, POS_TEXT, POS_LONGTEXT, VLC_TRUE );
-#ifdef HAVE_ISATTY
-    add_bool( "rc-fake-tty", 0, NULL, TTY_TEXT, TTY_LONGTEXT, VLC_TRUE );
-#endif
-    add_string( "rc-unix", 0, NULL, UNIX_TEXT, UNIX_LONGTEXT, VLC_TRUE );
-    add_string( "rc-host", 0, NULL, HOST_TEXT, HOST_LONGTEXT, VLC_TRUE );
 
 #ifdef WIN32
     add_bool( "rc-quiet", 0, NULL, QUIET_TEXT, QUIET_LONGTEXT, VLC_FALSE );
+#else
+#if defined (HAVE_ISATTY)
+    add_bool( "rc-fake-tty", 0, NULL, TTY_TEXT, TTY_LONGTEXT, VLC_TRUE );
+#endif
+    add_string( "rc-unix", 0, NULL, UNIX_TEXT, UNIX_LONGTEXT, VLC_TRUE );
 #endif
+    add_string( "rc-host", 0, NULL, HOST_TEXT, HOST_LONGTEXT, VLC_TRUE );
 
     set_capability( "interface", 20 );
     set_callbacks( Activate, Deactivate );
@@ -208,7 +204,8 @@ static int Activate( vlc_object_t *p_this )
     char *psz_host, *psz_unix_path;
     int  *pi_socket = NULL;
 
-#if defined(HAVE_ISATTY) && !defined(WIN32)
+#ifndef WIN32
+#if defined(HAVE_ISATTY)
     /* Check that stdin is a TTY */
     if( !config_GetInt( p_intf, "rc-fake-tty" ) && !isatty( 0 ) )
     {
@@ -220,11 +217,9 @@ static int Activate( vlc_object_t *p_this )
     psz_unix_path = config_GetPsz( p_intf, "rc-unix" );
     if( psz_unix_path )
     {
-        int i_socket, i_overwrite;
-
-        i_overwrite = config_GetInt( p_intf, "rc-overwrite" );
+        int i_socket;
 
-#if !defined(AF_LOCAL) || defined(WIN32)
+#ifndef AF_LOCAL
         msg_Warn( p_intf, "your OS doesn't support filesystem sockets" );
         free( psz_unix_path );
         return VLC_EGENERIC;
@@ -237,7 +232,7 @@ static int Activate( vlc_object_t *p_this )
 
         if( (i_socket = socket( AF_LOCAL, SOCK_STREAM, 0 ) ) < 0 )
         {
-            msg_Warn( p_intf, "can't open socket: %s", strerror(errno) );
+            msg_Warn( p_intf, "can't open socket: %m" );
             free( psz_unix_path );
             return VLC_EGENERIC;
         }
@@ -256,8 +251,8 @@ static int Activate( vlc_object_t *p_this )
 
             if (bind (i_socket, (struct sockaddr *)&addr, sizeof (addr)))
             {
-                msg_Err (p_intf, "cannot bind UNIX socket at %s: %s",
-                         psz_unix_path, strerror (errno));
+                msg_Err (p_intf, "cannot bind UNIX socket at %s: %m",
+                         psz_unix_path);
                 free (psz_unix_path);
                 net_Close (i_socket);
                 return VLC_EGENERIC;
@@ -266,7 +261,7 @@ static int Activate( vlc_object_t *p_this )
 
         if( listen( i_socket, 1 ) )
         {
-            msg_Warn( p_intf, "can't listen on socket: %s", strerror(errno));
+            msg_Warn( p_intf, "can't listen on socket: %m");
             free( psz_unix_path );
             net_Close( i_socket );
             return VLC_EGENERIC;
@@ -282,8 +277,9 @@ static int Activate( vlc_object_t *p_this )
         }
         pi_socket[0] = i_socket;
         pi_socket[1] = -1;
-#endif
+#endif /* AF_LOCAL */
     }
+#endif /* !WIN32 */
 
     if( ( pi_socket == NULL ) &&
         ( psz_host = config_GetPsz( p_intf, "rc-host" ) ) != NULL )
@@ -384,38 +380,6 @@ static void RegisterCallbacks( intf_thread_t *p_intf )
     ADD( "goto", INTEGER, Playlist )
     ADD( "status", INTEGER, Playlist )
 
-    /* marquee on the fly items */
-    ADD( "marq-marquee", STRING, Other )
-    ADD( "marq-x", INTEGER, Other )
-    ADD( "marq-y", INTEGER, Other )
-    ADD( "marq-position", INTEGER, Other )
-    ADD( "marq-color", INTEGER, Other )
-    ADD( "marq-opacity", INTEGER, Other )
-    ADD( "marq-timeout", INTEGER, Other )
-    ADD( "marq-size", INTEGER, Other )
-
-    ADD( "mosaic-alpha", INTEGER, Other )
-    ADD( "mosaic-height", INTEGER, Other )
-    ADD( "mosaic-width", INTEGER, Other )
-    ADD( "mosaic-xoffset", INTEGER, Other )
-    ADD( "mosaic-yoffset", INTEGER, Other )
-    ADD( "mosaic-offsets", STRING, Other )
-    ADD( "mosaic-align", INTEGER, Other )
-    ADD( "mosaic-vborder", INTEGER, Other )
-    ADD( "mosaic-hborder", INTEGER, Other )
-    ADD( "mosaic-position", INTEGER, Other )
-    ADD( "mosaic-rows", INTEGER, Other )
-    ADD( "mosaic-cols", INTEGER, Other )
-    ADD( "mosaic-order", STRING, Other )
-    ADD( "mosaic-keep-aspect-ratio", INTEGER, Other )
-
-    /* logo on the fly items */
-    ADD( "logo-file", STRING, Other )
-    ADD( "logo-x", INTEGER, Other )
-    ADD( "logo-y", INTEGER, Other )
-    ADD( "logo-position", INTEGER, Other )
-    ADD( "logo-transparency", INTEGER, Other )
-
     /* OSD menu commands */
     ADD(  "menu", STRING, Menu )
 
@@ -490,7 +454,7 @@ static void Run( intf_thread_t *p_intf )
     if( p_intf->p_sys->hConsoleIn == INVALID_HANDLE_VALUE )
     {
         msg_Err( p_intf, "couldn't find user input handle" );
-        p_intf->b_die = VLC_TRUE;
+        vlc_object_kill( p_intf );
     }
 #endif
 
@@ -503,7 +467,9 @@ static void Run( intf_thread_t *p_intf )
             p_intf->p_sys->i_socket == -1 )
         {
             p_intf->p_sys->i_socket =
-                net_Accept( p_intf, p_intf->p_sys->pi_socket_listen, 0 );
+                net_Accept( p_intf, p_intf->p_sys->pi_socket_listen,
+                            INTF_IDLE_SLEEP );
+            if( p_intf->p_sys->i_socket == -1 ) continue;
         }
 
         b_complete = ReadCommand( p_intf, p_buffer, &i_size );
@@ -531,8 +497,10 @@ static void Run( intf_thread_t *p_intf )
             {
                 if( !p_input->b_dead || !p_input->b_die )
                 {
-                    msg_rc( STATUS_CHANGE "( new input: %s )",
-                            input_GetItem(p_input)->psz_uri );
+                    char *psz_uri =
+                            input_item_GetURI( input_GetItem( p_input ) );
+                    msg_rc( STATUS_CHANGE "( new input: %s )", psz_uri );
+                    free( psz_uri );
                     msg_rc( STATUS_CHANGE "( audio volume: %d )",
                             config_GetInt( p_intf, "volume" ));
                 }
@@ -628,8 +596,37 @@ static void Run( intf_thread_t *p_intf )
             psz_arg = "";
         }
 
+        /* module specfic commands: @<module name> <command> <args...> */
+        if( *psz_cmd == '@' && *psz_arg )
+        {
+            /* Parse miscellaneous commands */
+            char *psz_alias = psz_cmd + 1;
+            char *psz_mycmd = strdup( psz_arg );
+            char *psz_myarg = strchr( psz_mycmd, ' ' );
+            char *psz_msg;
+
+            if( !psz_myarg )
+            {
+                msg_rc( "Not enough parameters." );
+            }
+            else
+            {
+                *psz_myarg = '\0';
+                psz_myarg ++;
+
+                var_Command( p_intf, psz_alias, psz_mycmd, psz_myarg,
+                             &psz_msg );
+
+                if( psz_msg )
+                {
+                    msg_rc( psz_msg );
+                    free( psz_msg );
+                }
+            }
+            free( psz_mycmd );
+        }
         /* If the user typed a registered local command, try it */
-        if( var_Type( p_intf, psz_cmd ) & VLC_VAR_ISCOMMAND )
+        else if( var_Type( p_intf, psz_cmd ) & VLC_VAR_ISCOMMAND )
         {
             vlc_value_t val;
             int i_ret;
@@ -640,15 +637,15 @@ static void Run( intf_thread_t *p_intf )
                     psz_cmd, i_ret, vlc_error( i_ret ) );
         }
         /* Or maybe it's a global command */
-        else if( var_Type( p_intf->p_libvlc_global, psz_cmd ) & VLC_VAR_ISCOMMAND )
+        else if( var_Type( p_intf->p_libvlc, psz_cmd ) & VLC_VAR_ISCOMMAND )
         {
             vlc_value_t val;
             int i_ret;
 
             val.psz_string = psz_arg;
             /* FIXME: it's a global command, but we should pass the
-             * local object as an argument, not p_intf->p_libvlc_global. */
-            i_ret = var_Set( p_intf->p_libvlc_global, psz_cmd, val );
+             * local object as an argument, not p_intf->p_libvlc. */
+            i_ret = var_Set( p_intf->p_libvlc, psz_cmd, val );
             if( i_ret != 0 )
             {
                 msg_rc( "%s: returned %i (%s)",
@@ -754,6 +751,11 @@ static void Run( intf_thread_t *p_intf )
         {
             checkUpdates( p_intf, psz_arg );
         }
+        else if( !strcmp( psz_cmd, "key" ) || !strcmp( psz_cmd, "hotkey" ) )
+        {
+            var_SetInteger( p_intf->p_libvlc, "key-pressed",
+                            config_GetInt( p_intf, psz_arg ) );
+        }
         else switch( psz_cmd[0] )
         {
         case 'f':
@@ -836,93 +838,94 @@ static void Help( intf_thread_t *p_intf, vlc_bool_t b_longhelp)
 {
     msg_rc(_("+----[ Remote control commands ]"));
     msg_rc(  "| ");
-    msg_rc(_("| add XYZ  . . . . . . . . . . add XYZ to playlist"));
-    msg_rc(_("| enqueue XYZ  . . . . . . . queue XYZ to playlist"));
-    msg_rc(_("| playlist . . .  show items currently in playlist"));
-    msg_rc(_("| play . . . . . . . . . . . . . . . . play stream"));
-    msg_rc(_("| stop . . . . . . . . . . . . . . . . stop stream"));
-    msg_rc(_("| next . . . . . . . . . . . .  next playlist item"));
-    msg_rc(_("| prev . . . . . . . . . .  previous playlist item"));
-    msg_rc(_("| goto . . . . . . . . . . . .  goto item at index"));
-    msg_rc(_("| repeat [on|off] . .  toggle playlist item repeat"));
-    msg_rc(_("| loop [on|off] . . . .  toggle playlist item loop"));
-    msg_rc(_("| clear . . . . . . . . . . .   clear the playlist"));
-    msg_rc(_("| status . . . . . . . . . current playlist status"));
-    msg_rc(_("| title [X]  . . . . set/get title in current item"));
-    msg_rc(_("| title_n  . . . . . .  next title in current item"));
-    msg_rc(_("| title_p  . . . .  previous title in current item"));
-    msg_rc(_("| chapter [X]  . . set/get chapter in current item"));
-    msg_rc(_("| chapter_n  . . . .  next chapter in current item"));
-    msg_rc(_("| chapter_p  . .  previous chapter in current item"));
+    msg_rc(_("| add XYZ  . . . . . . . . . . . . add XYZ to playlist"));
+    msg_rc(_("| enqueue XYZ  . . . . . . . . . queue XYZ to playlist"));
+    msg_rc(_("| playlist . . . . .  show items currently in playlist"));
+    msg_rc(_("| play . . . . . . . . . . . . . . . . . . play stream"));
+    msg_rc(_("| stop . . . . . . . . . . . . . . . . . . stop stream"));
+    msg_rc(_("| next . . . . . . . . . . . . . .  next playlist item"));
+    msg_rc(_("| prev . . . . . . . . . . . .  previous playlist item"));
+    msg_rc(_("| goto . . . . . . . . . . . . . .  goto item at index"));
+    msg_rc(_("| repeat [on|off] . . . .  toggle playlist item repeat"));
+    msg_rc(_("| loop [on|off] . . . . . .  toggle playlist item loop"));
+    msg_rc(_("| clear . . . . . . . . . . . . .   clear the playlist"));
+    msg_rc(_("| status . . . . . . . . . . . current playlist status"));
+    msg_rc(_("| title [X]  . . . . . . set/get title in current item"));
+    msg_rc(_("| title_n  . . . . . . . .  next title in current item"));
+    msg_rc(_("| title_p  . . . . . .  previous title in current item"));
+    msg_rc(_("| chapter [X]  . . . . set/get chapter in current item"));
+    msg_rc(_("| chapter_n  . . . . . .  next chapter in current item"));
+    msg_rc(_("| chapter_p  . . . .  previous chapter in current item"));
     msg_rc(  "| ");
-    msg_rc(_("| seek X . seek in seconds, for instance `seek 12'"));
-    msg_rc(_("| pause  . . . . . . . . . . . . . .  toggle pause"));
-    msg_rc(_("| fastforward  . . . . . .  .  set to maximum rate"));
-    msg_rc(_("| rewind  . . . . . . . . . .  set to minimum rate"));
-    msg_rc(_("| faster . . . . . . . .  faster playing of stream"));
-    msg_rc(_("| slower . . . . . . . .  slower playing of stream"));
-    msg_rc(_("| normal . . . . . . . .  normal playing of stream"));
-    msg_rc(_("| f [on|off] . . . . . . . . . . toggle fullscreen"));
-    msg_rc(_("| info . . .  information about the current stream"));
+    msg_rc(_("| seek X . . . seek in seconds, for instance `seek 12'"));
+    msg_rc(_("| pause  . . . . . . . . . . . . . . . .  toggle pause"));
+    msg_rc(_("| fastforward  . . . . . . . .  .  set to maximum rate"));
+    msg_rc(_("| rewind  . . . . . . . . . . . .  set to minimum rate"));
+    msg_rc(_("| faster . . . . . . . . . .  faster playing of stream"));
+    msg_rc(_("| slower . . . . . . . . . .  slower playing of stream"));
+    msg_rc(_("| normal . . . . . . . . . .  normal playing of stream"));
+    msg_rc(_("| f [on|off] . . . . . . . . . . . . toggle fullscreen"));
+    msg_rc(_("| info . . . . .  information about the current stream"));
     msg_rc(_("| get_time . . seconds elapsed since stream's beginning"));
-    msg_rc(_("| is_playing . .  1 if a stream plays, 0 otherwise"));
-    msg_rc(_("| get_title . . .  the title of the current stream"));
-    msg_rc(_("| get_length . .  the length of the current stream"));
+    msg_rc(_("| is_playing . . . .  1 if a stream plays, 0 otherwise"));
+    msg_rc(_("| get_title . . . . .  the title of the current stream"));
+    msg_rc(_("| get_length . . . .  the length of the current stream"));
     msg_rc(  "| ");
-    msg_rc(_("| volume [X] . . . . . . . .  set/get audio volume"));
-    msg_rc(_("| volup [X]  . . . . .  raise audio volume X steps"));
-    msg_rc(_("| voldown [X]  . . . .  lower audio volume X steps"));
-    msg_rc(_("| adev [X] . . . . . . . . .  set/get audio device"));
-    msg_rc(_("| achan [X]. . . . . . . .  set/get audio channels"));
-    msg_rc(_("| atrack [X] . . . . . . . . . set/get audio track"));
-    msg_rc(_("| vtrack [X] . . . . . . . . . set/get video track"));
-    msg_rc(_("| vratio [X]  . . . . . set/get video aspect ratio"));
-    msg_rc(_("| vcrop [X]  . . . . . . . . .  set/get video crop"));
-    msg_rc(_("| vzoom [X]  . . . . . . . . .  set/get video zoom"));
-    msg_rc(_("| strack [X] . . . . . . . set/get subtitles track"));
-    msg_rc(_("| menu [on|off|up|down|left|right|select] use menu"));
+    msg_rc(_("| volume [X] . . . . . . . . . .  set/get audio volume"));
+    msg_rc(_("| volup [X]  . . . . . . .  raise audio volume X steps"));
+    msg_rc(_("| voldown [X]  . . . . . .  lower audio volume X steps"));
+    msg_rc(_("| adev [X] . . . . . . . . . . .  set/get audio device"));
+    msg_rc(_("| achan [X]. . . . . . . . . .  set/get audio channels"));
+    msg_rc(_("| atrack [X] . . . . . . . . . . . set/get audio track"));
+    msg_rc(_("| vtrack [X] . . . . . . . . . . . set/get video track"));
+    msg_rc(_("| vratio [X]  . . . . . . . set/get video aspect ratio"));
+    msg_rc(_("| vcrop [X]  . . . . . . . . . . .  set/get video crop"));
+    msg_rc(_("| vzoom [X]  . . . . . . . . . . .  set/get video zoom"));
+    msg_rc(_("| strack [X] . . . . . . . . . set/get subtitles track"));
+    msg_rc(_("| key [hotkey name] . . . . . .  simulate hotkey press"));
+    msg_rc(_("| menu . . [on|off|up|down|left|right|select] use menu"));
     msg_rc(  "| ");
 
     if (b_longhelp)
     {
-        msg_rc(_("| marq-marquee STRING  . . overlay STRING in video"));
-        msg_rc(_("| marq-x X . . . . . . . . . . . .offset from left"));
-        msg_rc(_("| marq-y Y . . . . . . . . . . . . offset from top"));
-        msg_rc(_("| marq-position #. . .  .relative position control"));
-        msg_rc(_("| marq-color # . . . . . . . . . . font color, RGB"));
-        msg_rc(_("| marq-opacity # . . . . . . . . . . . . . opacity"));
-        msg_rc(_("| marq-timeout T. . . . . . . . . . timeout, in ms"));
-        msg_rc(_("| marq-size # . . . . . . . . font size, in pixels"));
+        msg_rc(_("| @name marq-marquee  STRING  . . overlay STRING in video"));
+        msg_rc(_("| @name marq-x X . . . . . . . . . . . .offset from left"));
+        msg_rc(_("| @name marq-y Y . . . . . . . . . . . . offset from top"));
+        msg_rc(_("| @name marq-position #. . .  .relative position control"));
+        msg_rc(_("| @name marq-color # . . . . . . . . . . font color, RGB"));
+        msg_rc(_("| @name marq-opacity # . . . . . . . . . . . . . opacity"));
+        msg_rc(_("| @name marq-timeout T. . . . . . . . . . timeout, in ms"));
+        msg_rc(_("| @name marq-size # . . . . . . . . font size, in pixels"));
         msg_rc(  "| ");
-        msg_rc(_("| logo-file STRING . . .the overlay file path/name"));
-        msg_rc(_("| logo-x X . . . . . . . . . . . .offset from left"));
-        msg_rc(_("| logo-y Y . . . . . . . . . . . . offset from top"));
-        msg_rc(_("| logo-position #. . . . . . . . relative position"));
-        msg_rc(_("| logo-transparency #. . . . . . . . .transparency"));
+        msg_rc(_("| @name logo-file STRING . . .the overlay file path/name"));
+        msg_rc(_("| @name logo-x X . . . . . . . . . . . .offset from left"));
+        msg_rc(_("| @name logo-y Y . . . . . . . . . . . . offset from top"));
+        msg_rc(_("| @name logo-position #. . . . . . . . relative position"));
+        msg_rc(_("| @name logo-transparency #. . . . . . . . .transparency"));
         msg_rc(  "| ");
-        msg_rc(_("| mosaic-alpha # . . . . . . . . . . . . . . alpha"));
-        msg_rc(_("| mosaic-height #. . . . . . . . . . . . . .height"));
-        msg_rc(_("| mosaic-width # . . . . . . . . . . . . . . width"));
-        msg_rc(_("| mosaic-xoffset # . . . .top left corner position"));
-        msg_rc(_("| mosaic-yoffset # . . . .top left corner position"));
-        msg_rc(_("| mosaic-offsets x,y(,x,y)*. . . . list of offsets"));
-        msg_rc(_("| mosaic-align 0..2,4..6,8..10. . .mosaic alignment"));
-        msg_rc(_("| mosaic-vborder # . . . . . . . . vertical border"));
-        msg_rc(_("| mosaic-hborder # . . . . . . . horizontal border"));
-        msg_rc(_("| mosaic-position {0=auto,1=fixed} . . . .position"));
-        msg_rc(_("| mosaic-rows #. . . . . . . . . . .number of rows"));
-        msg_rc(_("| mosaic-cols #. . . . . . . . . . .number of cols"));
-        msg_rc(_("| mosaic-order id(,id)* . . . . order of pictures "));
-        msg_rc(_("| mosaic-keep-aspect-ratio {0,1} . . .aspect ratio"));
+        msg_rc(_("| @name mosaic-alpha # . . . . . . . . . . . . . . alpha"));
+        msg_rc(_("| @name mosaic-height #. . . . . . . . . . . . . .height"));
+        msg_rc(_("| @name mosaic-width # . . . . . . . . . . . . . . width"));
+        msg_rc(_("| @name mosaic-xoffset # . . . .top left corner position"));
+        msg_rc(_("| @name mosaic-yoffset # . . . .top left corner position"));
+        msg_rc(_("| @name mosaic-offsets x,y(,x,y)*. . . . list of offsets"));
+        msg_rc(_("| @name mosaic-align 0..2,4..6,8..10. . .mosaic alignment"));
+        msg_rc(_("| @name mosaic-vborder # . . . . . . . . vertical border"));
+        msg_rc(_("| @name mosaic-hborder # . . . . . . . horizontal border"));
+        msg_rc(_("| @name mosaic-position {0=auto,1=fixed} . . . .position"));
+        msg_rc(_("| @name mosaic-rows #. . . . . . . . . . .number of rows"));
+        msg_rc(_("| @name mosaic-cols #. . . . . . . . . . .number of cols"));
+        msg_rc(_("| @name mosaic-order id(,id)* . . . . order of pictures "));
+        msg_rc(_("| @name mosaic-keep-aspect-ratio {0,1} . . .aspect ratio"));
         msg_rc(  "| ");
         msg_rc(_("| check-updates [newer] [equal] [older]\n"
                  "|               [undef] [info] [source] [binary] [plugin]"));
         msg_rc(  "| ");
     }
-    msg_rc(_("| help . . . . . . . . . . . . . this help message"));
-    msg_rc(_("| longhelp . . . . . . . . . a longer help message"));
-    msg_rc(_("| logout . . . . .  exit (if in socket connection)"));
-    msg_rc(_("| quit . . . . . . . . . . . . . . . . .  quit vlc"));
+    msg_rc(_("| help . . . . . . . . . . . . . . . this help message"));
+    msg_rc(_("| longhelp . . . . . . . . . . . a longer help message"));
+    msg_rc(_("| logout . . . . . . .  exit (if in socket connection)"));
+    msg_rc(_("| quit . . . . . . . . . . . . . . . . . . .  quit vlc"));
     msg_rc(  "| ");
     msg_rc(_("+----[ end of help ]"));
 }
@@ -1181,7 +1184,7 @@ static int Input( vlc_object_t *p_this, char const *psz_cmd,
              || !strcmp( psz_cmd, "vtrack" )
              || !strcmp( psz_cmd, "strack" ) )
     {
-        char *psz_variable;
+        const char *psz_variable;
         vlc_value_t val_name;
         int i_error;
 
@@ -1361,7 +1364,8 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
         {
             msg_rc( "Trying to add %s to playlist.", newval.psz_string );
             playlist_AddInput( p_playlist, p_item,
-                     PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END, VLC_TRUE );
+                     PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END, VLC_TRUE,
+                     VLC_FALSE );
         }
     }
     else if( !strcmp( psz_cmd, "enqueue" ) &&
@@ -1373,7 +1377,8 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
         {
             msg_rc( "trying to enqueue %s to playlist", newval.psz_string );
             playlist_AddInput( p_playlist, p_item,
-                               PLAYLIST_APPEND, PLAYLIST_END, VLC_TRUE );
+                               PLAYLIST_APPEND, PLAYLIST_END, VLC_TRUE,
+                               VLC_FALSE);
         }
     }
     else if( !strcmp( psz_cmd, "playlist" ) )
@@ -1393,8 +1398,10 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
         if( p_playlist->p_input )
         {
             /* Replay the current state of the system. */
-            msg_rc( STATUS_CHANGE "( new input: %s )",
-                    input_GetItem(p_playlist->p_input)->psz_uri );
+            char *psz_uri =
+                    input_item_GetURI( input_GetItem( p_playlist->p_input ) );
+            msg_rc( STATUS_CHANGE "( new input: %s )", psz_uri );
+            free( psz_uri );
             msg_rc( STATUS_CHANGE "( audio volume: %d )",
                     config_GetInt( p_intf, "volume" ));
 
@@ -1430,84 +1437,6 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
     return VLC_SUCCESS;
 }
 
-static int Other( vlc_object_t *p_this, char const *psz_cmd,
-                     vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    intf_thread_t *p_intf = (intf_thread_t*)p_this;
-    vlc_object_t  *p_playlist;
-    vlc_value_t    val;
-    vlc_object_t  *p_input;
-
-    p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
-    if( !p_playlist )
-    {
-        return VLC_ENOOBJ;
-    }
-
-    p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_ANYWHERE );
-    if( !p_input )
-    {
-        vlc_object_release( p_playlist );
-        return VLC_ENOOBJ;
-    }
-
-    if( p_input )
-    {
-        var_Get( p_input, "state", &val );
-        if( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) )
-        {
-            msg_rc( _("Type 'pause' to continue.") );
-            vlc_object_release( p_playlist );
-            vlc_object_release( p_input );
-            return VLC_EGENERIC;
-        }
-    }
-
-    /* Parse miscellaneous commands */
-    {
-        static const char vars[] =
-            "marq-x\0" "marq-y\0" "marq-position\0" "marq-color\0"
-            "marq-opacity\0" "marq-size\0" "marq-timeout\0"
-            "mosaic-alpha\0" "mosaic-height\0" "mosaic-width\0"
-            "mosaic-xoffset\0" "mosaic-yoffset\0" "mosaic-align\0"
-            "mosaic-vborder\0" "mosaic-hborder\0" "mosaic-position\0"
-            "mosaic-rows\0" "mosaic-cols\0" "mosaic-order\0"
-            "mosaic-offsets\0" "mosaic-keep-aspect-ratio\0"
-            "logo-file\0" "logo-x\0" "logo-y\0" "logo-position\0"
-            "logo-transparency\0";
-        const char *psz_name;
-
-        if( newval.psz_string )
-        for( psz_name = vars; *psz_name; psz_name += strlen( psz_name ) + 1 )
-        {
-            if( strcmp( psz_name, psz_cmd ) == 0 )
-            {
-                int i_type = var_Type( p_input->p_libvlc_global, psz_name );
-
-                if( i_type & VLC_VAR_INTEGER )
-                {
-                    var_SetInteger( p_input->p_libvlc_global, psz_name,
-                                    atoi( newval.psz_string ) );
-                    break;
-                }
-                else if( i_type & VLC_VAR_STRING )
-                {
-                    var_SetInteger( p_input->p_libvlc_global, psz_name,
-                                    newval.psz_string );
-                    break;
-                }
-            }
-        }
-
-        if( *psz_name == '\0' )
-            msg_rc( "Unknown command!" );
-    }
-
-    vlc_object_release( p_playlist );
-    vlc_object_release( p_input );
-    return VLC_SUCCESS;
-}
-
 static int Quit( vlc_object_t *p_this, char const *psz_cmd,
                  vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
@@ -1519,7 +1448,7 @@ static int Quit( vlc_object_t *p_this, char const *psz_cmd,
         playlist_Stop( p_playlist );
         vlc_object_release( p_playlist );
     }
-    p_this->p_libvlc->b_die = VLC_TRUE;
+    vlc_object_kill( p_this->p_libvlc );
     return VLC_SUCCESS;
 }
 
@@ -1531,7 +1460,6 @@ static int Intf( vlc_object_t *p_this, char const *psz_cmd,
     p_newintf = intf_Create( p_this->p_libvlc, newval.psz_string, 0, NULL );
     if( p_newintf )
     {
-        p_newintf->b_block = VLC_FALSE;
         if( intf_RunThread( p_newintf ) )
         {
             vlc_object_detach( p_newintf );
@@ -2014,9 +1942,9 @@ vlc_bool_t ReadCommand( intf_thread_t *p_intf, char *p_buffer, int *pi_size )
 #endif
 
     while( !intf_ShouldDie( p_intf ) && *pi_size < MAX_LINE_LENGTH &&
-           (i_read = net_ReadNonBlock( p_intf, p_intf->p_sys->i_socket == -1 ?
+           (i_read = net_Read( p_intf, p_intf->p_sys->i_socket == -1 ?
                        0 /*STDIN_FILENO*/ : p_intf->p_sys->i_socket, NULL,
-                  (uint8_t *)p_buffer + *pi_size, 1, INTF_IDLE_SLEEP ) ) > 0 )
+                  (uint8_t *)p_buffer + *pi_size, 1, VLC_FALSE ) ) > 0 )
     {
         if( p_buffer[ *pi_size ] == '\r' || p_buffer[ *pi_size ] == '\n' )
             break;
@@ -2025,9 +1953,17 @@ vlc_bool_t ReadCommand( intf_thread_t *p_intf, char *p_buffer, int *pi_size )
     }
 
     /* Connection closed */
-    if( i_read == -1 )
+    if( i_read <= 0 )
     {
-        p_intf->p_sys->i_socket = -1;
+        if( p_intf->p_sys->i_socket != -1 )
+        {
+            net_Close( p_intf->p_sys->i_socket );
+            p_intf->p_sys->i_socket = -1;
+        }
+        else
+            /* Standard input closed: exit */
+            vlc_object_kill( p_intf );
+
         p_buffer[ *pi_size ] = 0;
         return VLC_TRUE;
     }