]> git.sesse.net Git - vlc/commitdiff
Changement de cha�ne configurable depuis un fichier texte.
authorVincent Seguin <seguin@videolan.org>
Mon, 31 Jan 2000 16:56:37 +0000 (16:56 +0000)
committerVincent Seguin <seguin@videolan.org>
Mon, 31 Jan 2000 16:56:37 +0000 (16:56 +0000)
Quelques corrections esthetiques dans vout.

include/common.h
include/config.h
include/interface.h
src/interface/interface.c
src/interface/intf_cmd.c
src/interface/main.c
src/video_output/video_output.c
vlc.channels [new file with mode: 0644]

index b20e25133490f7fae1715a8321ef7ccb90f525a6..d40741f2952c08eaaca91d00ff5fdca864e0da5b 100644 (file)
@@ -39,11 +39,13 @@ struct intf_thread_s;
 struct intf_sys_s;
 struct intf_console_s;
 struct intf_msg_s;
+struct intf_channel_s;
 
 typedef struct intf_thread_s *          p_intf_thread_t;
 typedef struct intf_sys_s *             p_intf_sys_t;
 typedef struct intf_console_s *         p_intf_console_t;
 typedef struct intf_msg_s *             p_intf_msg_t;
+typedef struct intf_channel_s *         p_intf_channel_t;
 
 /* Input */
 struct input_thread_s;
index 74d1d66094710593e7efaa08d64052954c3e6db6..a6f1004db71c92d24318b53933c6ab5381f6dca1 100644 (file)
 #define INTF_INIT_SCRIPT_VAR           "vlc_init"
 #define INTF_INIT_SCRIPT_DEFAULT        "vlc.init"
 
+/* Environment variable used to store channels file and default value */
+#define INTF_CHANNELS_VAR               "vlc_channels"
+#define INTF_CHANNELS_DEFAULT           "vlc.channels"
+
 /* Base delay in micro second for interface sleeps */
 #define INTF_IDLE_SLEEP                 100000
 
index b15869b48a6bbd7820840aa0957fb657dbf27b9c..3791abb631e45f5b2c13962564fb6c9ae19d03e6 100644 (file)
@@ -34,6 +34,9 @@ typedef struct intf_thread_s
     p_intf_console_t    p_console;                                 /* console */
     p_intf_sys_t        p_sys;                            /* system interface */
 
+    /* Channels array - NULL if not used */
+    p_intf_channel_t    p_channel;                 /* description of channels */    
+
     /* Main threads - NULL if not active */
     p_vout_thread_t     p_vout;
     p_input_thread_t    p_input;        
@@ -46,6 +49,6 @@ intf_thread_t * intf_Create             ( void );
 void            intf_Run                ( intf_thread_t * p_intf );
 void            intf_Destroy            ( intf_thread_t * p_intf );
 
-int             intf_SelectInput        ( intf_thread_t * p_intf, int i_index );
+int             intf_SelectChannel      ( intf_thread_t * p_intf, int i_channel );
 int             intf_ProcessKey         ( intf_thread_t * p_intf, int i_key );
 
index b76caaff370c97e32bbf474c8b4839ea8d761576..c329d99feb036ff2e44b3bfc57d186c575af11fd 100644 (file)
 
 #include "intf_sys.h"
 
