* theme_loader.cpp
*****************************************************************************
* Copyright (C) 2003 VideoLAN
- * $Id: theme_loader.cpp,v 1.1 2004/01/03 23:31:34 asmax Exp $
+ * $Id$
*
* Authors: Cyril Deguet <asmax@via.ecp.fr>
* Olivier Teulière <ipkiss@via.ecp.fr>
#include "theme_loader.hpp"
#include "theme.hpp"
#include "../parser/builder.hpp"
-#include "../parser/parser_context.hpp"
+#include "../parser/skin_parser.hpp"
#include "../src/os_factory.hpp"
+#include "../src/vlcproc.hpp"
#include "../src/window_manager.hpp"
-#include <fcntl.h>
-#if !defined( WIN32 )
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
# include <unistd.h>
-#else
+#elif defined( WIN32 )
# include <direct.h>
#endif
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+#endif
+
#if defined( HAVE_ZLIB_H )
# include <zlib.h>
#define DEFAULT_XML_FILE "theme.xml"
-extern "C"
-{
- extern FILE *yyin;
- int yylex( void *pContext );
-}
bool ThemeLoader::load( const string &fileName )
{
return false;
#endif
-#if 0
+ Theme *pNewTheme = getIntf()->p_sys->p_theme;
+ if( !pNewTheme )
+ {
+ return false;
+ }
+
// Check if the skin to load is in the config file, to load its config
- char *skin_last = config_GetPsz( getIntf(), "skin_last" );
+ char *skin_last = config_GetPsz( getIntf(), "skins2-last" );
if( skin_last != NULL && fileName == (string)skin_last )
{
- getIntf()->p_sys->p_theme->LoadConfig();
+ // Restore the theme configuration
+ getIntf()->p_sys->p_theme->loadConfig();
+ // Used to anchor the windows at the beginning
+ pNewTheme->getWindowManager().stopMove();
}
else
{
- config_PutPsz( getIntf(), "skin_last", fileName.c_str() );
- config_SaveConfigFile( getIntf(), "skins" );
- }
-#endif
- Theme *pNewTheme = getIntf()->p_sys->p_theme;
- if( pNewTheme )
- {
- // Used to anchor the windows at the beginning
- pNewTheme->getWindowManager().stopMove();
+ config_PutPsz( getIntf(), "skins2-last", fileName.c_str() );
// Show the windows
pNewTheme->getWindowManager().showAll();
}
+ if( skin_last ) free( skin_last );
+
+ // The new theme cannot embed a video output yet
+ VlcProc::instance( getIntf() )->dropVout();
return true;
}
if( ! extractTarGz( fileName, tempPath ) )
return false;
- // Parse the extracted XML file
- const string &sep = OSFactory::instance( getIntf() )->getDirSeparator();
- if( ! parse( tempPath + sep + string( DEFAULT_XML_FILE ) ) )
+ // Find the XML file and parse it
+ string xmlFile;
+ if( ! findThemeFile( tempPath, xmlFile ) || ! parse( xmlFile ) )
{
msg_Err( getIntf(), "%s doesn't contain a " DEFAULT_XML_FILE " file",
fileName.c_str() );
bool ThemeLoader::parse( const string &xmlFile )
{
- // Things to do before loading theme
-// getIntf()->p_sys->p_theme->OnLoadTheme();
- // Set the file to parse
- yyin = fopen( xmlFile.c_str(), "r" );
- if( yyin == NULL )
- {
- // Skin cannot be opened
- msg_Err( getIntf(), "Cannot open the specified skin file: %s",
- xmlFile.c_str() );
- return false;
- }
-
// File loaded
msg_Dbg( getIntf(), "Using skin file: %s", xmlFile.c_str() );
- // Save current working directory
- char *cwd = new char[PATH_MAX];
- getcwd( cwd, PATH_MAX );
-
- // Change current working directory to xml file
+ // Extract the path of the XML file
+ string path;
const string &sep = OSFactory::instance( getIntf() )->getDirSeparator();
- unsigned int p = xmlFile.rfind( sep, xmlFile.size() );
+ string::size_type p = xmlFile.rfind( sep, xmlFile.size() );
if( p != string::npos )
{
- string path = xmlFile.substr( 0, p );
- chdir( path.c_str() );
+ path = xmlFile.substr( 0, p + 1 );
+ }
+ else
+ {
+ path = "";
}
// Start the parser
- ParserContext context( getIntf() );
- int lex = yylex( &context );
- fclose( yyin );
-
- if( lex )
+ SkinParser parser( getIntf(), xmlFile, path );
+ if( ! parser.parse() )
{
- // Set old working directory to current
- chdir( cwd );
- delete[] cwd;
-
- msg_Warn( getIntf(), "yylex failed: %i", lex );
+ msg_Err( getIntf(), "Failed to parse %s", xmlFile.c_str() );
return false;
}
// Build and store the theme
- Builder builder( getIntf(), context.m_data );
+ Builder builder( getIntf(), parser.getData() );
getIntf()->p_sys->p_theme = builder.build();
- // Set old working directory to current.
- // We need to do that _after_ calling Builder:build(), otherwise the
- // opening of the files will fail
- chdir( cwd );
- delete[] cwd;
-
return true;
}
+bool ThemeLoader::findThemeFile( const string &rootDir, string &themeFilePath )
+{
+ // Path separator
+ const string &sep = OSFactory::instance( getIntf() )->getDirSeparator();
+
+ DIR *pCurrDir;
+ struct dirent *pDirContent;
+
+ // Open the dir
+ pCurrDir = opendir( rootDir.c_str() );
+
+ if( pCurrDir == NULL )
+ {
+ // An error occurred
+ msg_Dbg( getIntf(), "Cannot open directory %s", rootDir.c_str() );
+ return false;
+ }
+
+ // Get the first directory entry
+ pDirContent = readdir( pCurrDir );
+
+ // While we still have entries in the directory
+ while( pDirContent != NULL )
+ {
+ string newURI = rootDir + sep + pDirContent->d_name;
+
+ // Skip . and ..
+ if( string( pDirContent->d_name ) != "." &&
+ string( pDirContent->d_name ) != ".." )
+ {
+#if defined( S_ISDIR )
+ struct stat stat_data;
+ stat( newURI.c_str(), &stat_data );
+ if( S_ISDIR(stat_data.st_mode) )
+#elif defined( DT_DIR )
+ if( pDirContent->d_type & DT_DIR )
+#else
+ if( 0 )
+#endif
+ {
+ // Can we find the theme file in this subdirectory?
+ if( findThemeFile( newURI, themeFilePath ) )
+ {
+ closedir( pCurrDir );
+ return true;
+ }
+ }
+ else
+ {
+ // Found the theme file?
+ if( string( DEFAULT_XML_FILE ) ==
+ string( pDirContent->d_name ) )
+ {
+ themeFilePath = newURI;
+ closedir( pCurrDir );
+ return true;
+ }
+ }
+ }
+
+ pDirContent = readdir( pCurrDir );
+ }
+
+ closedir( pCurrDir );
+ return false;
+}
+
+
#if !defined( HAVE_LIBTAR_H ) && defined( HAVE_ZLIB_H )
#ifdef WIN32
free( buffer );
return 1;
}
+#endif
+#ifdef HAVE_ZLIB_H
int gzopen_frontend( char *pathname, int oflags, int mode )
{
char *gzflags;
return (int)gzf;
}
-
#endif