]> git.sesse.net Git - vlc/blobdiff - modules/control/rc/rc.c
* rc: Fixed a bug with seek command.
[vlc] / modules / control / rc / rc.c
index 8d8f140e6dfdaad9c61a87336cfdd86484c52213..4d2530a000560ed3c51cad013ef06709de8a85c5 100644 (file)
@@ -2,7 +2,7 @@
  * rc.c : remote control stdin/stdout plugin for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: rc.c,v 1.19 2003/01/14 14:51:02 massiot Exp $
+ * $Id: rc.c,v 1.37 2003/07/28 07:16:50 fenrir Exp $
  *
  * Authors: Peter Surda <shurdeek@panorama.sth.ac.at>
  *
 #endif
 #include <sys/types.h>
 
-#if defined( WIN32 )
-#include <winsock2.h>                                            /* select() */
-#endif
-
-#include "error.h"
+#include "vlc_error.h"
 
 #define MAX_LINE_LENGTH 256
 
@@ -78,19 +74,19 @@ static int  AudioConfig  ( vlc_object_t *, char const *,
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
-#define POS_TEXT N_("show stream position")
+#define POS_TEXT N_("Show stream position")
 #define POS_LONGTEXT N_("Show the current position in seconds within the stream from time to time.")
 
-#define TTY_TEXT N_("fake TTY")
+#define TTY_TEXT N_("Fake TTY")
 #define TTY_LONGTEXT N_("Force the rc plugin to use stdin as if it was a TTY.")
 
 vlc_module_begin();
-    add_category_hint( N_("Remote control"), NULL );
-    add_bool( "rc-show-pos", 0, NULL, POS_TEXT, POS_LONGTEXT );
+    add_category_hint( N_("Remote control"), NULL, VLC_TRUE );
+    add_bool( "rc-show-pos", 0, NULL, POS_TEXT, POS_LONGTEXT, VLC_TRUE );
 #ifdef HAVE_ISATTY
-    add_bool( "fake-tty", 0, NULL, TTY_TEXT, TTY_LONGTEXT );
+    add_bool( "fake-tty", 0, NULL, TTY_TEXT, TTY_LONGTEXT, VLC_TRUE );
 #endif
-    set_description( _("remote control interface module") );
+    set_description( _("remote control interface") );
     set_capability( "interface", 20 );
     set_callbacks( Activate, NULL );
 vlc_module_end();
@@ -102,7 +98,7 @@ static int Activate( vlc_object_t *p_this )
 {
     intf_thread_t *p_intf = (intf_thread_t*)p_this;
 
-#ifdef HAVE_ISATTY
+#if defined(HAVE_ISATTY) && !defined(WIN32)
     /* Check that stdin is a TTY */
     if( !config_GetInt( p_intf, "fake-tty" ) && !isatty( 0 ) )
     {
@@ -144,6 +140,12 @@ static void Run( intf_thread_t *p_intf )
 
     double     f_ratio = 1.0;
 
+#ifdef WIN32
+    HANDLE hConsoleIn;
+    INPUT_RECORD input_record;
+    DWORD i_dummy2;
+#endif
+
     p_input = NULL;
     p_playlist = NULL;
 
@@ -194,30 +196,99 @@ static void Run( intf_thread_t *p_intf )
     var_Create( p_intf, "achan", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
     var_AddCallback( p_intf, "achan", AudioConfig, NULL );
 
+#ifdef WIN32
+    /* Get the file descriptor of the console input */
+    hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);
+    if( hConsoleIn == INVALID_HANDLE_VALUE )
+    {
+        msg_Err( p_intf, "Couldn't open STD_INPUT_HANDLE" ); 
+        p_intf->b_die = VLC_TRUE;
+    }
+#endif
+
     while( !p_intf->b_die )
     {
+        vlc_bool_t     b_complete = VLC_FALSE;
+
+#ifndef WIN32
         fd_set         fds;
         struct timeval tv;
-        vlc_bool_t     b_complete = VLC_FALSE;
 
         /* Check stdin */
         tv.tv_sec = 0;
-        tv.tv_usec = 50000;
+        tv.tv_usec = (long)INTF_IDLE_SLEEP;
         FD_ZERO( &fds );
         FD_SET( STDIN_FILENO, &fds );
 
-        i_dummy = select( 32, &fds, NULL, NULL, &tv );
+        i_dummy = select( STDIN_FILENO + 1, &fds, NULL, NULL, &tv );
+#else
+        /* On Win32, select() only works on socket descriptors */
+        i_dummy = ( WaitForSingleObject( hConsoleIn, INTF_IDLE_SLEEP/1000 )
+                    == WAIT_OBJECT_0 );
+#endif
         if( i_dummy > 0 )
         {
             int i_size = 0;
 
             while( !p_intf->b_die
                     && i_size < MAX_LINE_LENGTH
+#ifndef WIN32
                     && read( STDIN_FILENO, p_buffer + i_size, 1 ) > 0
-                    && p_buffer[ i_size ] != '\r'
-                    && p_buffer[ i_size ] != '\n' )
+#else
+                    && ReadConsoleInput( hConsoleIn, &input_record, 1,
+                                         &i_dummy2 )
+#endif
+                   )
             {
+#ifdef WIN32
+                if( input_record.EventType != KEY_EVENT ||
+                    !input_record.Event.KeyEvent.bKeyDown ||
+                    input_record.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT ||
+                    input_record.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL||
+                    input_record.Event.KeyEvent.wVirtualKeyCode == VK_MENU ||
+                    input_record.Event.KeyEvent.wVirtualKeyCode == VK_CAPITAL )
+                {
+                    /* nothing interesting */
+                    continue;
+                }
+
+                p_buffer[ i_size ] =
+                    input_record.Event.KeyEvent.uChar.AsciiChar;
+
+                /* Echo out the command */
+                putc( p_buffer[ i_size ], stdout );
+
+                /* Handle special keys */
+                if( p_buffer[ i_size ] == '\r' || p_buffer[ i_size ] == '\n' )
+                {
+                    putc( '\n', stdout );
+                    break;
+                }
+                switch( p_buffer[ i_size ] )
+                {
+                case '\b':
+                    if( i_size )
+                    {
+                        i_size -= 2;
+                        putc( ' ', stdout );
+                        putc( '\b', stdout );
+                    }
+                    break;
+                case '\r':
+                    i_size --;
+                    break;
+                }
+
+                i_size++;
+#else
+
+                if( p_buffer[ i_size ] == '\r' || p_buffer[ i_size ] == '\n' )
+                {
+                    break;
+                }
+
                 i_size++;
+#endif
             }
 
             if( i_size == MAX_LINE_LENGTH
@@ -456,8 +527,19 @@ static int Input( vlc_object_t *p_this, char const *psz_cmd,
     }
     else if( !strcmp( psz_cmd, "seek" ) )
     {
-        input_Seek( p_input, atoi( newval.psz_string ),
-                    INPUT_SEEK_SECONDS | INPUT_SEEK_SET );
+        if( strlen( newval.psz_string ) > 0 &&
+            newval.psz_string[strlen( newval.psz_string ) - 1] == '%' )
+        {
+            input_Seek( p_input, atoi( newval.psz_string ),
+                        INPUT_SEEK_PERCENT | INPUT_SEEK_SET );
+        }
+        else
+        {
+            input_Seek( p_input, atoi( newval.psz_string ),
+                        INPUT_SEEK_SECONDS | INPUT_SEEK_SET );
+        }
+        vlc_object_release( p_input );
+        return VLC_SUCCESS;
     }
     else if( !strcmp( psz_cmd, "chapter" ) ||
              !strcmp( psz_cmd, "chapter_n" ) ||
@@ -476,8 +558,9 @@ static int Input( vlc_object_t *p_this, char const *psz_cmd,
             {
                 /* Get. */
                 vlc_mutex_lock( &p_input->stream.stream_lock );
-                printf( "Currently playing chapter %d\n",
-                        p_input->stream.p_selected_area->i_part );
+                printf( "Currently playing chapter %d/%d\n",
+                        p_input->stream.p_selected_area->i_part,
+                        p_input->stream.p_selected_area->i_part_nb - 1 );
                 vlc_mutex_unlock( &p_input->stream.stream_lock );
 
                 vlc_object_release( p_input );
@@ -498,15 +581,15 @@ static int Input( vlc_object_t *p_this, char const *psz_cmd,
         }
 
         vlc_mutex_lock( &p_input->stream.stream_lock );
-        if( ( i_chapter > 0 ) && ( i_chapter <=
+        if( ( i_chapter > 0 ) && ( i_chapter <
             p_input->stream.p_selected_area->i_part_nb ) )
         {
-          p_input->stream.p_selected_area->i_part = i_chapter;
-          vlc_mutex_unlock( &p_input->stream.stream_lock );
-          input_ChangeArea( p_input,
-                            (input_area_t*)p_input->stream.p_selected_area );
-          input_SetStatus( p_input, INPUT_STATUS_PLAY );
-          vlc_mutex_lock( &p_input->stream.stream_lock );
+            input_area_t *p_area = p_input->stream.p_selected_area;
+            p_input->stream.p_selected_area->i_part = i_chapter;
+            vlc_mutex_unlock( &p_input->stream.stream_lock );
+            input_ChangeArea( p_input, p_area );
+            input_SetStatus( p_input, INPUT_STATUS_PLAY );
+            vlc_mutex_lock( &p_input->stream.stream_lock );
         }
         vlc_mutex_unlock( &p_input->stream.stream_lock );
 
@@ -530,8 +613,9 @@ static int Input( vlc_object_t *p_this, char const *psz_cmd,
             {
                 /* Get. */
                 vlc_mutex_lock( &p_input->stream.stream_lock );
-                printf( "Currently playing title %d\n",
-                        p_input->stream.p_selected_area->i_id );
+                printf( "Currently playing title %d/%d\n",
+                        p_input->stream.p_selected_area->i_id,
+                        p_input->stream.i_area_nb - 1 );
                 vlc_mutex_unlock( &p_input->stream.stream_lock );
 
                 vlc_object_release( p_input );
@@ -552,13 +636,11 @@ static int Input( vlc_object_t *p_this, char const *psz_cmd,
         }
 
         vlc_mutex_lock( &p_input->stream.stream_lock );
-        if( ( i_title > 0 ) && ( i_title <=
-            p_input->stream.p_selected_area->i_part_nb ) )
+        if( ( i_title > 0 ) && ( i_title < p_input->stream.i_area_nb ) )
         {
-            p_input->stream.p_selected_area->i_part = i_title;
+            input_area_t *p_area = p_input->stream.pp_areas[i_title];
             vlc_mutex_unlock( &p_input->stream.stream_lock );
-            input_ChangeArea( p_input,
-                     (input_area_t*)p_input->stream.pp_areas[i_title] );
+            input_ChangeArea( p_input, p_area );
             input_SetStatus( p_input, INPUT_STATUS_PLAY );
             vlc_mutex_lock( &p_input->stream.stream_lock );
         }
@@ -604,7 +686,7 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
     else if( !strcmp( psz_cmd, "add" ) )
     {
         printf( "trying to add %s to playlist\n", newval.psz_string );
-        playlist_Add( p_playlist, newval.psz_string,
+        playlist_Add( p_playlist, newval.psz_string, NULL, 0,
                       PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END );
     }
     else if( !strcmp( psz_cmd, "playlist" ) )
@@ -618,7 +700,7 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
         }
         if ( i == 0 )
         {
-            printf( "| no etries\n" );
+            printf( "| no entries\n" );
         }
     }
     /*
@@ -644,16 +726,8 @@ 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;
-    char *psz_oldmodule = config_GetPsz( p_this->p_vlc, "intf" );
 
-    config_PutPsz( p_this->p_vlc, "intf", newval.psz_string );
-    p_newintf = intf_Create( p_this->p_vlc );
-    config_PutPsz( p_this->p_vlc, "intf", psz_oldmodule );
-
-    if( psz_oldmodule )
-    {
-        free( psz_oldmodule );
-    }
+    p_newintf = intf_Create( p_this->p_vlc, newval.psz_string );
 
     if( p_newintf )
     {
@@ -671,10 +745,7 @@ static int Intf( vlc_object_t *p_this, char const *psz_cmd,
 static int Volume( vlc_object_t *p_this, char const *psz_cmd,
                    vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
-    aout_instance_t * p_aout;
     int i_error;
-    p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
-    if ( p_aout == NULL ) return VLC_ENOOBJ;
 
     if ( *newval.psz_string )
     {
@@ -686,13 +757,13 @@ static int Volume( vlc_object_t *p_this, char const *psz_cmd,
                     AOUT_VOLUME_MAX );
             i_error = VLC_EBADVAR;
         }
-        else i_error = aout_VolumeSet( p_aout, i_volume );
+        else i_error = aout_VolumeSet( p_this, i_volume );
     }
     else
     {
         /* Get. */
         audio_volume_t i_volume;
-        if ( aout_VolumeGet( p_aout, &i_volume ) < 0 )
+        if ( aout_VolumeGet( p_this, &i_volume ) < 0 )
         {
             i_error = VLC_EGENERIC;
         }
@@ -702,7 +773,6 @@ static int Volume( vlc_object_t *p_this, char const *psz_cmd,
             i_error = VLC_SUCCESS;
         }
     }
-    vlc_object_release( (vlc_object_t *)p_aout );
 
     return i_error;
 }
@@ -710,7 +780,6 @@ static int Volume( vlc_object_t *p_this, char const *psz_cmd,
 static int VolumeMove( vlc_object_t *p_this, char const *psz_cmd,
                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
-    aout_instance_t * p_aout;
     audio_volume_t i_volume;
     int i_nb_steps = atoi(newval.psz_string);
     int i_error = VLC_SUCCESS;
@@ -720,20 +789,16 @@ static int VolumeMove( vlc_object_t *p_this, char const *psz_cmd,
         i_nb_steps = 1;
     }
 
-    p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
-    if ( p_aout == NULL ) return VLC_ENOOBJ;
-
     if ( !strcmp(psz_cmd, "volup") )
     {
-        if ( aout_VolumeUp( p_aout, i_nb_steps, &i_volume ) < 0 )
+        if ( aout_VolumeUp( p_this, i_nb_steps, &i_volume ) < 0 )
             i_error = VLC_EGENERIC;
     }
     else
     {
-        if ( aout_VolumeDown( p_aout, i_nb_steps, &i_volume ) < 0 )
+        if ( aout_VolumeDown( p_this, i_nb_steps, &i_volume ) < 0 )
             i_error = VLC_EGENERIC;
     }
-    vlc_object_release( (vlc_object_t *)p_aout );
 
     if ( !i_error ) printf( "Volume is %d\n", i_volume );
     return i_error;
@@ -744,7 +809,7 @@ static int AudioConfig( vlc_object_t *p_this, char const *psz_cmd,
 {
     aout_instance_t * p_aout;
     const char * psz_variable;
-    const char * psz_name;
+    vlc_value_t val_name;
     int i_error;
 
     p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
@@ -753,55 +818,58 @@ static int AudioConfig( vlc_object_t *p_this, char const *psz_cmd,
     if ( !strcmp( psz_cmd, "adev" ) )
     {
         psz_variable = "audio-device";
-        psz_name = "audio devices";
     }
     else
     {
         psz_variable = "audio-channels";
-        psz_name = "audio channels";
     }
 
+    /* Get the descriptive name of the variable */
+    var_Change( (vlc_object_t *)p_aout, psz_variable, VLC_VAR_GETTEXT,
+                 &val_name, NULL );
+    if( !val_name.psz_string ) val_name.psz_string = strdup(psz_variable);
+
     if ( !*newval.psz_string )
     {
         /* Retrieve all registered ***. */
-        vlc_value_t val;
-        int i;
-        char * psz_value;
+        vlc_value_t val, text;
+        int i, i_value;
 
         if ( var_Get( (vlc_object_t *)p_aout, psz_variable, &val ) < 0 )
         {
             vlc_object_release( (vlc_object_t *)p_aout );
             return VLC_EGENERIC;
         }
-        psz_value = val.psz_string;
+        i_value = val.i_int;
 
         if ( var_Change( (vlc_object_t *)p_aout, psz_variable,
-                         VLC_VAR_GETLIST, &val ) < 0 )
+                         VLC_VAR_GETLIST, &val, &text ) < 0 )
         {
-            free( psz_value );
             vlc_object_release( (vlc_object_t *)p_aout );
             return VLC_EGENERIC;
         }
 
-        printf( "+----[ %s ]\n", psz_name );
+        printf( "+----[ %s ]\n", val_name.psz_string );
         for ( i = 0; i < val.p_list->i_count; i++ )
         {
-            if ( !strcmp( psz_value, val.p_list->p_values[i].psz_string ) )
-                printf( "| %s *\n", val.p_list->p_values[i].psz_string );
+            if ( i_value == val.p_list->p_values[i].i_int )
+                printf( "| %i - %s *\n", val.p_list->p_values[i].i_int,
+                       text.p_list->p_values[i].psz_string );
             else
-                printf( "| %s\n", val.p_list->p_values[i].psz_string );
+                printf( "| %i - %s\n", val.p_list->p_values[i].i_int,
+                       text.p_list->p_values[i].psz_string );
         }
         var_Change( (vlc_object_t *)p_aout, psz_variable, VLC_VAR_FREELIST,
-                    &val );
-        printf( "+----[ end of %s ]\n", psz_name );
+                    &val, &text );
+        printf( "+----[ end of %s ]\n", val_name.psz_string );
 
-        free( psz_value );
+        if( val_name.psz_string ) free( val_name.psz_string );
         i_error = VLC_SUCCESS;
     }
     else
     {
         vlc_value_t val;
-        val.psz_string = newval.psz_string;
+        val.i_int = atoi( newval.psz_string );
 
         i_error = var_Set( (vlc_object_t *)p_aout, psz_variable, val );
     }