+/*******************************************************************************
+ * intf_channel_t: channel description
+ *******************************************************************************
+ * A 'channel' is a descriptor of an input method. It is used to switch easily
+ * from source to source without having to specify the whole input thread 
+ * configuration. The channels array, stored in the interface thread object, is
+ * loaded in intf_Create, and unloaded in intf_Destroy.
+ *******************************************************************************/
+typedef struct intf_channel_s
+{
+    /* Channel description */
+    int         i_channel;              /* channel number, -1 for end of array */
+    char *      psz_description;                /* channel description (owned) */
+    
+    /* Input configuration */
+    int         i_input_method;                     /* input method descriptor */
+    char *      psz_input_source;                     /* source string (owned) */
+    int         i_input_port;                                          /* port */
+    int         i_input_vlan;                                          /* vlan */
+} intf_channel_t;
+
+/*******************************************************************************
+ * Local prototypes
+ *******************************************************************************/
+static int      LoadChannels    ( intf_thread_t *p_intf, char *psz_filename );
+static void     UnloadChannels  ( intf_thread_t *p_intf );
+static int      ParseChannel    ( intf_channel_t *p_channel, char *psz_str );
+
 /*******************************************************************************
  * intf_Create: prepare interface before main loop
  *******************************************************************************
@@ -54,6 +82,11 @@ intf_thread_t* intf_Create( void )
     p_intf->p_vout =    NULL;
     p_intf->p_input =   NULL;   
 
+    /* Load channels - the pointer will be set to NULL on failure. The 
+     * return value is ignored since the program can work without 
+     * channels */
+    LoadChannels( p_intf, main_GetPszVariable( INTF_CHANNELS_VAR, INTF_CHANNELS_DEFAULT ));    
+
     /* Start interfaces */
     p_intf->p_console = intf_ConsoleCreate();
     if( p_intf->p_console == NULL )
@@ -126,39 +159,55 @@ void intf_Destroy( intf_thread_t *p_intf )
     /* Destroy interfaces */
     intf_SysDestroy( p_intf );
     intf_ConsoleDestroy( p_intf->p_console );
+        
+    /* Unload channels */
+    UnloadChannels( p_intf );    
 
     /* Free structure */
     free( p_intf );
 }
 
 /*******************************************************************************
- * intf_SelectInput: change input stream
+ * intf_SelectChannel: change channel
  *******************************************************************************
  * Kill existing input, if any, and try to open a new one, using an input
  * configuration table.
  *******************************************************************************/
-int intf_SelectInput( intf_thread_t * p_intf, int i_index )
+int intf_SelectChannel( intf_thread_t * p_intf, int i_channel )
 {
-    intf_DbgMsg("\n");
-
-    /* If VLANs are not active, return with an error */
-    if( !p_main->b_vlans )
-    {
-        intf_ErrMsg("error: VLANs are not activated\n");
-        return( 1 );        
-    }    
+    intf_channel_t *    p_channel;                                  /* channel */
     
-    /* Kill existing input, if any */
-    if( p_intf->p_input != NULL )
-    {        
-        input_DestroyThread( p_intf->p_input, NULL );
+    /* Look for channel in array */
+    if( p_intf->p_channel != NULL )
+    {
+        for( p_channel = p_intf->p_channel; p_channel->i_channel != -1; p_channel++ )
+        {
+            if( p_channel->i_channel == i_channel )
+            {
+                /*
+                 * Change channel
+                 */
+
+                /* Kill existing input, if any */
+                if( p_intf->p_input != NULL )
+                {        
+                    input_DestroyThread( p_intf->p_input, NULL );
+                }
+                
+                intf_Msg("Channel %d: %s\n", i_channel, p_channel->psz_description );                
+
+                /* Open a new input */
+                p_intf->p_input = input_CreateThread( p_channel->i_input_method, p_channel->psz_input_source,
+                                                      p_channel->i_input_port, p_channel->i_input_vlan, 
+                                                      p_intf->p_vout, p_main->p_aout, NULL );        
+                return( p_intf->p_input == NULL );             
+            }            
+        }        
     }
 
-    /* Open a new input */
-    intf_Msg("Switching to channel %d\n", i_index );    
-    p_intf->p_input = input_CreateThread( INPUT_METHOD_TS_VLAN_BCAST, NULL, 0, i_index, 
-                                          p_intf->p_vout, p_main->p_aout, NULL );        
-    return( p_intf->p_input == NULL );    
+    /* Channel does not exist */
+    intf_Msg("Channel %d does not exist\n", i_channel );
+    return( 1 );    
 }
 
 /*******************************************************************************
@@ -186,10 +235,9 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
     case '7':
     case '8':
     case '9':                    
-        if( intf_SelectInput( p_intf, i_key - '0' ) )
-        {
-            intf_ErrMsg("error: can not open channel %d\n", i_key - '0');            
-        }        
+        /* Change channel - return code is ignored since SelectChannel displays
+         * its own error messages */
+        intf_SelectChannel( p_intf, i_key - '0' );        
         break;
     case '+':                                                      /* volume + */
         // ??
@@ -262,5 +310,235 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
     return( 0 );    
 }
 
