]> git.sesse.net Git - vlc/blobdiff - modules/control/rc.c
FSF address change.
[vlc] / modules / control / rc.c
index 75f953b6f3392f90958292e3687d919ff7598fce..0e55f9fb1710e378e513e55891318ab372509b07 100644 (file)
@@ -19,7 +19,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 /*****************************************************************************
@@ -37,6 +37,7 @@
 #include <vlc/intf.h>
 #include <vlc/aout.h>
 #include <vlc/vout.h>
+#include <vlc_video.h>
 #include <vlc_osd.h>
 
 #ifdef HAVE_UNISTD_H
@@ -70,6 +71,7 @@ static void Deactivate   ( vlc_object_t * );
 static void Run          ( intf_thread_t * );
 
 static void Help         ( intf_thread_t *, vlc_bool_t );
+static void RegisterCallbacks( intf_thread_t * );
 
 static vlc_bool_t ReadCommand( intf_thread_t *, char *, int * );
 
@@ -113,7 +115,7 @@ struct intf_sys_t
     /* status changes */
     vlc_mutex_t       status_lock;
     playlist_status_t i_last_state;
-    
+
 #ifdef WIN32
     HANDLE hConsoleIn;
     vlc_bool_t b_quiet;
@@ -129,17 +131,16 @@ void __msg_rc( intf_thread_t *p_intf, const char *psz_fmt, ... )
 {
     va_list args;
     va_start( args, psz_fmt );
-    
+
     if( p_intf->p_sys->i_socket == -1 )
     {
         vprintf( psz_fmt, args );
-        printf( "\n" );
+        printf( "\r\n" );
     }
     else
     {
         net_vaPrintf( p_intf, p_intf->p_sys->i_socket, NULL, psz_fmt, args );
-        net_Write( p_intf, p_intf->p_sys->i_socket, NULL, (uint8_t *)"\r\n",
-                   2 );
+        net_Write( p_intf, p_intf->p_sys->i_socket, NULL, (uint8_t*)"\r\n", 2 );
     }
     va_end( args );
 }
@@ -304,7 +305,7 @@ static int Activate( vlc_object_t *p_this )
     p_intf->p_sys->psz_unix_path = psz_unix_path;
     vlc_mutex_init( p_intf, &p_intf->p_sys->status_lock );
     p_intf->p_sys->i_last_state = PLAYLIST_STOPPED;
-    
+
     /* Non-buffered stdout */
     setvbuf( stdout, (char *)NULL, _IOLBF, 0 );
 
@@ -354,28 +355,10 @@ static void Deactivate( vlc_object_t *p_this )
 }
 
 /*****************************************************************************
- * Run: rc thread
- *****************************************************************************
- * This part of the interface is in a separate thread so that we can call
- * exec() from within it without annoying the rest of the program.
+ * RegisterCallbacks: Register callbacks to dynamic variables
  *****************************************************************************/
