]> git.sesse.net Git - vlc/blobdiff - modules/gui/skins2/src/theme_loader.cpp
Quick patch to make pda.c inteface compile again. It disables the management of the...
[vlc] / modules / gui / skins2 / src / theme_loader.cpp
old mode 100755 (executable)
new mode 100644 (file)
index 3741faa..0295a6d
@@ -2,7 +2,7 @@
  * 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>
@@ -53,11 +63,6 @@ int tar_close       ( TAR *t );
 
 #define DEFAULT_XML_FILE "theme.xml"
 
-extern "C"
-{
-    extern FILE *yyin;
-    int yylex( void *pContext );
-}
 
 bool ThemeLoader::load( const string &fileName )
 {
@@ -71,27 +76,31 @@ 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;
 }
@@ -139,9 +148,9 @@ bool ThemeLoader::extract( const string &fileName )
     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() );
@@ -164,63 +173,106 @@ void ThemeLoader::deleteTempFiles( const string &path )
 
 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
@@ -475,7 +527,9 @@ int makedir( char *newdir )
     free( buffer );
     return 1;
 }
+#endif
 
+#ifdef HAVE_ZLIB_H
 int gzopen_frontend( char *pathname, int oflags, int mode )
 {
     char *gzflags;
@@ -504,5 +558,4 @@ int gzopen_frontend( char *pathname, int oflags, int mode )
 
     return (int)gzf;
 }
-
 #endif