+/* following functions are local */
+                    
+/*******************************************************************************
+ * LoadChannels: load channels description from a file
+ *******************************************************************************
+ * This structe describes all interface-specific data of the main (interface)
+ * thread.
+ * Each line of the file is a semicolon separated list of the following 
+ * fields :
+ *      integer         channel number
+ *      string          channel description
+ *      integer         input method (see input.h)
+ *      string          input source
+ *      integer         input port
+ *      integer         input vlan
+ * The last field must end with a semicolon.
+ * Comments and empty lines are not explicitely allowed, but lines with parsing
+ * errors are ignored without warning.
+ *******************************************************************************/
+static int LoadChannels( intf_thread_t *p_intf, char *psz_filename )
+{
+    FILE *              p_file;                                        /* file */
+    intf_channel_t *    p_channel;                          /* current channel */    
+    char                psz_line[INTF_MAX_CMD_SIZE];            /* line buffer */
+    int                 i_index;                     /* channel or field index */        
+
+    /* Set default value */
+    p_intf->p_channel = NULL;    
     
-                
+    /* Open file */
+    p_file = fopen( psz_filename, "r" );
+    if( p_file == NULL )
+    {
+        intf_ErrMsg("error: can't open %s (%s)\n", psz_filename, strerror(errno));
+        return( 1 );        
+    }
+
+    /* First pass: count number of lines */
+    for( i_index = 0; fgets( psz_line, INTF_MAX_CMD_SIZE, p_file ) != NULL; i_index++ )
+    {
+        ;        
+    }
+
+    if( i_index != 0 )
+    {        
+        /* Allocate array and rewind - some of the lines may be invalid, and the
+         * array will probably be larger than the actual number of channels, but
+         * it has no consequence. */
+        p_intf->p_channel = malloc( sizeof( intf_channel_t ) * i_index );
+        if( p_intf->p_channel == NULL )
+        {
+            intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+            fclose( p_file );
+            return( 1 );            
+        }        
+        p_channel = p_intf->p_channel;        
+        rewind( p_file );
+
+        /* Second pass: read channels descriptions */
+        while( fgets( psz_line, INTF_MAX_CMD_SIZE, p_file ) != NULL )
+        {
+            if( !ParseChannel( p_channel, psz_line ) )
+            {
+                intf_DbgMsg("channel [%d] %s : method %d (%s:%d vlan %d)\n",
+                            p_channel->i_channel, p_channel->psz_description,
+                            p_channel->i_input_method, p_channel->psz_input_source,
+                            p_channel->i_input_port, p_channel->i_input_vlan );                
+                p_channel++;                
+            }
+        }
+        
+        /* Add marker at the end of the array */
+        p_channel->i_channel = -1;
+    }
+
+    /* Close file */
+    fclose( p_file );    
+    return( 0 );
+}
+
+/******************************************************************************
+ * UnloadChannels: unload channels description
+ ******************************************************************************
+ * This function free all resources allocated by LoadChannels, if any.
+ ******************************************************************************/
+static void UnloadChannels( intf_thread_t *p_intf )
+{
+    int i_channel;                                           /* channel index */    
+    
+    if( p_intf->p_channel != NULL )
+    {
+        /* Free allocated strings */
+        for( i_channel = 0; 
+             p_intf->p_channel[ i_channel ].i_channel != -1; 
+             i_channel++ )
+        {
+            if( p_intf->p_channel[ i_channel ].psz_description != NULL )
+            {                
+                free( p_intf->p_channel[ i_channel ].psz_description );
+            }
+            if( p_intf->p_channel[ i_channel ].psz_input_source != NULL )
+            {                
+                free( p_intf->p_channel[ i_channel ].psz_input_source );            
+            }            
+        }        
+
+        /* Free array */
+        free( p_intf->p_channel );        
+        p_intf->p_channel = NULL;        
+    }    
+}
+
+
+/*******************************************************************************
+ * ParseChannel: parse a channel description line
+ *******************************************************************************
+ * See LoadChannels. This function return non 0 on parsing error.
+ *******************************************************************************/
+static int ParseChannel( intf_channel_t *p_channel, char *psz_str )
+{
+    char *      psz_index;                                /* current character */
+    char *      psz_end;                             /* end pointer for strtol */    
+    int         i_field;                          /* field number, -1 on error */
+    int         i_field_length;               /* field length, for text fields */
+
+    /* Set some default fields */
+    p_channel->i_channel =              0;
+    p_channel->psz_description =        NULL;
+    p_channel->i_input_method =         0;
+    p_channel->psz_input_source =       NULL;
+    p_channel->i_input_port =           0;
+    p_channel->i_input_vlan =           0;    
+
+    /* Parse string */
+    i_field = 0;
+    for( psz_index = psz_str; (i_field != -1) && (*psz_index != '\0'); psz_index++ )
+    {
+        if( *psz_index == ';' )
+        {
+            /* Mark end of field */
+            *psz_index = '\0';
+
+            /* Parse field */
+            switch( i_field++ )
+            {
+            case 0:                                          /* channel number */
+                p_channel->i_channel = strtol( psz_str, &psz_end, 0);
+                if( (*psz_str == '\0') || (*psz_end != '\0') )
+                {
+                    i_field = -1;
+                }
+                break;                
+            case 1:                                     /* channel description */
+                i_field_length = strlen( psz_str );                
+                if( i_field_length != 0 )
+                {
+                    p_channel->psz_description = malloc( i_field_length + 1 );
+                    if( p_channel->psz_description == NULL )
+                    {
+                        intf_ErrMsg("error: %s\n", strerror( ENOMEM ));                        
+                        i_field = -1;                        
+                    }
+                    else
+                    {                        
+                        strcpy( p_channel->psz_description, psz_str );                        
+                    }                        
+                }
+                break;                
+            case 2:                                            /* input method */
+                p_channel->i_input_method = strtol( psz_str, &psz_end, 0);
+                if( (*psz_str == '\0') || (*psz_end != '\0') )
+                {
+                    i_field = -1;
+                }
+                break;                
+            case 3:                                            /* input source */
+                i_field_length = strlen( psz_str );                
+                if( i_field_length != 0 )
+                {
+                    p_channel->psz_input_source = malloc( i_field_length + 1 );
+                    if( p_channel->psz_input_source == NULL )
+                    {
+                        intf_ErrMsg("error: %s\n", strerror( ENOMEM ));                        
+                        i_field = -1;                        
+                    }
+                    else
+                    {                        
+                        strcpy( p_channel->psz_input_source, psz_str );                        
+                    }                        
+                }
+                break;                
+            case 4:                                              /* input port */
+                p_channel->i_input_port = strtol( psz_str, &psz_end, 0);
+                if( (*psz_str == '\0') || (*psz_end != '\0') )
+                {
+                    i_field = -1;
+                }
+                break;                                
+            case 5:                                              /* input vlan */
+                p_channel->i_channel = strtol( psz_str, &psz_end, 0);
+                if( (*psz_str == '\0') || (*psz_end != '\0') )
+                {
+                    i_field = -1;
+                }
+                break;                
+                /* ... following fields are ignored */
+            }
+
+            /* Set new beginning of field */
+            psz_str = psz_index + 1;
+        }
+    }      
+
+    /* At least the first three fields must be parsed sucessfully for function
+     * success. Other parsing errors are returned using i_field = -1. */    
+    if( i_field < 3 )
+    {
+        /* Function fails. Free allocated strings */
+        if( p_channel->psz_description != NULL )
+        {
+            free( p_channel->psz_description );            
+        }
+        if( p_channel->psz_input_source != NULL )
+        {
+            free( p_channel->psz_input_source );            
+        }                
+        return( 1 );        
+    }
+
+    /* Return success */
+    return( 0 );    
+}
index af02111a27cbb100d766008bd9cfd88fb13f9ebd..186536b72f1f8c6c1054b606f391b70d4e58faaf 100644 (file)
@@ -69,7 +69,7 @@ int intf_ExecCommand( char *psz_cmd )
     int             i_index;                           /* multi-purposes index */
     int             i_return;                          /* command return value */
 
