Commit cd74cb2c authored by Christophe Massiot's avatar Christophe Massiot

Removed unused files.

parent 5d45070c
......@@ -36,11 +36,8 @@ PLUGINS_TARGETS := alsa/alsa beos/beos darwin/darwin dsp/dsp dummy/dummy \
INTERFACE = src/interface/main.o \
src/interface/interface.o \
src/interface/intf_msg.o \
src/interface/intf_cmd.o \
src/interface/intf_ctrl.o \
src/interface/intf_playlist.o \
src/interface/intf_channels.o \
src/interface/intf_console.o \
src/interface/intf_urldecode.o \
INPUT = src/input/input_ext-dec.o \
......@@ -102,7 +99,6 @@ VIDEO_DECODER = src/video_decoder/video_decoder.o
MISC = src/misc/mtime.o \
src/misc/tests.o \
src/misc/rsc_files.o \
src/misc/modules.o \
src/misc/netutils.o
......
-------------------------------------------------------------------------------
* marque les points prioritaires
+ les points à ne pas oublier avant la fin de l'année
- les trucs qu'il faudra faire, mais qui ne sont pas urgents
? les idées à discuter
-------------------------------------------------------------------------------
Input
=====
? utilisation de la NAT pour convoyer des infos sur les vlans
* gestion du décodeur générique/par défaut
- passage en b_run
+ trouver des flux de test bien tordus pour tester l'update des
PSI, les discontinuites, la gestion des PCR, etc...
Input: vlan method
==================
+ faire une libvlan rapide (benny est dessus)
- reconcevoir l'API et les dialogues du vlan serveur, faire une
libvlan avancée, l'encapsuler proprement dans input_vlan, refaire
le vlan server
Main
====
- lire un fichier de config en plus de la ligne de commande
Audio output
============
- détection automatique du materiel ;
- 8/16 Bits, Signed/Unsigned, Mono/Stereo (sauf 16 Bits Signed Stereo) ;
Audio decoder
=============
+ implémenter une synkronisation absolue et non relative ;
- MPEG2 Layer I, II, III (sauf Layer II Stereo) ;
AC3 decoder
===========
* éviter le SIGSEGV lorsque le décodeur mange du garbage en entrée ;
+ implémenter une synkronisation absolue et non relative ;
Video output
============
+ nettoyer la boucle principale
+ tenir compte du fait que lorsque b_die est mis, normalement tous
les flux et images doivent déjà être detruits -> afficher une
erreur plutôt que de les supprimer
+ gestion de b_active
+ arbre de décisions avec goto pour les passes
* convertion et affichage des images
* gestion des couleurs X11
? interpolation pour des display ratios < 1
? utiliser XDGA pour accelerer
Video graphics
==============
+ tout reste à implementer
+ rajouter les convertions rgb->pixel
Video decoder
=============
* tout tout tout
+ sur p_vout->b_active == 0, trasher tout sauf I
* parser/trasher de PES
Generic decoder
===============
* identification des paquets
* sauvegarde d'un flux multiplexé
* sauvegarde de flux demultiplexés
Interface
=========
- incrustation d'infos sur les buffers
+ réagir aux signaux
Interface: commandes
====================
- Plein de commandes à implémenter
Interface: console
==================
- Utiliser un widget quelconque (portable de préférence) et renommer
en intf_console si la portabilité est atteinte (sinon, x11console).
- Utilisation des pixmaps pour egayer un peu en début de ligne
- Gestion des fontes et couleurs
- Choix d'une couleur de bg en l'absende de pixmap
- Ascenceur pour la zone de texte
- Unicité des enregistrements de l'history - sauvegarde de l'history
- Gestion de la souris (copier/coller)
General: sources
================
+ déclarer en extern inline les fonctions de mtime et netlist...
- Eliminer les headers superflus des sources, bien indiquer les dépendances
- conserver la cohérence des sources: input_psi plutot que psi par exemple.
+ vérifier que des messages sont bien émis partout (faire une recherche sur
les 'returns'... En particulier dans video_output).
General: processus
==================
* définir l'ordre de fermeture et les accès
- identifier les threads (pour ps)
? penser au mode mono-thread
+ utiliser les messages b_die, b_error, b_active et b_run
General: X11
============
- detection de fermeture des fenêtres
- déclaration des icones pour les window managers
- implémentation de X{En|Dis}ableScreenSaver dans xutils
Documentation
=============
- documentation des interfaces de programmation dès qu'elles sont
au point. En LaTeX ? (pour latex2html).
......@@ -4,7 +4,7 @@
* interface, such as message output. See config.h for output configuration.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: intf_msg.h,v 1.12 2001/04/27 19:29:11 massiot Exp $
* $Id: intf_msg.h,v 1.13 2001/04/30 15:00:59 massiot Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
......@@ -81,7 +81,6 @@ void intf_MsgDestroy ( void );
void intf_Msg ( char *psz_format, ... );
void intf_ErrMsg ( char *psz_format, ... );
void intf_WarnMsg ( int i_level, char *psz_format, ... );
void intf_IntfMsg ( char *psz_format, ... );
void intf_MsgImm ( char *psz_format, ... );
void intf_ErrMsgImm ( char *psz_format, ... );
......
/*****************************************************************************
* rsc_files.h: resources files manipulation functions
* This library describes a general format used to store 'resources'. Resources
* can be anything, including pictures, audio streams, and so on.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: rsc_files.h,v 1.7 2001/03/21 13:42:33 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Requires:
* config.h
* common.h
*****************************************************************************/
/*****************************************************************************
* Constants
*****************************************************************************/
/* Maximum length of a resource name (not including the final '\0') - this
* constant should not be changed without extreme care */
#define RESOURCE_MAX_NAME 32
/*****************************************************************************
* resource_descriptor_t: resource descriptor
*****************************************************************************
* This type describe an entry in the resource table.
*****************************************************************************/
typedef struct
{
char psz_name[RESOURCE_MAX_NAME + 1]; /* name */
u16 i_type; /* type */
u64 i_offset; /* data offset */
u64 i_size; /* data size */
} resource_descriptor_t;
/* Resources types */
#define EMPTY_RESOURCE 0 /* empty place in table */
#define PICTURE_RESOURCE 10 /* native video picture */
/*****************************************************************************
* resource_file_t: resource file descriptor
*****************************************************************************
* This type describes a resource file and store it's resources table. It can
* be used through the *Resource functions, or directly with the i_file field.
*****************************************************************************/
typedef struct
{
/* File informations */
int i_file; /* file descriptor */
int i_type; /* file type */
boolean_t b_up_to_date; /* is file up to date ? */
boolean_t b_read_only; /* read-only mode */
/* Resources table */
int i_size; /* table size */
resource_descriptor_t * p_resource; /* resources table */
} resource_file_t;
/* Resources files types */
#define VLC_RESOURCE_FILE 0 /* VideoLAN Client resource file */
/*****************************************************************************
* Prototypes
*****************************************************************************/
resource_file_t * CreateResourceFile ( char *psz_filename, int i_type, int i_size, int i_mode );
resource_file_t * OpenResourceFile ( char *psz_filename, int i_type, int i_flags );
int UpdateResourceFile ( resource_file_t *p_file );
int CloseResourceFile ( resource_file_t *p_file );
int SeekResource ( resource_file_t *p_file, char *psz_name, int i_type );
int ReadResource ( resource_file_t *p_file, char *psz_name, int i_type,
size_t max_size, byte_t *p_data );
int vlc_WriteResource ( resource_file_t *p_file, char *psz_name, int i_type,
size_t size, byte_t *p_data );
......@@ -4,7 +4,7 @@
* interface, such as command line.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: interface.c,v 1.73 2001/04/28 03:36:25 sam Exp $
* $Id: interface.c,v 1.74 2001/04/30 15:00:59 massiot Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
......@@ -47,7 +47,6 @@
#include "intf_msg.h"
#include "interface.h"
#include "intf_cmd.h"
#include "intf_playlist.h"
#include "intf_channels.h"
#include "keystrokes.h"
......
/*****************************************************************************
* intf_cmd.c: interface commands parsing and executions functions
* This file implements the interface commands execution functions. It is used
* by command-line oriented interfaces and scripts. The commands themselves are
* implemented in intf_ctrl.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: intf_cmd.c,v 1.18 2001/03/21 13:42:34 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <errno.h> /* errno */
#include <stdio.h> /* FILE */
#include <stdlib.h> /* strtod(), strtol() */
#include <string.h> /* strerror() */
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "interface.h"
#include "intf_msg.h"
#include "intf_cmd.h"
#include "intf_ctrl.h"
#include "main.h"
/*
* Local prototypes
*/
static int ParseCommandArguments ( char *psz_argv[INTF_MAX_ARGS],
char *psz_cmd );
static int CheckCommandArguments ( intf_arg_t argv[INTF_MAX_ARGS],
int i_argc,
char *psz_argv[INTF_MAX_ARGS],
char *psz_format );
static void ParseFormatString ( intf_arg_t format[INTF_MAX_ARGS],
char *psz_format );
static int ConvertArgument ( intf_arg_t *p_arg, int i_flags,
char *psz_str );
/*****************************************************************************
* intf_ExecCommand: parse and execute a command
*****************************************************************************
* This function is called when a command needs to be executed. It parse the
* command line, build an argument array, find the command in control commands
* array and run the command. It returns the return value of the command, or
* EINVAL if no command could be executed. Command line is modified by this
* function.
* Note that this function may terminate abruptly the program or signify it's
* end to the interface thread.
*****************************************************************************/
int intf_ExecCommand( char *psz_cmd )
{
char * psz_argv[INTF_MAX_ARGS]; /* arguments pointers */
intf_arg_t argv[INTF_MAX_ARGS]; /* converted arguments */
int i_argc; /* number of arguments */
int i_index; /* multi-purposes index */
int i_return; /* command return value */
intf_DbgMsg("command `%s'", psz_cmd);
/* Parse command line (separate arguments). If nothing has been found,
* the function returns without error */
i_argc = ParseCommandArguments( psz_argv, psz_cmd );
if( !i_argc )
{
return( 0 );
}
/* Find command. Command is always the first token on the line */
for( i_index = 0;
control_command[i_index].psz_name && strcmp( psz_argv[0], control_command[i_index].psz_name );
i_index++ )
{
;
}
if( !control_command[i_index].psz_name ) /* unknown command */
{
/* Print error message */
intf_IntfMsg( "error: unknown command `%s'. Try `help'", psz_argv[0] );
return( INTF_USAGE_ERROR );
}
/* Check arguments validity */
if( CheckCommandArguments( argv, i_argc, psz_argv,
control_command[i_index].psz_format ) )
{
/* The given arguments does not match the format string. An error
* message has already been displayed, so only the usage string
* is printed */
intf_IntfMsg( "usage: %s", control_command[i_index].psz_usage );
return( INTF_USAGE_ERROR );
}
/* Execute command */
i_return = control_command[i_index].function( i_argc, argv );
/* Manage special error codes */
switch( i_return )
{
case INTF_FATAL_ERROR: /* fatal error */
/* Print message and terminates the interface thread */
intf_ErrMsg( "intf error: fatal error in command `%s'", psz_argv[0] );
p_main->p_intf->b_die = 1;
break;
case INTF_CRITICAL_ERROR: /* critical error */
/* 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_ErrMsgImm( "intf error: critical error in command `%s', "
"please report this error !", psz_argv[0] );
exit( INTF_CRITICAL_ERROR );
break;
case INTF_USAGE_ERROR: /* usage error */
/* Print error message and usage */
intf_IntfMsg( "usage: %s", control_command[i_index].psz_usage );
break;
}
/* Return error code */
return( i_return );
}
/*****************************************************************************
* intf_ExecScript: parse and execute a command script
*****************************************************************************
* This function, based on ExecCommand read a file and tries to execute each
* of its line as a command. It returns 0 if everything succeeded, a negative
* number if the script could not be executed and a positive one if an error
* occured during execution.
*****************************************************************************/
int intf_ExecScript( char *psz_filename )
{
FILE * p_file; /* file */
char psz_line[INTF_MAX_CMD_SIZE]; /* line */
char * psz_index; /* index in string */
char * psz_vlcrc; /* full path to vlcrc */
int i_err; /* error indicator */
/* Open file */
i_err = 0;
if( !( psz_index = getenv("HOME") ) )
{
psz_index = "/";
}
psz_vlcrc = malloc( strlen( psz_index ) + 1 + strlen( psz_filename ) + 1 );
sprintf( psz_vlcrc, "%s/%s", psz_index, psz_filename );
p_file = fopen( psz_vlcrc, "r" );
if( p_file == NULL )
{
intf_DbgMsg("intf warning: %s: %s", psz_vlcrc, strerror(errno));
return( -1 );
}
/* For each line: read and execute */
while( fgets( psz_line, INTF_MAX_CMD_SIZE, p_file ) != NULL )
{
/* If line begins with a '#', it is a comment and shoule be ignored,
* else, execute it */
if( psz_line[0] != '#' )
{
/* The final '\n' needs to be removed before execution */
for( psz_index = psz_line;
*psz_index && (*psz_index != '\n');
psz_index++ )
{
;
}
if( *psz_index == '\n' )
{
*psz_index = '\0';
}
/* Execute command */
i_err |= intf_ExecCommand( psz_line );
}
}
if( !feof( p_file ) )
{
intf_ErrMsg( "intf error: %s: %s", psz_vlcrc, strerror(errno));
return( -1 );
}
/* Close file */
fclose( p_file );
return( i_err != 0 );
}
/* following functions are local */
/*****************************************************************************
* ParseCommandArguments: isolate arguments in a command line
*****************************************************************************
* This function modify the original command line, adding '\0' and completes
* an array of pointers to beginning of arguments. It return the number of
* arguments.
*****************************************************************************/
static int ParseCommandArguments( char *psz_argv[INTF_MAX_ARGS], char *psz_cmd )
{
int i_argc; /* number of arguments */
char * psz_index; /* index */
boolean_t b_block; /* block (argument) indicator */
/* Initialize parser state */
b_block = 0; /* we start outside a block to remove spaces at beginning */
i_argc = 0;
/* Go through command until end has been reached or maximal number of
* arguments has been reached */
for( psz_index = psz_cmd;
*psz_index && (i_argc < INTF_MAX_ARGS);
psz_index++ )
{
/* Inside a block, end of blocks are marked by spaces */
if( b_block )
{
if( *psz_index == ' ' )
{
*psz_index = '\0'; /* mark the end of argument */
b_block = 0; /* exit the block */
}
}
/* Outside a block, beginning of blocks are marked by any character
* different from space */
else
{
if( *psz_index != ' ' )
{
psz_argv[i_argc++] = psz_index; /* store argument */
b_block = 1; /* enter the block */
}
}
}
/* Return number of arguments found */
return( i_argc );
}
/*****************************************************************************
* CheckCommandArguments: check arguments agains format
*****************************************************************************
* This function parse each argument and tries to find a match in the format
* string. It fills the argv array.
* If all arguments have been sucessfuly identified and converted, it returns
* 0, else, an error message is issued and non 0 is returned.
* Note that no memory is allocated by this function, but that the arguments
* can be modified.
*****************************************************************************/
static int CheckCommandArguments( intf_arg_t argv[INTF_MAX_ARGS], int i_argc,
char *psz_argv[INTF_MAX_ARGS],
char *psz_format )
{
intf_arg_t format[INTF_MAX_ARGS]; /* parsed format indicators */
int i_arg; /* argument index */
int i_format; /* format index */
char * psz_index; /* string index */
char * psz_cmp_index; /* string comparaison index */
int i_index; /* generic index */
boolean_t b_found; /* `argument found' flag */
/* Build format array */
ParseFormatString( format, psz_format );
/* Initialize parser: i_format must be the first non named formatter */
for( i_format = 0; ( i_format < INTF_MAX_ARGS )
&& (format[i_format].i_flags & INTF_NAMED_ARG);
i_format++ )
{
;
}
/* Scan all arguments */
for( i_arg = 1; i_arg < i_argc; i_arg++ )
{
b_found = 0;
/* Test if argument can be taken as a named argument: try to find a
* '=' in the string */
for( psz_index = psz_argv[i_arg];
*psz_index && ( *psz_index != '=' );
psz_index++ )
{
;
}
if( *psz_index == '=' ) /* '=' found */
{
/* Browse all named arguments to check if there is one matching */
for( i_index = 0; (i_index < INTF_MAX_ARGS)
&& ( format[i_index].i_flags & INTF_NAMED_ARG )
&& !b_found;
i_index++ )
{
/* Current format string is named... compare start of two
* names. A local inline ntation of a strcmp is used since
* string isn't ended by '\0' but by '=' */
for( psz_index = psz_argv[i_arg],
psz_cmp_index = format[i_index].ps_name;
(*psz_index == *psz_cmp_index) && (*psz_index != '=')
&& (*psz_cmp_index != '=');
psz_index++, psz_cmp_index++ )
{
;
}
if( *psz_index == *psz_cmp_index ) /* the names match */
{
/* The argument is a named argument which name match the
* named argument i_index. To be valid, the argument
* should not have been already encountered and the type
* must match. Before going further, the '=' is replaced
* by a '\0'. */
*psz_index = '\0';
/* Check unicity. If the argument has already been
* encountered, print an error message and return. */
if( format[i_index].i_flags & INTF_PRESENT_ARG )
{
intf_IntfMsg( "error: `%s' has already been "
"encountered", psz_argv[i_arg] );
return( 1 );
}
/* Register argument and prepare exit */
b_found = 1;
format[i_index].i_flags |= INTF_PRESENT_ARG;
argv[i_arg].i_flags = INTF_NAMED_ARG;
argv[i_arg].i_index = i_index;
argv[i_arg].ps_name = psz_argv[i_arg];
/* Check type and store value */
psz_index++;
if( ConvertArgument( &argv[i_arg],
format[i_index].i_flags, psz_index ) )
{
/* An error occured during conversion */
intf_IntfMsg( "error: invalid type for `%s'",
psz_index );
}
}
}
}
/* If argument is not a named argument, the format string will
* be browsed starting from last position until the argument is
* found or an error occurs. */
if( !b_found )
{
/* Reset type indicator */
argv[i_arg].i_flags = 0;
/* If argument is not a named argument, the format string will
* be browsed starting from last position until the argument is
* found, an error occurs or the last format argument is
* reached */
while( !b_found && (i_format < INTF_MAX_ARGS)
&& format[i_format].i_flags )
{
/* Try to convert argument */
if( !ConvertArgument( &argv[i_arg], format[i_format].i_flags,
psz_argv[i_arg] ) )
{
/* Matching format has been found */
b_found = 1;
format[i_format].i_flags |= INTF_PRESENT_ARG;
argv[i_arg].i_index = i_format;
/* If argument is repeatable, dot not increase format
* counter */
if( !(format[i_format].i_flags & INTF_REP_ARG) )
{
i_format++;
}
}
else
{
/* Argument does not match format. This can be an error,
* or just a missing optionnal parameter, or the end of a
* repeated argument */
if( (format[i_format].i_flags & INTF_OPT_ARG)
|| (format[i_format].i_flags & INTF_PRESENT_ARG) )
{
/* This is not an error */
i_format++;
}
else
{
/* The present format argument is mandatory and does
* not match the argument */
intf_IntfMsg( "error: missing argument before `%s'",
psz_argv[i_arg] );
return( 1 );
}
}
}
}
/* If argument is not a named argument and hasn't been found in
* format string, then it is an usage error and the function can
* return */
if( !b_found )
{
intf_IntfMsg( "error: `%s' does not match any argument",
psz_argv[i_arg] );
return( 1 );
}
intf_DbgMsg(
"argument flags=0x%x (index=%d) name=%s str=%s int=%d float=%f",
argv[i_arg].i_flags, argv[i_arg].i_index,
(argv[i_arg].i_flags & INTF_NAMED_ARG) ? argv[i_arg].ps_name : "NA",
(argv[i_arg].i_flags & INTF_STR_ARG) ? argv[i_arg].psz_str : "NA",
(argv[i_arg].i_flags & INTF_INT_ARG) ? argv[i_arg].i_num : 0,
(argv[i_arg].i_flags & INTF_FLOAT_ARG) ? argv[i_arg].f_num : 0 );
}
/* Parse all remaining format specifier to verify they are all optionnal */
for( ; (i_format < INTF_MAX_ARGS) && format[i_format].i_flags ; i_format++ )
{
if( !(( format[i_format].i_flags & INTF_OPT_ARG)
|| ( format[i_format].i_flags & INTF_PRESENT_ARG)) )
{
/* Format has not been used and is neither optionnal nor multiple
* and present */
intf_IntfMsg("error: missing argument(s)");
return( 1 );
}
}
/* If an error occured, the function already exited, so if this point is
* reached, everything is fine */
return( 0 );
}
/*****************************************************************************
* ConvertArgument: try to convert an argument to a given type
*****************************************************************************
* This function tries to convert the string argument given in psz_str to
* a type specified in i_flags. It updates p_arg and returns O on success,
* or 1 on error. No error message is issued.
*****************************************************************************/
static int ConvertArgument( intf_arg_t *p_arg, int i_flags, char *psz_str )
{
char *psz_end; /* end pointer for conversion functions */
if( i_flags & INTF_STR_ARG ) /* string */
{
/* A conversion from a string to a string will always succeed... */
p_arg->psz_str = psz_str;
p_arg->i_flags |= INTF_STR_ARG;
}
else if( i_flags & INTF_INT_ARG ) /* integer */
{
p_arg->i_num = strtol( psz_str, &psz_end, 0 ); /* convert string */
/* If the conversion failed, return 1 and do not modify argument
* flags. Else, add 'int' flag and continue. */
if( !*psz_str || *psz_end )
{
return( 1 );
}
p_arg->i_flags |= INTF_INT_ARG;
}
else if( i_flags & INTF_FLOAT_ARG ) /* float */
{
p_arg->f_num = strtod( psz_str, &psz_end ); /* convert string */
/* If the conversion failed, return 1 and do not modify argument
* flags. Else, add 'float' flag and continue. */
if( !*psz_str || *psz_end )
{
return( 1 );
}
p_arg->i_flags |= INTF_FLOAT_ARG;
}
#ifdef DEBUG
else /* error: missing type specifier */
{
intf_ErrMsg( "intf error: missing type specifier for `%s' (0x%x)",
psz_str, i_flags );
return( 1 );
}
#endif
return( 0 );
}
/*****************************************************************************
* ParseFormatString: parse a format string (ok ?)
*****************************************************************************
* This function read a format string, as specified in the control_command
* array, and fill a format array, to allow easier argument identification.
* Note that no memory is allocated by this function, but that, in a named
* argument, the name field does not end with a '\0' but with an '='.
* See command.h for format string specifications.
* Note that this function is designed to be efficient, not to check
* everything in a format string, which should be entered by a developper
* and therefore should be correct (TRUST !).
*****************************************************************************/
static void ParseFormatString( intf_arg_t format[INTF_MAX_ARGS], char *psz_format )
{
char * psz_index; /* format string index */
char * psz_start; /* argument format start */
char * psz_item; /* item index */
int i_index; /* format index */
/* Initialize parser */
i_index = 0;
psz_start = psz_format;
/* Reset first format indicator */
format[ 0 ].i_flags = 0;
/* Parse format string */
for( psz_index = psz_format; *psz_index && (i_index < INTF_MAX_ARGS) ; psz_index++ )
{
/* A space is always an item terminator */
if( *psz_index == ' ' )
{
/* Parse format item. Items are parsed from end to beginning or to
* first '=' */
for( psz_item = psz_index - 1;
(psz_item >= psz_start) && !( format[i_index].i_flags & INTF_NAMED_ARG);
psz_item-- )
{
switch( *psz_item )
{
case 's': /* string */
format[i_index].i_flags |= INTF_STR_ARG;
break;
case 'i': /* integer */
format[i_index].i_flags |= INTF_INT_ARG;
break;
case 'f': /* float */
format[i_index].i_flags |= INTF_FLOAT_ARG;
break;
case '*': /* can be repeated */
format[i_index].i_flags |= INTF_REP_ARG;
break;
case '?': /* optionnal argument */
format[i_index].i_flags |= INTF_OPT_ARG;
break;
case '=': /* name argument */
format[i_index].i_flags |= INTF_NAMED_ARG;
format[i_index].ps_name = psz_start;
break;
#ifdef DEBUG
default:/* error which should never happen: incorrect format */
intf_DbgMsg("error: incorrect format string `%s'", psz_format);
break;
#endif
}
}
/* Mark next item start, increase items counter and reset next
* format indicator, if it wasn't the last one. */
i_index++;
psz_start = psz_index + 1;
if( i_index != INTF_MAX_ARGS ) /* end of array not reached */
{
format[ i_index ].i_flags = 0;
}
}
}
}
/*****************************************************************************
* intf_cmd.h: interface commands parsing and executions functions
* This file implements the interface commands execution functions. It is used
* by command-line oriented interfaces and scripts. The commands themselves are
* implemented in intf_ctrl.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: intf_cmd.h,v 1.4 2001/03/21 13:42:34 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Required headers:
* none
*****************************************************************************/
/*****************************************************************************
* intf_arg_t: control fonction argument descriptor
*****************************************************************************
* This structure is used to control an argument type and to transmit
* arguments to control functions. It is also used to parse format string and
* build an easier to use array of arguments.
*****************************************************************************/
typedef struct
{
/* Argument type */
int i_flags; /* argument type and flags */
int i_index; /* index of mask in format string */
/* Converted arguments value */
char * psz_str; /* string value */
char * ps_name; /* name, can be '\0' or '=' terminated */
long i_num; /* integer value */
float f_num; /* float value */
} intf_arg_t;
/* Arguments flags */
#define INTF_STR_ARG 1 /* string argument */
#define INTF_INT_ARG 2 /* integer argument */
#define INTF_FLOAT_ARG 4 /* float argument */
#define INTF_NAMED_ARG 16 /* named argument */
#define INTF_OPT_ARG 256 /* optionnal argument */
#define INTF_REP_ARG 512 /* argument can be repeated */
#define INTF_PRESENT_ARG 1024 /* argument has been encountered */
/*****************************************************************************
* intf_command_t: control command descriptor
*****************************************************************************
* This structure describes a control commands. It stores informations needed
* for argument type checking, command execution but also a short inline help.
* See control.c for more informations about fields.
*****************************************************************************/
typedef struct
{
/* Function control */
char * psz_name; /* command name */
int (* function)( int i_argc, intf_arg_t *p_argv ); /* function */
char * psz_format; /* arguments format */
/* Function informations */
char * psz_summary; /* info text */
char * psz_usage; /* usage text */
char * psz_help; /* help text */
} intf_command_t;
/*****************************************************************************
* Error constants
*****************************************************************************
* These errors should be used as return values for control functions (see
* control.c). The intf_ExecCommand function as different behaviour depending
* of the error it received. Other errors numbers can be used, but their valued
* should be positive to avoid conflict with future error codes.
*****************************************************************************/
#define INTF_NO_ERROR 0 /* success */
#define INTF_FATAL_ERROR -1 /* fatal error: the program will end */
#define INTF_CRITICAL_ERROR -2 /* critical error: the program will exit */
#define INTF_USAGE_ERROR -3 /* usage error: command usage will be displayed */
#define INTF_OTHER_ERROR -4/* other error: command prints its own message */
/*****************************************************************************
* Prototypes
*****************************************************************************/
int intf_ExecCommand ( char *psz_cmd );
int intf_ExecScript ( char *psz_filename );
/*****************************************************************************
* intf_console.c: generic console for interface
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: intf_console.c,v 1.7 2001/03/21 13:42:34 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <stdlib.h> /* malloc() */
#include "config.h"
/*****************************************************************************
* intf_console_t: console descriptor
*****************************************************************************
* Generic console object. This object will have a representation depending of
* the interface.
*****************************************************************************/
typedef struct intf_console_s
{
/* Text and history arrays - last line/command has indice 0 */
char * psz_text[INTF_CONSOLE_MAX_TEXT];
char * psz_history[INTF_CONSOLE_MAX_HISTORY];
} intf_console_t;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
/*****************************************************************************
* intf_ConsoleCreate: create console
*****************************************************************************
* This function will initialize the console object.
* It returns NULL on error.
*****************************************************************************/
intf_console_t *intf_ConsoleCreate( void )
{
intf_console_t *p_console;
p_console = malloc( sizeof( intf_console_t ) );
return( p_console );
}
/*****************************************************************************
* intf_ConsoleDestroy
*****************************************************************************
* Destroy the console instance initialized by intf_ConsoleCreate.
*****************************************************************************/
void intf_ConsoleDestroy( intf_console_t *p_console )
{
free( p_console );
}
/*****************************************************************************
* intf_ConsoleClear: clear console
*****************************************************************************
* Empty all text.
*****************************************************************************/
void intf_ConsoleClear( intf_console_t *p_console )
{
/* XXX?? */
}
/*****************************************************************************
* intf_ConsolePrint: print a message to console
*****************************************************************************
* Print a message to the console.
*****************************************************************************/
void intf_ConsolePrint( intf_console_t *p_console, char *psz_str )
{
/* XXX?? */
}
/*****************************************************************************
* intf_ConsoleExec: execute a command in console
*****************************************************************************
* This function will run a command and print its result in console.
*****************************************************************************/
void intf_ConsoleExec( intf_console_t *p_console, char *psz_str )
{
/* XXX?? */
}
/* following functions are local */
/*****************************************************************************
* intf_console.h: generic console methods for interface
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: intf_console.h,v 1.4 2001/03/21 13:42:34 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Prototypes
*****************************************************************************/
p_intf_console_t intf_ConsoleCreate ( void );
void intf_ConsoleDestroy ( p_intf_console_t p_console );
void intf_ConsoleClear ( p_intf_console_t p_console );
void intf_ConsolePrint ( p_intf_console_t p_console, char *psz_str );
void intf_ConsoleExec ( p_intf_console_t p_console, char *psz_str );
/*****************************************************************************
* intf_ctrl.c: interface commands access to control functions
* Library of functions common to all interfaces, allowing access to various
* structures and settings. Interfaces should only use those functions
* to read or write informations from other threads.
* A control function must be declared in the `local prototypes' section (it's
* type is fixed), and copied into the control_command array. Functions should
* be listed in alphabetical order, so when `help' is called they are also
* displayed in this order.
* A control function can use any function of the program, but should respect
* two points: first, it should not block, since if it does so, the whole
* interface thread will hang and in particular miscelannous interface events
* won't be handled. Secondly, it should send it's output messages exclusively
* with intf_IntfMsg() function, except particularly critical messages which
* can use over intf_*Msg() functions.
* Control functions should return 0 (INTF_NO_ERROR) on success, or one of the
* error codes defined in command.h. Custom error codes are allowed, but should
* be positive.
* More informations about parameters stand in `list of commands' section.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: intf_ctrl.c,v 1.36 2001/04/11 02:01:24 henri Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <sys/stat.h> /* on BSD, fstat() needs stat.h */
#include <stdio.h> /* fprintf() */
#include <string.h> /* strcmp() */
#include <stdlib.h> /* malloc(), free() */
#include <unistd.h> /* close(), read() */
#include <fcntl.h> /* open() */
/* Common headers */
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "debug.h"
#include "intf_msg.h"
#include "stream_control.h"
#include "input_ext-intf.h"
#include "audio_output.h"
#include "intf_cmd.h"
#include "interface.h"
#include "main.h"
/*
* Local prototypes
*/
static int Demo ( int i_argc, intf_arg_t *p_argv );
static int DisplayImage ( int i_argc, intf_arg_t *p_argv );
static int Exec ( int i_argc, intf_arg_t *p_argv );
static int Help ( int i_argc, intf_arg_t *p_argv );
static int PlayAudio ( int i_argc, intf_arg_t *p_argv );
static int PlayVideo ( int i_argc, intf_arg_t *p_argv );
static int Quit ( int i_argc, intf_arg_t *p_argv );
static int SelectPID ( int i_argc, intf_arg_t *p_argv );
static int SpawnInput ( int i_argc, intf_arg_t *p_argv );
#ifdef DEBUG
static int Test ( int i_argc, intf_arg_t *p_argv );
#endif
static int Channel ( int i_argc, intf_arg_t *p_argv );
static int Psi ( int i_argc, intf_arg_t *p_argv );
/*
* List of commands.
* This list is used by intf_ExecCommand function to find functions to
* execute and prepare its arguments. It is terminated by an element which name
* is a null pointer. intf_command_t is defined in command.h.
*
* Here is a description of a command description elements:
* name is the name of the function, as it should be typed on command line,
* function is a pointer to the control function,
* format is an argument descriptor (see below),
* summary is a text string displayed in regard of the command name when `help'
* is called without parameters, and whith usage on syntax error,
* usage is a short syntax indicator displayed with summary when the command
* causes a syntax error,
* help is a complete help about the command, displayed when `help' is called with
* the command name as parameter.
*
* Format string is a list of ' ' separated strings, which have following
* meanings:
* s string argument
* i integer argument
* f float argument
* ? optionnal argument
* * argument can be repeated
* name= named argument
* Example: "channel=i? s*? i " means that any number of string arguments,
* followed by a single mandatory integer argument are waited. A named argument,
* which name is `channel' and must have an integer value can be optionnaly
* specified at beginning. The last space is mandatory if there is at least one
* element, since it acts as an item terminator.
* Named arguments MUST be at the beginning of the format string, and in
* alphabetic order, but their order on command line has no importance.
* The format string can't have more than INTF_MAX_ARGS elements.
*/
const intf_command_t control_command[] =
{
{ "demo", Demo, /* demo */
/* format: */ "",
/* summary: */ "program demonstration",
/* usage: */ "demo",
/* help: */ "Start program capabilities demonstration." },
{ "display", DisplayImage, /* display */
/* format: */ "s ",
/* summary: */ "load and display an image",
/* usage: */ "display <file>",
/* help: */ "Load and display an image. Image format is automatically "\
"identified from file name extension." },
{ "exec", Exec, /* exec */
/* format: */ "s ",
/* summary: */ "execute a script file",
/* usage: */ "exec <file>",
/* help: */ "Load an execute a script." },
{ "exit", Quit, /* exit (quit alias) */
/* format: */ "",
/* summary: */ "quit program",
/* usage: */ "exit",
/* help: */ "see `quit'." },
{ "help", Help, /* help */
/* format: */ "s? ",
/* summary: */ "list all functions or print help about a specific function",
/* usage: */ "help [command]",
/* help: */ "If called without argument, list all available " \
" functions.\nIf a command name is provided as argument, displays a short "\
"inline help about the command.\n" },
{ "play-audio", PlayAudio, /* play-audio */
/* format: */ "channels=i? rate=i? s ",
/* summary: */ "play an audio file",
/* usage: */ "play-audio [channels=1/2] [rate=r] <file>",
/* help: */ "Load and play an audio file." },
{ "play-video", PlayVideo, /* play-video */
/* format: */ "s ",
/* summary: */ "play a video (.vlp) file",
/* usage: */ "play-video <file>",
/* help: */ "Load and play a video file." },
{ "quit", Quit, /* quit */
/* format: */ "",
/* summary: */ "quit program",
/* usage: */ "quit",
/* help: */ "Terminates the program execution... There is not much to"\
" say about it !" },
{ "select-pid", SelectPID, /* select-pid */
/* format: */ "i i ",
/* summary: */ "spawn a decoder thread for a specified PID",
/* summary: */ "select-pid <input> <pid>",
/* help: */ "Spawn a decoder thread for <pid>. The stream will be" \
" received by <input>." },
{ "spawn-input", SpawnInput, /* spawn-input */
/* format: */ "method=i? filename=s? hostname=s? ip=s? port=i?"\
" channel=i?",
/* summary: */ "spawn an input thread",
/* summary: */ "spawn-input [method=<method>]\n" \
"[filename=<file>|hostname=<hostname>|ip=<ip>]\n" \
"[port=<port>] [channel=<channel>]",
/* help: */ "Spawn an input thread. Method is 10, 20, 21, 22, 32, "\
"hostname is the fully-qualified domain name, ip is a dotted-decimal address." },
#ifdef DEBUG
{ "test", Test, /* test */
/* format: */ "i? ",
/* summary: */ "crazy developper's test",
/* usage: */ "depends on the last coder :-)",
/* help: */ "`test' works only in DEBUG mode, and is provide for " \
"developpers as an easy way to test part of their code. If you don't know "\
"what it should do, just try !" },
#endif
{ "channel", Channel,
/* format: */ "intf=s? s i? ",
/* summary: */ "channel changing operations",
/* usage: */ "channel synchro\n" \
"channel [intf=<interface>] request\n" \
"channel [intf=<interface>] join <channel>\n" \
"channel [intf=<interface>] leave",
/* help: */ "Perform various operations on channels. 'synchro'"\
"resynchronize with the server. 'request' ask which is the current"\
"channel (for the default interface or for a given one)."\
"'join' and 'leave' try to change channel." },
{ "psi", Psi,
/* format: */ "i ",
/* summary: */ "Dump PSI tables",
/* usage: */ "psi <input thread index>",
/* help: */ "Display the PSI tables on the console. Warning: this is debug" \
"command, it can leads to pb since locks are not taken yet" },
{ 0, 0, 0, 0, 0 } /* array terminator */
};
/* following functions are local */
/*****************************************************************************
* Demo: demo
*****************************************************************************
* This function is provided to display a demo of program possibilities.
*****************************************************************************/
static int Demo( int i_argc, intf_arg_t *p_argv )
{
intf_IntfMsg( COPYRIGHT_MESSAGE );
return( INTF_NO_ERROR );
}
/*****************************************************************************
* Exec: execute a script
*****************************************************************************
* This function load and execute a script.
*****************************************************************************/
static int Exec( int i_argc, intf_arg_t *p_argv )
{
int i_err; /* error code */
i_err = intf_ExecScript( p_argv[1].psz_str );
return( i_err ? INTF_OTHER_ERROR : INTF_NO_ERROR );
}
/*****************************************************************************
* DisplayImage: load and display an image (ok ?)
*****************************************************************************
* Try to load an image identified by it's filename and displays it as a still
* image using interface video heap.
*****************************************************************************/
static int DisplayImage( int i_argc, intf_arg_t *p_argv )
{
/* XXX?? */
return( INTF_NO_ERROR );
}
/*****************************************************************************
* Help: list all available commands (ok ?)
*****************************************************************************
* This function print a list of available commands
*****************************************************************************/
static int Help( int i_argc, intf_arg_t *p_argv )
{
int i_index; /* command index */
/* If called with an argument: look for the command and display it's help */
if( i_argc == 2 )
{
fprintf( stderr, "maxx debug: coin\n" );
for( i_index = 0; control_command[i_index].psz_name
&& strcmp( control_command[i_index].psz_name, p_argv[1].psz_str );
i_index++ )
{
;
}
fprintf( stderr, "maxx debug: meuh\n" );
/* Command has been found in list */
if( control_command[i_index].psz_name )
{
fprintf( stderr, "maxx debug: meow\n" );
intf_IntfMsg( control_command[i_index].psz_usage );
fprintf( stderr, "maxx debug: blah\n" );
intf_IntfMsg( control_command[i_index].psz_help );
fprintf( stderr, "maxx debug: blih\n" );
}
/* Command is unknown */
else
{
intf_IntfMsg("help: don't know command `%s'", p_argv[1].psz_str);
return( INTF_OTHER_ERROR );
}
}
/* If called without argument: print all commands help field */
else
{
for( i_index = 0; control_command[i_index].psz_name; i_index++ )
{
intf_IntfMsg( "%s: %s", control_command[i_index].psz_name,
control_command[i_index].psz_summary );
}
}
return( INTF_NO_ERROR );
}
/*****************************************************************************
* PlayAudio: play an audio file (ok ?)
*****************************************************************************
* Play a raw audio file from a file, at a given rate.
*****************************************************************************/
static int PlayAudio( int i_argc, intf_arg_t *p_argv )
{
char * psz_file = NULL; /* name of the audio raw file (s16) */
int i_fd; /* file descriptor of the audio file that is to be loaded */
aout_fifo_t fifo; /* fifo stores the informations about the file */
struct stat stat_buffer; /* needed to find out the size of psz_file */
int i_arg; /* argument index */
if ( !p_main->b_audio ) /* audio is disabled */
{
intf_IntfMsg("play-audio error: audio is disabled");
return( INTF_NO_ERROR );
}
/* Set default configuration */
fifo.i_channels = 1 + ( fifo.b_stereo = AOUT_STEREO_DEFAULT );
fifo.l_rate = AOUT_RATE_DEFAULT;
/* The channels and rate parameters are essential ! */
/* Parse parameters - see command list above */
for ( i_arg = 1; i_arg < i_argc; i_arg++ )
{
switch( p_argv[i_arg].i_index )
{
case 0: /* channels */
fifo.i_channels = p_argv[i_arg].i_num;
break;
case 1: /* rate */
fifo.l_rate = p_argv[i_arg].i_num;
break;
case 2: /* filename */
psz_file = p_argv[i_arg].psz_str;
break;
}
}
/* Setting up the type of the fifo */
switch ( fifo.i_channels )
{
case 1:
fifo.i_type = AOUT_INTF_MONO_FIFO;
break;
case 2:
fifo.i_type = AOUT_INTF_STEREO_FIFO;
break;
default:
intf_IntfMsg("play-audio error: channels must be 1 or 2");
return( INTF_OTHER_ERROR );
}
/* Open file */
i_fd = open( psz_file, O_RDONLY );
if ( i_fd < 0 ) /* error */
{
intf_IntfMsg("play-audio error: can't open `%s'", psz_file);
return( INTF_OTHER_ERROR );
}
/* Get file size to calculate number of audio units */
fstat( i_fd, &stat_buffer );
fifo.l_units = ( long )( stat_buffer.st_size / (sizeof(s16) << fifo.b_stereo) );
/* Allocate memory, read file and close it */
if ( (fifo.buffer = malloc(sizeof(s16)*(fifo.l_units << fifo.b_stereo))) == NULL ) /* !! */
{
intf_IntfMsg("play-audio error: not enough memory to read `%s'", psz_file );
close( i_fd ); /* close file */
return( INTF_OTHER_ERROR );
}
if ( read(i_fd, fifo.buffer, sizeof(s16)*(fifo.l_units << fifo.b_stereo))
!= sizeof(s16)*(fifo.l_units << fifo.b_stereo) )
{
intf_IntfMsg("play-audio error: can't read %s", psz_file);
free( fifo.buffer );
close( i_fd );
return( INTF_OTHER_ERROR );
}
close( i_fd );
/* Now we can work out how many output units we can compute with the fifo */
fifo.l_units = (long)(((s64)fifo.l_units*(s64)p_main->p_aout->l_rate)/(s64)fifo.l_rate);
/* Create the fifo */
if ( aout_CreateFifo(p_main->p_aout, &fifo) == NULL )
{
intf_IntfMsg("play-audio error: can't create audio fifo");
free( fifo.buffer );
return( INTF_OTHER_ERROR );
}
return( INTF_NO_ERROR );
}
/*****************************************************************************
* PlayVideo: play a video sequence from a file
*****************************************************************************
* XXX??
*****************************************************************************/
static int PlayVideo( int i_argc, intf_arg_t *p_argv )
{
/* XXX?? */
return( INTF_NO_ERROR );
}
/*****************************************************************************
* Quit: quit program (ok ?)
*****************************************************************************
* This function set `die' flag of interface, asking the program to terminate.
*****************************************************************************/
static int Quit( int i_argc, intf_arg_t *p_argv )
{
p_main->p_intf->b_die = 1;
return( INTF_NO_ERROR );
}
/*****************************************************************************
*
*****************************************************************************
*
*****************************************************************************/
static int SelectPID( int i_argc, intf_arg_t *p_argv )
{
int i_input = -1, i_pid = -1;
int i_arg;
/* Parse parameters - see command list above */
for ( i_arg = 1; i_arg < i_argc; i_arg++ )
{
switch( p_argv[i_arg].i_index )
{
case 0:
/* FIXME: useless ?? */
i_input = p_argv[i_arg].i_num;
break;
case 1:
i_pid = p_argv[i_arg].i_num;
break;
}
}
/* Find to which input this command is destinated */
intf_IntfMsg( "Adding PID %d to input %d", i_pid, i_input );
//XXX?? input_AddPgrmElem( p_main->p_intf->p_x11->p_input,
//XXX?? i_pid );
return( INTF_NO_ERROR );
}
/*****************************************************************************
* SpawnInput: spawn an input thread (ok ?)
*****************************************************************************
* Spawn an input thread
*****************************************************************************/
static int SpawnInput( int i_argc, intf_arg_t *p_argv )
{
/* FIXME */
#if 0
int i_arg;
int i_method = 0; /* method parameter */
char * p_source = NULL; /* source parameter */
int i_port = 0; /* port parameter */
int i_vlan_id = 0; /* vlan id parameter */
/* Parse parameters - see command list above */
for ( i_arg = 1; i_arg < i_argc; i_arg++ )
{
switch( p_argv[i_arg].i_index )
{
case 0: /* method */
i_method = p_argv[i_arg].i_num;
break;
case 1: /* filename, hostname, ip */
case 2:
case 3:
p_source = p_argv[i_arg].psz_str;
break;
case 4: /* port */
i_port = p_argv[i_arg].i_num;
break;
case 5: /* VLAN id */
i_vlan_id = p_argv[i_arg].i_num;
break;
}
}
/* Destroy current input, if any */
if( p_main->p_intf->p_input != NULL )
{
input_DestroyThread( p_main->p_intf->p_input, NULL );
}
p_main->p_intf->p_input = input_CreateThread( i_method, p_source, i_port, i_vlan_id,
p_main->p_intf->p_vout, p_main->p_aout,
NULL );
#endif
return( INTF_NO_ERROR );
}
/*****************************************************************************
* Test: test function
*****************************************************************************
* This function is provided to test new functions in the program. Fell free
* to modify !
* This function is only defined in DEBUG mode.
*****************************************************************************/
#ifdef DEBUG
static int Test( int i_argc, intf_arg_t *p_argv )
{
int i_thread;
/*XXX?? if( i_argc == 1 )
{
i_thread = intf_CreateVoutThread( &p_main->intf_thread, NULL, -1, -1);
intf_IntfMsg("return value: %d", i_thread );
}
else*/
{
i_thread = p_argv[1].i_num;
//XXX?? intf_DestroyVoutThread( &p_main->intf_thread, i_thread );
}
return( INTF_NO_ERROR );
}
#endif
/*****************************************************************************
* Channels: channel operations
*****************************************************************************
* This function performs various channel operations.
*****************************************************************************/
static int Channel( int i_argc, intf_arg_t *p_argv )
{
int i_command; /* command argument number */
/* Do not try anything if channel changing is desactivated */
if( !p_main->b_channels )
{
intf_IntfMsg("channel changing is desactivated");
return( INTF_OTHER_ERROR );
}
/* Look for command in list of arguments - this argument is mandatory and
* imposed by the calling function */
for( i_command = 1; p_argv[i_command].i_index == 1; i_command++ )
{
;
}
/* Command is 'join' */
if( !strcmp(p_argv[i_command].psz_str, "join") )
{
/* XXX?? */
}
/* Command is 'leave' */
else if( !strcmp(p_argv[i_command].psz_str, "leave") )
{
/* XXX?? */
}
/* Command is unknown */
else
{
intf_IntfMsg("channel error: unknown command %s", p_argv[i_command].psz_str );
return( INTF_USAGE_ERROR );
}
return( INTF_NO_ERROR );
}
/*****************************************************************************
* Psi
*****************************************************************************
* This function is provided to display PSI tables.
*****************************************************************************/
static int Psi( int i_argc, intf_arg_t *p_argv )
{
int i_index = p_argv[1].i_num;
intf_IntfMsg("Reading PSI table for input %d", i_index);
//XXX?? input_PsiRead(p_main->p_intf->p_x11->p_input );
return( INTF_NO_ERROR );
}
/*****************************************************************************
* intf_ctrl.h: interface commands access to control functions
* Library of functions common to all interfaces, allowing access to various
* structures and settings. Interfaces should only use those functions
* to read or write informations from other threads.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: intf_ctrl.h,v 1.4 2001/03/21 13:42:34 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Required headers:
* none
*****************************************************************************/
/*****************************************************************************
* Extern variables
*****************************************************************************/
extern const intf_command_t control_command[];
......@@ -4,7 +4,7 @@
* interface, such as message output. See config.h for output configuration.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: intf_msg.c,v 1.32 2001/04/28 03:36:25 sam Exp $
* $Id: intf_msg.c,v 1.33 2001/04/30 15:01:00 massiot Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
......@@ -43,7 +43,6 @@
#include "intf_msg.h"
#include "interface.h"
#include "intf_console.h"
#include "main.h"
......@@ -76,7 +75,6 @@ typedef struct
/* Message types */
#define INTF_MSG_STD 0 /* standard message */
#define INTF_MSG_ERR 1 /* error message */
#define INTF_MSG_INTF 2 /* interface message */
#define INTF_MSG_DBG 3 /* debug message */
#define INTF_MSG_WARN 4 /* warning message*/
......@@ -238,26 +236,6 @@ void intf_WarnMsg( int i_level, char *psz_format, ... )
}
/*****************************************************************************
* intf_IntfMsg : print an interface message (ok ?)
*****************************************************************************
* In opposition to all other intf_*Msg function, this function does not print
* it's message on default terminal (stdout or stderr), but send it to
* interface (in fact to the X11 console). This means that the interface MUST
* be initialized and a X11 console openned before this function is used, and
* that once the console is closed, this call is vorbidden.
* Practically, only the interface thread itself should call this function, and
* flush all messages before intf_CloseX11Console() is called.
*****************************************************************************/
void intf_IntfMsg(char *psz_format, ...)
{
va_list ap;
va_start( ap, psz_format );
QueueMsg( p_main->p_msg, INTF_MSG_INTF, psz_format, ap );
va_end( ap );
}
/*****************************************************************************
* _intf_DbgMsg: print a debugging message (ok ?)
*****************************************************************************
......@@ -608,10 +586,6 @@ static void PrintMsg( intf_msg_item_t *p_msg )
break;
case INTF_MSG_INTF: /* interface messages */
snprintf( psz_msg, i_msg_len, "%s", p_msg->psz_msg );
break;
case INTF_MSG_DBG: /* debug messages */
mstrtime( psz_date, p_msg->date );
snprintf( psz_msg, i_msg_len, "(%s) " INTF_MSG_DBG_FORMAT "%s",
......@@ -635,9 +609,6 @@ static void PrintMsg( intf_msg_item_t *p_msg )
#endif
fprintf( stderr, "%s\n", psz_msg );
break;
case INTF_MSG_INTF: /* interface messages */
intf_ConsolePrint( p_main->p_intf->p_console, psz_msg );
break;
}
#ifdef TRACE_LOG
......@@ -670,9 +641,6 @@ static void PrintMsg( intf_msg_item_t *p_msg )
case INTF_MSG_WARN:
fprintf( stderr, "%s\n", p_msg->psz_msg ); /* warning message */
break;
case INTF_MSG_INTF: /* interface messages */
intf_ConsolePrint( p_main->p_intf->p_console, p_msg->psz_msg );
break;
}
}
......
/*****************************************************************************
* rsc_files.c: resources files manipulation functions
* This library describe a general format used to store 'resources'. Resources
* can be anything, including pictures, audio streams, and so on.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: rsc_files.c,v 1.10 2001/04/27 19:29:11 massiot Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Format of a resource file:
* offset type meaning
* 0 char[2] "RF" (magic number)
* 2 char[2] "VL" (minor magic number, ignored)
* 4 u16 i_type: resource file type. This is to allow
* different versions of the resources types constants.
* 6 u16 i_size: number of entries in the resources table.
* {
* +0 char[32] resource name (ASCIIZ or ASCII[32])
* +32 u16 resource type
* +34 u64 data offset in bytes, from beginning of file
* +42 u64 data size in bytes
* } * i_size
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <errno.h> /* errno */
#include <fcntl.h> /* open() */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror(), strncopy() */
#include <unistd.h> /* read(), close(), lseek(), write() */
#include "config.h"
#include "common.h"
#include "mtime.h"
#include "rsc_files.h"
#include "intf_msg.h"
/*****************************************************************************
* CreateResourceFile: create a new resource file
*****************************************************************************
* Creates a new resource file. The file is opened read/write and erased if
* it already exists.
*****************************************************************************
* Messages type: rsc, major code 101
*****************************************************************************/
resource_file_t *CreateResourceFile( char *psz_filename, int i_type, int i_size,
int i_mode )
{
resource_file_t * p_file; /* new descriptor */
int i_index; /* resource index */
/* Create descriptor and tables */
p_file = malloc( sizeof(resource_file_t) );
if( p_file == NULL )
{
intf_ErrMsg("rsc error 101-1: %s", strerror(errno));
return( NULL );
}
p_file->p_resource = malloc( sizeof(resource_descriptor_t) * i_size );
if( p_file->p_resource == NULL )
{
intf_ErrMsg("rsc error 101-2: %s", strerror(errno));
free( p_file );
return( NULL );
}
/* Open file */
p_file->i_file = open( psz_filename, O_CREAT | O_RDWR, i_mode );
if( p_file->i_file == -1 ) /* error */
{
intf_ErrMsg("rsc error 101-3: %s: %s", psz_filename, strerror(errno) );
free( p_file->p_resource );
free( p_file );
}
/* Initialize tables */
p_file->i_type = i_type;
p_file->i_size = i_size;
p_file->b_read_only = 0;
for( i_index = 0; i_index < i_size; i_index++ )
{
p_file->p_resource[i_index].i_type = EMPTY_RESOURCE;
}
return( p_file );
}
/*****************************************************************************
* OpenResourceFile: open an existing resource file read-only
*****************************************************************************
* Open an existing resource file. i_flags should be O_RDONLY or O_RDWR. An
* error will occurs if the file does not exists.
*****************************************************************************
* Messages type: rsc, major code 102
*****************************************************************************/
resource_file_t *OpenResourceFile( char *psz_filename, int i_type, int i_flags )
{
resource_file_t * p_file; /* new descriptor */
int i_index; /* resource index */
byte_t p_buffer[50]; /* buffer */
/* Create descriptor and tables */
p_file = malloc( sizeof(resource_file_t) );
if( p_file == NULL )
{
intf_ErrMsg("rsc error 102-1: %s", strerror(errno));
return( NULL );
}
/* Open file */
p_file->i_file = open( psz_filename, i_flags );
if( p_file->i_file == -1 ) /* error */
{
intf_ErrMsg("rsc error 102-2: %s: %s", psz_filename, strerror(errno) );
free( p_file );
return( NULL );
}
/* Read header */
if( read( p_file->i_file, p_buffer, 8 ) != 8)
{
intf_ErrMsg("rsc error 102-3: %s: unexpected end of file (not a resource file ?)");
close( p_file->i_file );
free( p_file);
return( NULL );
}
if( (p_buffer[0] != 'R') || (p_buffer[0] != 'F') || (*(u16 *)(p_buffer + 4) != i_type) )
{
intf_ErrMsg("rsc error 102-4: %s is not a valid resource file or has incorrect type", psz_filename);
close( p_file->i_file );
free( p_file );
return( NULL );
}
p_file->i_type = i_type;
p_file->i_size = *(u16 *)(p_buffer + 6);
intf_DbgMsg("rsc debug 102-1: %s opened, %d resources", psz_filename, p_file->i_size);
/* Allocate tables */
p_file->p_resource = malloc( sizeof(resource_descriptor_t) * p_file->i_size );
if( p_file->p_resource == NULL )
{
intf_ErrMsg("rsc error 102-5: %s", strerror(errno));
close( p_file->i_file );
free( p_file );
return( NULL );
}
/* Initialize table */
p_file->b_up_to_date = 1;
p_file->b_read_only = ( i_flags & O_RDWR ) ? 0 : 1;
for( i_index = 0; i_index < p_file->i_size; i_index++ )
{
if( read( p_file->i_file, p_buffer, 50 ) != 50 )
{
intf_ErrMsg("rsc error 102-6: %s: unexpected end of file", psz_filename);
close( p_file->i_file );
free( p_file->p_resource );
free( p_file );
return( NULL );
}
memcpy( p_file->p_resource[i_index].psz_name, p_buffer, 32 );
p_file->p_resource[i_index].psz_name[RESOURCE_MAX_NAME] = '\0';
p_file->p_resource[i_index].i_type = *(u16 *)(p_buffer + 32 );
p_file->p_resource[i_index].i_offset = *(u64 *)(p_buffer + 34 );
p_file->p_resource[i_index].i_size = *(u64 *)(p_buffer + 42 );
}
return( p_file );
}
/*****************************************************************************
* UpdateResourceFile: write the resources table in a resource file
*****************************************************************************
* This function writes resources table in the resource file. This is
* automatically done when the file is closed, but can also be done manually.
*****************************************************************************
* Messages type: rsc, major code 103
*****************************************************************************/
int UpdateResourceFile( resource_file_t *p_file )
{
byte_t p_buffer[50]; /* buffer */
int i_index; /* resource index */
if( p_file->b_read_only )
{
intf_ErrMsg("rsc debug 103-1: can't update a read-only file");
return( -1 );
}
/* Seek beginning of file */
if( lseek( p_file->i_file, 0, SEEK_SET ) )
{
intf_ErrMsg("rsc error 103-1: %s", strerror(errno));
return( -2 );
}
/* Write header */
p_buffer[0] = 'R';
p_buffer[1] = 'F';
p_buffer[2] = 'V';
p_buffer[3] = 'L';
*(u16 *)(p_buffer + 4) = p_file->i_type;
*(u16 *)(p_buffer + 6) = p_file->i_size;
if( write( p_file->i_file, p_buffer, 8 ) != 8 )
{
intf_ErrMsg("rsc error 103-2: %s", strerror(errno));
return( -3 );
}
/* Write resources table */
for( i_index = 0; i_index < p_file->i_size; i_index++ )
{
memcpy( p_buffer, p_file->p_resource[i_index].psz_name, 32 );
*(u16 *)(p_buffer + 32) = p_file->p_resource[i_index].i_type;
*(u64 *)(p_buffer + 34) = p_file->p_resource[i_index].i_offset;
*(u64 *)(p_buffer + 42) = p_file->p_resource[i_index].i_size;
if( write( p_file->i_file, p_buffer, 8 ) != 8 )
{
intf_ErrMsg("rsc error 103-3: %s", strerror(errno));
return( -4 );
}
}
/* Mark file as up to date */
p_file->b_up_to_date = 1;
return( 0 );
}
/*****************************************************************************
* CloseResourceFile: close a resource file
*****************************************************************************
* Updates the resources table if required, and close the file. It returns non
* 0 in case of error.
*****************************************************************************
* Messages type: rsc, major code 104
*****************************************************************************/
int CloseResourceFile( resource_file_t *p_file )
{
/* Update table */
if( !p_file->b_up_to_date && ( UpdateResourceFile( p_file ) < 0 ) )
{
return( -1 );
}
/* Close and destroy descriptor */
if( close( p_file->i_file ) )
{
intf_ErrMsg("rsc error 104-1: %s", strerror(errno));
return( -2 );
}
free( p_file->p_resource );
free( p_file );
return( 0 );
}
/*****************************************************************************
* SeekResource: seek a resource in a resource file
*****************************************************************************
* Look for a resource in file and place the "reading head" at the beginning of
* the resource data.
* In case of success, the resource number is returned. Else, a negative number
* is returned.
*****************************************************************************
* Messages type: rsc, major code 105
*****************************************************************************/
int SeekResource( resource_file_t *p_file, char *psz_name, int i_type )
{
int i_index; /* resource index */
/* Look for resource in table */
for( i_index = 0;
(i_index < p_file->i_size)
&& ((i_type != p_file->p_resource[i_index].i_type )
|| strcmp(psz_name, p_file->p_resource[i_index].psz_name));
i_index++ )
{
;
}
if( i_index == p_file->i_size )
{
intf_ErrMsg("rsc error 105-1: unknown resource %s.%d", psz_name, i_type);
return( -1 );
}
/* Seek */
if( lseek( p_file->i_file, p_file->p_resource[i_index].i_offset, SEEK_SET ) )
{
intf_ErrMsg("rsc error 105-2: can not reach %s.%d: %s", psz_name,
i_type, strerror(errno));
return( -2 );
}
return( i_index );
}
/*****************************************************************************
* ReadResource: read a resource
*****************************************************************************
* Read a resource from a file. The function returns a negative value in case
* of error, and 0 in case of success.
*****************************************************************************
* Messages type: rsc, major code 106
*****************************************************************************/
int ReadResource( resource_file_t *p_file, char *psz_name, int i_type,
size_t max_size, byte_t *p_data )
{
int i_index; /* resource index */
/* Seek resource */
i_index = SeekResource( p_file, psz_name, i_type );
if( i_index < 0 )
{
return( -1 );
}
/* Check if buffer is large enough */
if( max_size < p_file->p_resource[i_index].i_size )
{
intf_ErrMsg("rsc error 106-1: buffer is too small");
return( -2 );
}
/* Read data */
if( read( p_file->i_file, p_data, p_file->p_resource[i_index].i_size )
!= p_file->p_resource[i_index].i_size )
{
intf_ErrMsg("rsc error 106-2: can not read %s.%d: %s",
p_file->p_resource[i_index].psz_name,
p_file->p_resource[i_index].i_type,
strerror(errno));
return( -3 );
}
return( 0 );
}
/*****************************************************************************
* WriteResource: write a resource
*****************************************************************************
* Append a resource at the end of the file. It returns non 0 on error.
*****************************************************************************
* Messages type: rsc, major code 107
*****************************************************************************/
/* Darwin port : namespace clash with Darwin's WriteResource */
int vlc_WriteResource( resource_file_t *p_file, char *psz_name, int i_type,
size_t size, byte_t *p_data )
{
int i_index; /* resource index */
int i_tmp_index; /* temporary resource index */
u64 i_offset; /* offset */
if( p_file->b_read_only )
{
intf_ErrMsg("rsc debug 107-1: can not write to a read-only resource file");
return( -1 );
}
/* Look for an empty place in the resources table */
i_index = -1;
i_offset = p_file->i_size * 50 + 8;
for( i_tmp_index = 0; i_tmp_index < p_file->i_size; i_tmp_index++ )
{
if( p_file->p_resource[i_tmp_index].i_type != EMPTY_RESOURCE)
{
i_offset = MAX( i_offset, p_file->p_resource[i_tmp_index].i_offset
+ p_file->p_resource[i_tmp_index].i_size );
}
else if( i_index == -1 )
{
i_index = i_tmp_index;
}
}
if( i_index == -1 )
{
intf_ErrMsg("rsc error 107-1: resources table is full");
return( -1 );
}
/* Seek end of file */
if( lseek( p_file->i_file, i_offset, SEEK_SET ) )
{
intf_ErrMsg("rsc error 107-2: %s", strerror(errno));
return( -2 );
}
/* Write data */
if( write( p_file->i_file, p_data, size ) != size )
{
intf_ErrMsg("rsc error 107-3: %s", strerror(errno));
return( -3 );
}
/* Update table */
strncpy( p_file->p_resource[i_index].psz_name, psz_name, RESOURCE_MAX_NAME );
p_file->p_resource[i_index].psz_name[RESOURCE_MAX_NAME] = '\0';
p_file->p_resource[i_index].i_type = i_type;
p_file->p_resource[i_index].i_offset = i_offset;
p_file->p_resource[i_index].i_size = size;
p_file->b_up_to_date = 0;
return( 0 );
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment