Commit 278bc72e authored by gbazin's avatar gbazin
Browse files

* This the last piece of the new configuration module. You can now save your
configuration options (only from the gtk/gnome interface for now). The config
file will be saved as ~/.VideoLan/vlc

It's not quite yet finished (well there are a few small details to sort out),
but I'm going away for the week-end and I wanted to commit this before so you
can all have a play with it :)
parent dffb93e1
This diff is collapsed.
......@@ -162,6 +162,7 @@ AC_CHECK_FUNCS(swab)
AC_CHECK_FUNCS([memalign valloc])
AC_CHECK_FUNCS(sigrelse)
AC_CHECK_FUNCS(getpwuid_r getpwuid)
dnl Check for getopt
NEED_GETOPT=0
......
......@@ -3,7 +3,7 @@
* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: common.h,v 1.85 2002/03/11 07:23:09 gbazin Exp $
* $Id: common.h,v 1.86 2002/03/16 01:40:58 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
......@@ -472,6 +472,8 @@ typedef struct module_symbols_s
char * ( * config_GetPszVariable ) ( const char * );
void ( * config_PutIntVariable ) ( const char *, int );
void ( * config_PutPszVariable ) ( const char *, char * );
int ( * config_LoadConfigFile ) ( const char * );
int ( * config_SaveConfigFile ) ( const char * );
struct module_config_s * ( * config_FindConfig ) ( const char * );
struct module_config_s * ( * config_Duplicate ) ( struct module_s * );
......
......@@ -4,7 +4,7 @@
* It includes functions allowing to declare, get or set configuration options.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: configuration.h,v 1.2 2002/03/11 07:23:09 gbazin Exp $
* $Id: configuration.h,v 1.3 2002/03/16 01:40:58 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -69,15 +69,20 @@ char * config_GetPszVariable( const char *psz_name );
void config_PutIntVariable( const char *psz_name, int i_value );
void config_PutPszVariable( const char *psz_name, char *psz_value );
int config_LoadConfigFile( const char *psz_module_name );
int config_SaveConfigFile( const char *psz_module_name );
module_config_t *config_FindConfig( const char *psz_name );
module_config_t *config_Duplicate ( module_t *p_module );
#else
# define config_GetIntVariable p_symbols->config_GetIntVariable
# define config_PutIntVariable p_symbols->config_PutIntVariable
# define config_GetPszVariable p_symbols->config_GetPszVariable
# define config_PutPszVariable p_symbols->config_PutPszVariable
# define config_Duplicate p_symbols->config_Duplicate
# define config_FindConfig p_symbols->config_FindConfig
# define config_Duplicate p_symbols->config_Duplicate
# define config_FindConfig p_symbols->config_FindConfig
# define config_LoadConfigFile p_symbols->config_LoadConfigFile
# define config_SaveConfigFile p_symbols->config_SaveConfigFile
#endif
/*****************************************************************************
......
......@@ -121,6 +121,12 @@
/* Define if you have the sigrelse function. */
#undef HAVE_SIGRELSE
/* Define if you have the getpwuid_r function. */
#undef HAVE_GETPWUID_R
/* Define if you have the getpwuid function. */
#undef HAVE_GETPWUID
/* Define if you have the stpcpy function. */
#undef HAVE_STPCPY
......
......@@ -3,7 +3,7 @@
* Declaration and extern access to global program object.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: main.h,v 1.31 2002/03/12 18:37:46 stef Exp $
* $Id: main.h,v 1.32 2002/03/16 01:40:58 gbazin Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
......@@ -63,6 +63,9 @@ typedef struct main_s
p_playlist_t p_playlist; /* playlist */
p_intf_msg_t p_msg; /* messages interface data */
p_input_channel_t p_channel; /* channel library data */
/* Locks */
vlc_mutex_t config_lock; /* lock for the config file */
} main_t;
#ifndef PLUGIN
......
......@@ -2,7 +2,7 @@
* gtk_preferences.c: functions to handle the preferences dialog box.
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: gtk_preferences.c,v 1.13 2002/03/11 20:14:16 gbazin Exp $
* $Id: gtk_preferences.c,v 1.14 2002/03/16 01:40:58 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -55,6 +55,7 @@ static void GtkCreateConfigDialog( char *, intf_thread_t * );
static void GtkConfigOk ( GtkButton *, gpointer );
static void GtkConfigApply ( GtkButton *, gpointer );
static void GtkConfigCancel ( GtkButton *, gpointer );
static void GtkConfigSave ( GtkButton *, gpointer );
static void GtkConfigDialogDestroyed ( GtkObject *, gpointer );
......@@ -102,6 +103,7 @@ static void GtkCreateConfigDialog( char *psz_module_name,
GtkWidget *dialog_action_area;
GtkWidget *ok_button;
GtkWidget *apply_button;
GtkWidget *save_button;
GtkWidget *cancel_button;
GtkWidget *item_frame;
......@@ -483,6 +485,11 @@ static void GtkCreateConfigDialog( char *psz_module_name,
gtk_box_pack_start( GTK_BOX(dialog_action_area), apply_button,
TRUE, TRUE, 0 );
save_button = gtk_button_new_with_label( _("Save") );
gtk_widget_show( save_button );
gtk_box_pack_start( GTK_BOX(dialog_action_area), save_button,
TRUE, TRUE, 0 );
cancel_button = gtk_button_new_with_label( _("Cancel") );
gtk_widget_show( cancel_button );
gtk_box_pack_start( GTK_BOX(dialog_action_area), cancel_button,
......@@ -494,6 +501,9 @@ static void GtkCreateConfigDialog( char *psz_module_name,
gtk_signal_connect( GTK_OBJECT(apply_button), "clicked",
GTK_SIGNAL_FUNC(GtkConfigApply),
config_dialog );
gtk_signal_connect( GTK_OBJECT(save_button), "clicked",
GTK_SIGNAL_FUNC(GtkConfigSave),
config_dialog );
gtk_signal_connect( GTK_OBJECT(cancel_button), "clicked",
GTK_SIGNAL_FUNC(GtkConfigCancel),
config_dialog );
......@@ -522,7 +532,6 @@ void GtkConfigApply( GtkButton * button, gpointer user_data )
hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
"config_hash_table" );
g_hash_table_foreach( hash_table, GtkSaveHashValue, NULL );
}
void GtkConfigOk( GtkButton * button, gpointer user_data )
......@@ -531,12 +540,17 @@ void GtkConfigOk( GtkButton * button, gpointer user_data )
gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
}
void GtkConfigCancel( GtkButton * button, gpointer user_data )
{
gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
}
void GtkConfigSave( GtkButton * button, gpointer user_data )
{
GtkConfigApply( button, user_data );
config_SaveConfigFile( NULL );
}
/****************************************************************************
* GtkPluginHighlighted: display plugin description when an entry is selected
* in the clist, and activate the configure button if necessary.
......
......@@ -4,7 +4,7 @@
* and spawn threads.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: main.c,v 1.163 2002/03/12 18:37:46 stef Exp $
* $Id: main.c,v 1.164 2002/03/16 01:40:58 gbazin Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -401,7 +401,6 @@ vout_bank_t *p_vout_bank;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int GetConfigurationFromFile ( void ){return 0;};
static int GetConfigurationFromCmdLine ( int *pi_argc, char *ppsz_argv[],
boolean_t b_ignore_errors );
static int GetFilenames ( int i_argc, char *ppsz_argv[] );
......@@ -604,11 +603,8 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
/*
* Override default configuration with config file settings
*/
if( GetConfigurationFromFile() )
{
intf_MsgDestroy();
return( errno );
}
vlc_mutex_init( &p_main->config_lock );
config_LoadConfigFile( NULL );
/*
* Override configuration with command line settings
......@@ -619,6 +615,7 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
return( errno );
}
/* p_main inititalization. FIXME ? */
p_main->i_desync = (mtime_t)config_GetIntVariable( "desync" )
* (mtime_t)1000;
......
......@@ -2,7 +2,7 @@
* configuration.c management of the modules configuration
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: configuration.c,v 1.3 2002/03/11 07:23:10 gbazin Exp $
* $Id: configuration.c,v 1.4 2002/03/16 01:40:58 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -20,13 +20,22 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <stdlib.h> /* free(), strtol() */
#include <stdio.h> /* sprintf() */
#include <stdlib.h> /* free(), strtol() */
#include <string.h> /* strdup() */
#include <unistd.h> /* getuid() */
#include <videolan/vlc.h>
#if defined(HAVE_GETPWUID) || defined(HAVE_GETPWUID_R)
#include <pwd.h> /* getpwuid() */
#endif
#include <sys/stat.h>
#include <sys/types.h>
static char *config_GetHomeDir(void);
/*****************************************************************************
* config_GetIntVariable: get the value of an int variable
*****************************************************************************
......@@ -252,3 +261,423 @@ module_config_t *config_Duplicate( module_t *p_module )
return p_config;
}
/*****************************************************************************
* config_LoadConfigFile: loads the configuration file.
*****************************************************************************
* This function is called to load the config options stored in the config
* file.
*****************************************************************************/
int config_LoadConfigFile( const char *psz_module_name )
{
module_t *p_module;
FILE *file;
char line[1024];
char *p_index, *psz_option_name, *psz_option_value;
int i;
char *psz_filename, *psz_homedir;
/* Acquire config file lock */
vlc_mutex_lock( &p_main->config_lock );
psz_homedir = config_GetHomeDir();
if( !psz_homedir )
{
intf_ErrMsg( "config_LoadConfigFile: GetHomeDir failed" );
vlc_mutex_unlock( &p_main->config_lock );
return -1;
}
psz_filename = (char *)malloc( strlen("/.VideoLan/vlc") +
strlen(psz_homedir) + 1 );
if( !psz_filename )
{
intf_ErrMsg( "config err: couldn't malloc psz_filename" );
free( psz_homedir );
vlc_mutex_unlock( &p_main->config_lock );
return -1;
}
sprintf( psz_filename, "%s/.VideoLan/vlc", psz_homedir );
free( psz_homedir );
intf_WarnMsg( 5, "config_SaveConfigFile: opening config file %s",
psz_filename );
file = fopen( psz_filename, "r" );
if( !file )
{
intf_WarnMsg( 1, "config_LoadConfigFile: couldn't open config file %s "
"for reading", psz_filename );
free( psz_filename );
vlc_mutex_unlock( &p_main->config_lock );
return -1;
}
/* Look for the selected module, if NULL then save everything */
for( p_module = p_module_bank->first ; p_module != NULL ;
p_module = p_module->next )
{
if( psz_module_name && strcmp( psz_module_name, p_module->psz_name ) )
continue;
/* The config file is organized in sections, one per module. Look for
* the interesting section ( a section is of the form [foo] ) */
rewind( file );
while( fgets( line, 1024, file ) )
{
if( (line[0] == '[') && (p_index = strchr(line,']')) &&
(p_index - &line[1] == strlen(p_module->psz_name) ) &&
!memcmp( &line[1], p_module->psz_name,
strlen(p_module->psz_name) ) )
{
intf_WarnMsg( 5, "config_LoadConfigFile: loading config for "
"module <%s>", p_module->psz_name );
break;
}
}
/* either we found the section or we're at the EOF */
/* Now try to load the options in this section */
while( fgets( line, 1024, file ) )
{
if( line[0] == '[' ) break; /* end of section */
/* ignore comments or empty lines */
if( (line[0] == '#') || (line[0] == (char)0) ) continue;
/* get rid of line feed */
if( line[strlen(line)-1] == '\n' )
line[strlen(line)-1] = (char)0;
/* look for option name */
psz_option_name = line;
psz_option_value = NULL;
p_index = strchr( line, '=' );
if( !p_index ) break; /* this ain't an option!!! */
*p_index = (char)0;
psz_option_value = p_index + 1;
/* try to match this option with one of the module's options */
for( i = 0; i < p_module->i_config_lines; i++ )
{
if( p_module->p_config[i].i_type & MODULE_CONFIG_HINT )
/* ignore hints */
continue;
if( !strcmp( p_module->p_config[i].psz_name,
psz_option_name ) )
{
/* We found it */
switch( p_module->p_config[i].i_type )
{
case MODULE_CONFIG_ITEM_BOOL:
case MODULE_CONFIG_ITEM_INTEGER:
p_module->p_config[i].i_value =
atoi( psz_option_value);
intf_WarnMsg( 7, "config_LoadConfigFile: found <%s> "
"option %s=%i",
p_module->psz_name,
p_module->p_config[i].psz_name,
p_module->p_config[i].i_value );
break;
default:
vlc_mutex_lock( p_module->p_config[i].p_lock );
/* free old string */
if( p_module->p_config[i].psz_value )
free( p_module->p_config[i].psz_value );
p_module->p_config[i].psz_value =
strdup( psz_option_value );
vlc_mutex_unlock( p_module->p_config[i].p_lock );
intf_WarnMsg( 7, "config_LoadConfigFile: found <%s> "
"option %s=%s",
p_module->psz_name,
p_module->p_config[i].psz_name,
p_module->p_config[i].psz_value );
break;
}
}
}
}
}
fclose( file );
free( psz_filename );
vlc_mutex_unlock( &p_main->config_lock );
return 0;
}
/*****************************************************************************
* config_SaveConfigFile: Save a module's config options.
*****************************************************************************
* This will save the specified module's config options to the config file.
* If psz_module_name is NULL then we save all the modules config options.
* It's no use to save the config options that kept their default values, so
* we'll try to be a bit clever here.
*
* When we save we mustn't delete the config options of the plugins that
* haven't been loaded. So we cannot just create a new config file with the
* config structures we've got in memory.
* I don't really know how to deal with this nicely, so I will use a completly
* dumb method ;-)
* I will load the config file in memory, but skipping all the sections of the
* modules we want to save. Then I will create a brand new file, dump the file
* loaded in memory and then append the sections of the modules we want to
* save.
* Really stupid no ?
*****************************************************************************/
int config_SaveConfigFile( const char *psz_module_name )
{
module_t *p_module;
FILE *file;
char p_line[1024], *p_index2;
int i, i_sizebuf = 0;
char *p_bigbuffer, *p_index;
boolean_t b_backup;
char *psz_filename, *psz_homedir;
/* Acquire config file lock */
vlc_mutex_lock( &p_main->config_lock );
psz_homedir = config_GetHomeDir();
if( !psz_homedir )
{
intf_ErrMsg( "config_SaveConfigFile: GetHomeDir failed" );
vlc_mutex_unlock( &p_main->config_lock );
return -1;
}
psz_filename = (char *)malloc( strlen("/.VideoLan/vlc") +
strlen(psz_homedir) + 1 );
if( !psz_filename )
{
intf_ErrMsg( "config err: couldn't malloc psz_filename" );
free( psz_homedir );
vlc_mutex_unlock( &p_main->config_lock );
return -1;
}
sprintf( psz_filename, "%s/.VideoLan", psz_homedir );
free( psz_homedir );
#ifndef WIN32
mkdir( psz_filename, 0755 );
#else
mkdir( psz_filename );
#endif
strcat( psz_filename, "/vlc" );
intf_WarnMsg( 5, "config_SaveConfigFile: opening config file %s",
psz_filename );
file = fopen( psz_filename, "r" );
if( !file )
{
intf_WarnMsg( 1, "config_SaveConfigFile: couldn't open config file %s "
"for reading", psz_filename );
}
else
{
/* look for file size */
fseek( file, 0, SEEK_END );
i_sizebuf = ftell( file );
rewind( file );
}
p_bigbuffer = p_index = malloc( i_sizebuf+1 );
if( !p_bigbuffer )
{
intf_ErrMsg( "config err: couldn't malloc bigbuffer" );
if( file ) fclose( file );
free( psz_filename );
vlc_mutex_unlock( &p_main->config_lock );
return -1;
}
p_bigbuffer[0] = 0;
/* backup file into memory, we only need to backup the sections we won't
* save later on */
b_backup = 0;
while( file && fgets( p_line, 1024, file ) )
{
if( (p_line[0] == '[') && (p_index2 = strchr(p_line,']')))
{
/* we found a section, check if we need to do a backup */
for( p_module = p_module_bank->first; p_module != NULL;
p_module = p_module->next )
{
if( ((p_index2 - &p_line[1]) == strlen(p_module->psz_name) ) &&
!memcmp( &p_line[1], p_module->psz_name,
strlen(p_module->psz_name) ) )
{
if( !psz_module_name )
break;
else if( !strcmp( psz_module_name, p_module->psz_name ) )
break;
}
}
if( !p_module )
{
/* we don't have this section in our list so we need to back
* it up */
*p_index2 = 0;
intf_WarnMsg( 5, "config_SaveConfigFile: backing up config for"
" unknown module <%s>", &p_line[1] );
*p_index2 = ']';
b_backup = 1;
}
else
{
b_backup = 0;
}
}
/* save line if requested and line is valid (doesn't begin with a
* space, tab, or eol) */
if( b_backup && (p_line[0] != '\n') && (p_line[0] != ' ')
&& (p_line[0] != '\t') )
{
strcpy( p_index, p_line );
p_index += strlen( p_line );
}
}
if( file ) fclose( file );
/*
* Save module config in file
*/
file = fopen( psz_filename, "w" );
if( !file )
{
intf_WarnMsg( 1, "config_SaveConfigFile: couldn't open config file %s "
"for writing", psz_filename );
free( psz_filename );
vlc_mutex_unlock( &p_main->config_lock );
return -1;
}
fprintf( file, "#\n# "COPYRIGHT_MESSAGE"\n#\n\n" );
/* Look for the selected module, if NULL then save everything */
for( p_module = p_module_bank->first ; p_module != NULL ;
p_module = p_module->next )
{
if( psz_module_name && strcmp( psz_module_name, p_module->psz_name ) )
continue;
if( !p_module->i_config_items )
continue;
intf_WarnMsg( 5, "config_SaveConfigFile: saving config for "
"module <%s>", p_module->psz_name );
fprintf( file, "[%s]\n", p_module->psz_name );
if( p_module->psz_longname )
fprintf( file, "# %s\n#\n", p_module->psz_longname );
for( i = 0; i < p_module->i_config_lines; i++ )
{
if( p_module->p_config[i].i_type & MODULE_CONFIG_HINT )
/* ignore hints */
continue;
switch( p_module->p_config[i].i_type )
{
case MODULE_CONFIG_ITEM_BOOL:
case MODULE_CONFIG_ITEM_INTEGER:
if( p_module->p_config[i].psz_text )
fprintf( file, "# %s\n", p_module->p_config[i].psz_text );
fprintf( file, "%s=%i\n", p_module->p_config[i].psz_name,
p_module->p_config[i].i_value );
break;
default:
if( p_module->p_config[i].psz_value )
{
if( p_module->p_config[i].psz_text )
fprintf( file, "# %s\n",
p_module->p_config[i].psz_text );
fprintf( file, "%s=%s\n", p_module->p_config[i].psz_name,
p_module->p_config[i].psz_value );
}
}
}
fprintf( file, "\n" );
}
/*
* Restore old settings from the config in file
*/
fputs( p_bigbuffer, file );
free( p_bigbuffer );
fclose( file );
free( psz_filename );
vlc_mutex_unlock( &p_main->config_lock );
return 0;
}
/*****************************************************************************
* config_GetHomeDir: find the user's home directory.
*****************************************************************************
* This function will try by different ways to find the user's home path.
*****************************************************************************/