-    intf_DbgMsg("intf debug: command `%s'\n", psz_cmd);
+    intf_DbgMsg("command `%s'\n", psz_cmd);
 
     /* Parse command line (separate arguments). If nothing has been found, 
      * the function returns without error */
@@ -110,7 +110,7 @@ int intf_ExecCommand( char *psz_cmd )
     {
     case INTF_FATAL_ERROR:                                      /* fatal error */
         /* Print message and terminates the interface thread */
-        intf_ErrMsg( "intf fatal: in command `%s'\n", psz_argv[0] );
+        intf_ErrMsg( "fatal error in command `%s'\n", psz_argv[0] );
         p_main->p_intf->b_die = 1;
         break;
 
@@ -118,7 +118,7 @@ int intf_ExecCommand( char *psz_cmd )
         /* Print message, flush messages queue and exit. Note that this
          * error should be very rare since it does not even try to cancel other
          * threads... */
-        intf_ErrMsg("intf critical: in command `%s'. Please report this error !\n", psz_argv[0] );
+        intf_ErrMsg("critical error in command `%s'. Please report this error !\n", psz_argv[0] );
         intf_FlushMsg();
         exit( INTF_CRITICAL_ERROR );
         break;
@@ -153,7 +153,7 @@ int intf_ExecScript( char *psz_filename )
     p_file = fopen( psz_filename, "r" );
     if( p_file == NULL )
     {
-        intf_ErrMsg("intf error: %s: %s\n", psz_filename, strerror(errno));
+        intf_ErrMsg("warning: %s: %s\n", psz_filename, strerror(errno));
         return( -1 );        
     }
     
@@ -180,7 +180,7 @@ int intf_ExecScript( char *psz_filename )
     }
     if( !feof( p_file ) )
     {
-        intf_ErrMsg("intf error: %s: %s\n", psz_filename, strerror(errno));
+        intf_ErrMsg("error: %s: %s\n", psz_filename, strerror(errno));
         return( -1 );        
     }
     