-static void Run( intf_thread_t *p_intf )
+static void RegisterCallbacks( intf_thread_t *p_intf )
 {
-    input_thread_t * p_input;
-    playlist_t *     p_playlist;
-
-    char       p_buffer[ MAX_LINE_LENGTH + 1 ];
-    vlc_bool_t b_showpos = config_GetInt( p_intf, "rc-show-pos" );
-    vlc_bool_t b_longhelp = VLC_FALSE;
-
-    int        i_size = 0;
-    int        i_oldpos = 0;
-    int        i_newpos;
-
-    p_buffer[0] = 0;
-    p_input = NULL;
-    p_playlist = NULL;
     /* Register commands that will be cleaned up upon object destruction */
     var_Create( p_intf, "quit", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
     var_AddCallback( p_intf, "quit", Quit, NULL );
@@ -390,13 +373,17 @@ static void Run( intf_thread_t *p_intf )
     var_AddCallback( p_intf, "play", Playlist, NULL );
     var_Create( p_intf, "stop", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
     var_AddCallback( p_intf, "stop", Playlist, NULL );
+    var_Create( p_intf, "clear", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "clear", Playlist, NULL );
     var_Create( p_intf, "prev", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
     var_AddCallback( p_intf, "prev", Playlist, NULL );
     var_Create( p_intf, "next", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
     var_AddCallback( p_intf, "next", Playlist, NULL );
     var_Create( p_intf, "goto", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
     var_AddCallback( p_intf, "goto", Playlist, NULL );
+    var_Create( p_intf, "status", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "status", Playlist, NULL );
+
     /* marquee on the fly items */
     var_Create( p_intf, "marq-marquee", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
     var_AddCallback( p_intf, "marq-marquee", Other, NULL );
@@ -457,7 +444,7 @@ static void Run( intf_thread_t *p_intf )
     var_AddCallback( p_intf, "time-opacity", Other, NULL );
     var_Create( p_intf, "time-size", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
     var_AddCallback( p_intf, "time-size", Other, NULL );
-    
+
     /* logo on the fly items */
     var_Create( p_intf, "logo-file", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
     var_AddCallback( p_intf, "logo-file", Other, NULL );
@@ -514,11 +501,38 @@ static void Run( intf_thread_t *p_intf )
     var_AddCallback( p_intf, "adev", AudioConfig, NULL );
     var_Create( p_intf, "achan", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
     var_AddCallback( p_intf, "achan", AudioConfig, NULL );
+}
+
+/*****************************************************************************
+ * Run: rc thread
+ *****************************************************************************
+ * This part of the interface is in a separate thread so that we can call
+ * exec() from within it without annoying the rest of the program.
+ *****************************************************************************/
+static void Run( intf_thread_t *p_intf )
+{
+    input_thread_t * p_input;
+    playlist_t *     p_playlist;
+
+    char       p_buffer[ MAX_LINE_LENGTH + 1 ];
+    vlc_bool_t b_showpos = config_GetInt( p_intf, "rc-show-pos" );
+    vlc_bool_t b_longhelp = VLC_FALSE;
+
+    int        i_size = 0;
+    int        i_oldpos = 0;
+    int        i_newpos;
+
+    p_buffer[0] = 0;
+    p_input = NULL;
+    p_playlist = NULL;
+
+    /* Register commands that will be cleaned up upon object destruction */
+    RegisterCallbacks( p_intf );
 
     /* status callbacks */
     /* Listen to audio volume updates */
-    var_AddCallback( p_intf->p_vlc, "volume", VolumeChanged, p_intf );
-    
+    var_AddCallback( p_intf->p_vlc, "volume-change", VolumeChanged, p_intf );
+
 #ifdef WIN32
     /* Get the file descriptor of the console input */
     p_intf->p_sys->hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);
@@ -594,7 +608,7 @@ static void Run( intf_thread_t *p_intf )
                 vlc_mutex_unlock( &p_playlist->object_lock );
             }
         }
-        
+
         if( (p_input != NULL) && !p_input->b_dead && !p_input->b_die &&
             (p_playlist != NULL) )
         {
@@ -731,32 +745,6 @@ static void Run( intf_thread_t *p_intf )
             else
             {
                 msg_rc( "1" );
-
-                /* FIXME: This is a hack */
-                /* Replay the current state of the system. */
-                msg_rc( STATUS_CHANGE "( New input: %s )", p_input->input.p_item->psz_uri );
-                msg_rc( STATUS_CHANGE "( audio volume: %d )", config_GetInt( p_intf, "volume" ));
-
-                if( p_playlist )
-                {
-                    vlc_mutex_lock( &p_playlist->object_lock );
-                    switch( p_playlist->status.i_status )
-                    {
-                        case PLAYLIST_STOPPED:
-                            msg_rc( STATUS_CHANGE "( stop state: 0 )" );
-                            break;
-                        case PLAYLIST_RUNNING:
-                            msg_rc( STATUS_CHANGE "( play state: %d )", var_GetInteger( p_input, "state" ) );
-                            break;
-                        case PLAYLIST_PAUSED:
-                            msg_rc( STATUS_CHANGE "( pause state: 2 )" );
-                            break;
-                        default:
-                            msg_rc( STATUS_CHANGE "( state unknown )" );
-                            break;
-                    }
-                    vlc_mutex_unlock( &p_playlist->object_lock );
-                } /* End of current playlist status */
             }
         }
         else if( !strcmp( psz_cmd, "get_time" ) )
@@ -817,7 +805,23 @@ static void Run( intf_thread_t *p_intf )
 
                 if( p_vout )
                 {
-                    p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
+                    vlc_value_t val;
+                    vlc_bool_t b_update = VLC_FALSE;
+                    var_Get( p_vout, "fullscreen", &val );
+                    val.b_bool = !val.b_bool;
+                    if( !strncmp(psz_arg, "on", 2) && (val.b_bool == VLC_TRUE) )
+                    {
+                        b_update = VLC_TRUE;
+                        val.b_bool = VLC_TRUE;
+                    }
+                    else if( !strncmp(psz_arg, "off", 3)  && (val.b_bool == VLC_FALSE) )
+                    {
+                        b_update = VLC_TRUE;
+                        val.b_bool = VLC_FALSE;
+                    }
+                    else if( strncmp(psz_arg, "off", 3) && strncmp(psz_arg, "on", 2) )
+                        b_update = VLC_TRUE;
+                    if( b_update ) var_Set( p_vout, "fullscreen", val );
                     vlc_object_release( p_vout );
                 }
             }
@@ -861,11 +865,11 @@ static void Run( intf_thread_t *p_intf )
         p_playlist = NULL;
     }
 
-    var_DelCallback( p_intf->p_vlc, "volume", VolumeChanged, p_intf );
+    var_DelCallback( p_intf->p_vlc, "volume-change", VolumeChanged, p_intf );
 }
 
 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"));
@@ -875,6 +879,8 @@ static void Help( intf_thread_t *p_intf, vlc_bool_t b_longhelp)
     msg_rc(_("| next . . . . . . . . . . . .  next playlist item"));
     msg_rc(_("| prev . . . . . . . . . .  previous playlist item"));
     msg_rc(_("| goto . . . . . . . . . . . .  goto item at index"));
+    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"));
@@ -889,7 +895,7 @@ static void Help( intf_thread_t *p_intf, vlc_bool_t b_longhelp)
     msg_rc(_("| faster . . . . . . . .  faster playing of stream"));
     msg_rc(_("| slower . . . . . . . .  slower playing of stream"));
     msg_rc(_("| normal . . . . . . . .  normal playing of stream"));
-    msg_rc(_("| f  . . . . . . . . . . . . . . toggle fullscreen"));
+    msg_rc(_("| f [on|off] . . . . . . . . . . toggle fullscreen"));
     msg_rc(_("| info . . .  information about the current stream"));
     msg_rc(  "| ");
     msg_rc(_("| volume [X] . . . . . . . .  set/get audio volume"));
@@ -899,7 +905,7 @@ static void Help( intf_thread_t *p_intf, vlc_bool_t b_longhelp)
     msg_rc(_("| achan [X]. . . . . . . .  set/get audio channels"));
     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"));
@@ -955,7 +961,7 @@ static int TimeOffsetChanged( vlc_object_t *p_this, char const *psz_cmd,
 {
     intf_thread_t *p_intf = (intf_thread_t*)p_data;
     input_thread_t *p_input = NULL;
-    
+
     vlc_mutex_lock( &p_intf->p_sys->status_lock );
     p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
     if( p_input )
@@ -973,7 +979,7 @@ static int VolumeChanged( vlc_object_t *p_this, char const *psz_cmd,
     intf_thread_t *p_intf = (intf_thread_t*)p_data;
 
     vlc_mutex_lock( &p_intf->p_sys->status_lock );
-    msg_rc( STATUS_CHANGE "( audio volume: %d )", newval.i_int );
+    msg_rc( STATUS_CHANGE "( audio volume: %d )", config_GetInt( p_this, "volume") );
     vlc_mutex_unlock( &p_intf->p_sys->status_lock );
     return VLC_SUCCESS;
 }
@@ -1022,7 +1028,7 @@ static int RateChanged( vlc_object_t *p_this, char const *psz_cmd,
 {
     intf_thread_t *p_intf = (intf_thread_t*)p_data;
     input_thread_t *p_input = NULL;
-    
+
     vlc_mutex_lock( &p_intf->p_sys->status_lock );
     p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
     if( p_input )
@@ -1051,17 +1057,16 @@ static int Input( vlc_object_t *p_this, char const *psz_cmd,
     if( ( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) ) &&
         ( strcmp( psz_cmd, "pause" ) != 0 ) )
     {
-        msg_rc( _("press pause to continue") );
+        msg_rc( _("press menu select or pause to continue") );
         vlc_object_release( p_input );
         return VLC_EGENERIC;
     }
-    
+
     /* Parse commands that only require an input */
     if( !strcmp( psz_cmd, "pause" ) )
     {
-        val.i_int = PAUSE_S;
-
-        var_Set( p_input, "state", val );
+        val.i_int = config_GetInt( p_intf, "key-play-pause" );
+        var_Set( p_intf->p_vlc, "key-pressed", val );
         vlc_object_release( p_input );
         return VLC_SUCCESS;
     }
@@ -1083,24 +1088,21 @@ static int Input( vlc_object_t *p_this, char const *psz_cmd,
     }
     else if ( !strcmp( psz_cmd, "fastforward" ) )
     {
-        val.i_int = config_GetInt( p_intf, "key-jump+3sec" );
+        val.i_int = config_GetInt( p_intf, "key-jump+extrashort" );
         var_Set( p_intf->p_vlc, "key-pressed", val );
-        
         vlc_object_release( p_input );
         return VLC_SUCCESS;
     }
     else if ( !strcmp( psz_cmd, "rewind" ) )
     {
-        val.i_int = config_GetInt( p_intf, "key-jump-3sec" );
+        val.i_int = config_GetInt( p_intf, "key-jump-extrashort" );
         var_Set( p_intf->p_vlc, "key-pressed", val );
-
         vlc_object_release( p_input );
         return VLC_SUCCESS;
     }
     else if ( !strcmp( psz_cmd, "faster" ) )
     {
         val.b_bool = VLC_TRUE;
-
         var_Set( p_input, "rate-faster", val );
         vlc_object_release( p_input );
         return VLC_SUCCESS;
@@ -1108,7 +1110,6 @@ static int Input( vlc_object_t *p_this, char const *psz_cmd,
     else if ( !strcmp( psz_cmd, "slower" ) )
     {
         val.b_bool = VLC_TRUE;
-
         var_Set( p_input, "rate-slower", val );
         vlc_object_release( p_input );
         return VLC_SUCCESS;
@@ -1116,7 +1117,6 @@ static int Input( vlc_object_t *p_this, char const *psz_cmd,
     else if ( !strcmp( psz_cmd, "normal" ) )
     {
         val.i_int = INPUT_RATE_DEFAULT;
-
         var_Set( p_input, "rate", val );
         vlc_object_release( p_input );
         return VLC_SUCCESS;
@@ -1157,7 +1157,6 @@ static int Input( vlc_object_t *p_this, char const *psz_cmd,
             val.b_bool = VLC_TRUE;
             var_Set( p_input, "prev-chapter", val );
         }
-
         vlc_object_release( p_input );
         return VLC_SUCCESS;
     }
@@ -1203,6 +1202,7 @@ static int Input( vlc_object_t *p_this, char const *psz_cmd,
     }
 
     /* Never reached. */
+    vlc_object_release( p_input );
     return VLC_EGENERIC;
 }
 
@@ -1224,15 +1224,13 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
     {
         vlc_value_t val;
         var_Get( p_playlist->p_input, "state", &val );
-        if( ( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) ) &&
-            ( strcmp( psz_cmd, "pause" ) != 0 ) )
-        {
-            msg_rc( _("press pause to continue") );
+        if( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) )        {
+            msg_rc( _("press menu select or pause to continue") );
             vlc_object_release( p_playlist );
             return VLC_EGENERIC;
         }
-    }    
-    
+    }
+
     /* Parse commands that require a playlist */
     if( !strcmp( psz_cmd, "prev" ) )
     {
@@ -1272,6 +1270,13 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
     {
         playlist_Stop( p_playlist );
     }
+    else if( !strcmp( psz_cmd, "clear" ) )
+    {
+        playlist_Stop( p_playlist );
+        vlc_mutex_lock( &p_playlist->object_lock );
+        playlist_Clear( p_playlist );
+        vlc_mutex_unlock( &p_playlist->object_lock );
+    }
     else if( !strcmp( psz_cmd, "add" ) &&
              newval.psz_string && *newval.psz_string )
     {
@@ -1287,6 +1292,7 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
     else if( !strcmp( psz_cmd, "playlist" ) )
     {
         int i;
+
         for ( i = 0; i < p_playlist->i_size; i++ )
         {
             msg_rc( "|%s%s   %s|%s|", i == p_playlist->i_index ? "*" : " ",
@@ -1300,7 +1306,34 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
             msg_rc( "| no entries" );
         }
     }
+    else if( !strcmp( psz_cmd, "status" ) )
+    {
+        if( p_playlist->p_input )
+        {
+            /* Replay the current state of the system. */
+            msg_rc( STATUS_CHANGE "( New input: %s )", p_playlist->p_input->input.p_item->psz_uri );
+            msg_rc( STATUS_CHANGE "( audio volume: %d )", config_GetInt( p_intf, "volume" ));
+
+            vlc_mutex_lock( &p_playlist->object_lock );
+            switch( p_playlist->status.i_status )
+            {
+                case PLAYLIST_STOPPED:
+                    msg_rc( STATUS_CHANGE "( stop state: 0 )" );
+                    break;
+                case PLAYLIST_RUNNING:
+                    msg_rc( STATUS_CHANGE "( play state: 1 )" );
+                    break;
+                case PLAYLIST_PAUSED:
+                    msg_rc( STATUS_CHANGE "( pause state: 2 )" );
+                    break;
+                default:
+                    msg_rc( STATUS_CHANGE "( state unknown )" );
+                    break;
+            }
+            vlc_mutex_unlock( &p_playlist->object_lock );
+        }
+    }
+
     /*
      * sanity check
      */
@@ -1326,7 +1359,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd,
     {
         return VLC_ENOOBJ;
     }
-    
+
     p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_ANYWHERE );
     if( !p_input )
     {
@@ -1337,8 +1370,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd,
     if( p_input )
     {
         var_Get( p_input, "state", &val );
-        if( ( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) ) &&
-            ( strcmp( psz_cmd, "pause" ) != 0 ) )
+        if( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) )
         {
             msg_rc( _("press pause to continue") );
             vlc_object_release( p_playlist );
@@ -1346,7 +1378,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd,
             return VLC_EGENERIC;
         }
     }
-    
+
     /* Parse miscellaneous commands */
     if( !strcmp( psz_cmd, "marq-marquee" ) )
     {
@@ -1632,7 +1664,7 @@ static int Quit( vlc_object_t *p_this, char const *psz_cmd,
                  vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
     playlist_t *p_playlist;
-    
+
     p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
     if( p_playlist )
     {
@@ -1646,10 +1678,9 @@ static int Quit( vlc_object_t *p_this, char const *psz_cmd,
 static int Intf( vlc_object_t *p_this, char const *psz_cmd,
                  vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
-    intf_thread_t *p_newintf;
+    intf_thread_t *p_newintf = NULL;
 
     p_newintf = intf_Create( p_this->p_vlc, newval.psz_string );
-
     if( p_newintf )
     {
         p_newintf->b_block = VLC_FALSE;
@@ -1667,7 +1698,26 @@ static int Volume( 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;
-    int i_error;
+    input_thread_t *p_input = NULL;
+    int i_error = VLC_EGENERIC;
+
+    p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_ANYWHERE );
+    if( !p_input )
+        return VLC_ENOOBJ;
+
+    if( p_input )
+    {
+        vlc_value_t val;
+
+        var_Get( p_input, "state", &val );
+        if( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) )
+        {
+            msg_rc( _("press menu select or pause to continue") );
+            vlc_object_release( p_input );
+            return VLC_EGENERIC;
+        }
+        vlc_object_release( p_input );
+    }
 
     if ( *newval.psz_string )
     {
@@ -1687,10 +1737,10 @@ static int Volume( vlc_object_t *p_this, char const *psz_cmd,
 
                 keyval.i_int = config_GetInt( p_intf, "key-vol-mute" );
                 var_Set( p_intf->p_vlc, "key-pressed", keyval );
-            }        
+            }
             i_error = aout_VolumeSet( p_this, i_volume );
             osd_Volume( p_this );
-            msg_rc( STATUS_CHANGE "( audio volume: %d )", i_volume );            
+            msg_rc( STATUS_CHANGE "( audio volume: %d )", i_volume );
         }
     }
     else
@@ -1716,10 +1766,29 @@ static int VolumeMove( vlc_object_t *p_this, char const *psz_cmd,
 {
     intf_thread_t *p_intf = (intf_thread_t*)p_this;
     audio_volume_t i_volume;
+    input_thread_t *p_input = NULL;
     int i_nb_steps = atoi(newval.psz_string);
     int i_error = VLC_SUCCESS;
     int i_volume_step = 0;
 
+    p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_ANYWHERE );
+    if( !p_input )
+        return VLC_ENOOBJ;
+
+    if( p_input )
+    {
+        vlc_value_t val;
+
+        var_Get( p_input, "state", &val );
+        if( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) )
+        {
+            msg_rc( _("press menu select or pause to continue") );
+            vlc_object_release( p_input );
+            return VLC_EGENERIC;
+        }
+        vlc_object_release( p_input );
+    }
+
     i_volume_step = config_GetInt( p_intf->p_vlc, "volume-step" );
     if ( i_nb_steps <= 0 || i_nb_steps > (AOUT_VOLUME_MAX/i_volume_step) )
     {
@@ -1746,11 +1815,29 @@ static int AudioConfig( 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;
+    input_thread_t *p_input = NULL;
     aout_instance_t * p_aout;
     const char * psz_variable;
     vlc_value_t val_name;
     int i_error;
 
+    p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_ANYWHERE );
+    if( !p_input )
+        return VLC_ENOOBJ;
+
+    if( p_input )
+    {
+        vlc_value_t val;
+
+        var_Get( p_input, "state", &val );
+        if( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) )        {
+            msg_rc( _("press menu select or pause to continue") );
+            vlc_object_release( p_input );
+            return VLC_EGENERIC;
+        }
+        vlc_object_release( p_input );
+    }
+
     p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
     if ( p_aout == NULL ) return VLC_ENOOBJ;
 
@@ -1832,7 +1919,7 @@ static int Menu( vlc_object_t *p_this, char const *psz_cmd,
         msg_rc( "[on|off|up|down|left|right|select]" );
         return i_error;
     }
-    
+
     p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
     if( !p_playlist )
         return VLC_ENOOBJ;
@@ -1843,13 +1930,13 @@ static int Menu( vlc_object_t *p_this, char const *psz_cmd,
         if( ( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) ) &&
             ( strcmp( newval.psz_string, "select" ) != 0 ) )
         {
-            msg_rc( _("press menu select to continue") );
+            msg_rc( _("press menu select or pause to continue") );
             vlc_object_release( p_playlist );
             return VLC_EGENERIC;
         }
-        vlc_object_release( p_playlist );
     }
-    
+    vlc_object_release( p_playlist );
+
     val.psz_string = strdup( newval.psz_string );
     if( !strcmp( val.psz_string, "on" ) || !strcmp( val.psz_string, "show" ))
         osd_MenuShow( p_this );