@@ -393,7 +393,7 @@ static int CheckCommandArguments( intf_arg_t argv[INTF_MAX_ARGS], int i_argc,
             return( 1 );
         }
 
-        intf_DbgMsg("intf debug: argument flags=0x%x (index=%d) name=%s str=%s int=%d float=%f\n",
+        intf_DbgMsg("argument flags=0x%x (index=%d) name=%s str=%s int=%d float=%f\n",
                     argv[i_arg].i_flags,
                     argv[i_arg].i_index,
                     (argv[i_arg].i_flags & INTF_NAMED_ARG) ? argv[i_arg].ps_name : "NA",
@@ -462,7 +462,7 @@ static int ConvertArgument( intf_arg_t *p_arg, int i_flags, char *psz_str )
 #ifdef DEBUG
     else                                      /* error: missing type specifier */
     {
-        intf_ErrMsg("intf error: missing type specifier for `%s' (0x%x)\n", psz_str, i_flags);
+        intf_ErrMsg("error: missing type specifier for `%s' (0x%x)\n", psz_str, i_flags);
         return( 1 );
     }
 #endif
@@ -531,7 +531,7 @@ static void ParseFormatString( intf_arg_t format[INTF_MAX_ARGS], char *psz_forma
                     break;
 #ifdef DEBUG
                 default:  /* error which should never happen: incorrect format */
-                    intf_DbgMsg("intf error: incorrect format string `%s'\n", psz_format);
+                    intf_DbgMsg("error: incorrect format string `%s'\n", psz_format);
                     break;
 #endif
                 }
index b13c868a71dcc2ed659ae1dcc6d8beb6dbb5c5a8..07bc65bb3acff338215215e5d792363b6b9787bc 100644 (file)
@@ -399,11 +399,9 @@ static void Usage( void )
 
     /* Options */
     intf_Msg("Options:\n" \
-             "  -h, --help                        \tprint usage\n" \
-             "  -v, --version                     \tprint program version\n" \
-             "  --noaudio                         \tdisable audio\n" \
+             "  -h, --help, -v, --version         \tprint usage or version\n" \
+             "  --noaudio, --novideo              \tdisable audio/video\n" \
              "  --stereo, --mono                  \tstereo/mono audio\n" \
-             "  --novideo                         \tdisable video\n" \
              "  --display <display>               \tdisplay string\n" \
              "  --width <w>, --height <h>         \tdisplay dimensions\n" \
              "  -g, --grayscale, --color          \tgrayscale/color video\n" \
@@ -414,6 +412,7 @@ static void Usage( void )
     /* Interface parameters */
     intf_Msg("Interface parameters:\n" \
             "  " INTF_INIT_SCRIPT_VAR "=<filename>             \tinitialization script\n" \
+             "  " INTF_CHANNELS_VAR "=<filename>            \tchannels list\n" \
             );
 
     /* Audio parameters */
@@ -440,17 +439,6 @@ static void Usage( void )
              "  " INPUT_VLAN_SERVER_VAR "=<hostname>     \tvlan server\n" \
              "  " INPUT_VLAN_PORT_VAR "=<port>           \tvlan server port\n" \
             );
-
-    /* Interfaces keys */
-    intf_Msg("Interface keys: most interfaces accept the following commands:\n" \
-             "  [space]                           \ttoggle interface\n"
-             "  [esc], q                          \tquit\n" \
-             "  0 - 9                             \tselect channel\n" \
-             "  +, -, m                           \tchange volume, mute\n" \
-             "  g, G, c                           \tchange gamma, toggle grayscale\n" \
-             "  i                                 \ttoggle info printing\n" \
-             "  s                                 \ttoggle picture scaling\n" \
-             );    
 }
 
 /*******************************************************************************
index 369e8fdfafe30ab4ba5bf08369a702b481080d89..9f571dc0382a3b2786ba9422fb1f5049339bf6cb 100644 (file)
@@ -808,7 +808,6 @@ static void RunThread( vout_thread_t *p_vout)
         }
         else if( p_vout->b_active )          /* idle or interface screen alone */
         {
-            //?? clear: SetBufferPicture( p_vout, NULL );
             if( p_vout->b_interface && 0 /* && ?? intf_change */ )
             {
                 /* Interface has changed, so a new rendering is required - force
@@ -1403,6 +1402,8 @@ static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic )
  * nothing has been rendered, or 1 if something has been changed on the screen.
  * Note that if you absolutely want something to be printed, you will have
  * to force it by setting the last idle date to 0.
+ * Unlike other rendering functions, this one calls the SetBufferPicture 
+ * function when needed.
  ******************************************************************************/
 static int RenderIdle( vout_thread_t *p_vout )
 {
@@ -1416,10 +1417,11 @@ static int RenderIdle( vout_thread_t *p_vout )
     if( (current_date - p_vout->last_display_date) > VOUT_IDLE_DELAY &&
         (current_date - p_vout->last_idle_date) > VOUT_IDLE_DELAY )
     {
+        SetBufferPicture( p_vout, NULL );            
         vout_TextSize( p_vout->p_large_font, WIDE_TEXT | OUTLINED_TEXT, psz_text,
                        &i_width, &i_height );
         if( !Align( p_vout, &i_x, &i_y, i_width, i_height, CENTER_RALIGN, CENTER_RALIGN ) )
-        {       
+        {  
             vout_Print( p_vout->p_large_font, 
                         p_vout->p_buffer[ p_vout->i_buffer_index ].p_data +
                         i_x * p_vout->i_bytes_per_pixel + i_y * p_vout->i_bytes_per_line,
diff --git a/vlc.channels b/vlc.channels
new file mode 100644 (file)
index 0000000..776f3b4
--- /dev/null
@@ -0,0 +1,3 @@
+0;Ptyx (caribou);20;caribou.via.ecp.fr;
+1;Sam (bofh);20;bofh.via.ecp.fr;
+2;Polux (dressler);20;dressler.via.ecp.fr;