⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 theme_loader.cpp

📁 uclinux 下的vlc播放器源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * theme_loader.cpp ***************************************************************************** * Copyright (C) 2003 the VideoLAN team * $Id: theme_loader.cpp 19663 2007-04-04 14:21:33Z lool $ * * Authors: Cyril Deguet     <asmax@via.ecp.fr> *          Olivier Teulière <ipkiss@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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/#include "theme_loader.hpp"#include "theme.hpp"#include "../parser/builder.hpp"#include "../parser/skin_parser.hpp"#include "../src/os_factory.hpp"#include "../src/vlcproc.hpp"#include "../src/window_manager.hpp"#include <cctype>#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>#elif defined( WIN32 ) && !defined( UNDER_CE )#   include <direct.h>#endif#ifdef HAVE_DIRENT_H#   include <dirent.h>#endif#if defined( HAVE_ZLIB_H )#   include <zlib.h>#   include <errno.h>int gzopen_frontend ( char *pathname, int oflags, int mode );int gzclose_frontend( int );int gzread_frontend ( int, void *, size_t );int gzwrite_frontend( int, const void *, size_t );#if defined( HAVE_LIBTAR_H )#   include <libtar.h>#elsetypedef gzFile TAR;int tar_open        ( TAR **t, char *pathname, int oflags );int tar_extract_all ( TAR *t, char *prefix );int tar_close       ( TAR *t );int getoct( char *p, int width );#endifint makedir( const char *newdir );#endif#define DEFAULT_XML_FILE "theme.xml"#define WINAMP2_XML_FILE "winamp2.xml"#define ZIP_BUFFER_SIZE 4096bool ThemeLoader::load( const string &fileName ){    // First, we try to un-targz the file, and if it fails we hope it's a XML    // file...    string path = getFilePath( fileName );#if defined( HAVE_ZLIB_H )    if( ! extract( sToLocale( fileName ) ) && ! parse( path, fileName ) )        return false;#else    if( ! parse( path, fileName ) )        return false;#endif    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(), "skins2-last" );    if( skin_last != NULL && fileName == (string)skin_last )    {        // 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(), "skins2-last", fileName.c_str() );        // Show the windows        pNewTheme->getWindowManager().showAll( true );    }    if( skin_last ) free( skin_last );    // The new theme cannot embed a video output yet    VlcProc::instance( getIntf() )->dropVout();    return true;}#if defined( HAVE_ZLIB_H )bool ThemeLoader::extractTarGz( const string &tarFile, const string &rootDir ){    TAR *t;#if defined( HAVE_LIBTAR_H )    tartype_t gztype = { (openfunc_t) gzopen_frontend,                         (closefunc_t) gzclose_frontend,                         (readfunc_t) gzread_frontend,                         (writefunc_t) gzwrite_frontend };    if( tar_open( &t, (char *)tarFile.c_str(), &gztype, O_RDONLY, 0,                  TAR_GNU ) == -1 )#else    if( tar_open( &t, (char *)tarFile.c_str(), O_RDONLY ) == -1 )#endif    {        return false;    }    if( tar_extract_all( t, (char *)rootDir.c_str() ) != 0 )    {        tar_close( t );        return false;    }    if( tar_close( t ) != 0 )    {        return false;    }    return true;}bool ThemeLoader::extractZip( const string &zipFile, const string &rootDir ){    // Try to open the ZIP file    unzFile file = unzOpen( zipFile.c_str() );    unz_global_info info;    if( unzGetGlobalInfo( file, &info ) != UNZ_OK )    {        return false;    }    // Extract all the files in the archive    for( unsigned long i = 0; i < info.number_entry; i++ )    {        if( !extractFileInZip( file, rootDir ) )        {            msg_Warn( getIntf(), "error while unzipping %s",                      zipFile.c_str() );            unzClose( file );            return false;        }        if( i < info.number_entry - 1 )        {            // Go the next file in the archive            if( unzGoToNextFile( file ) !=UNZ_OK )            {                msg_Warn( getIntf(), "error while unzipping %s",                          zipFile.c_str() );                unzClose( file );                return false;            }        }    }    unzClose( file );    return true;}bool ThemeLoader::extractFileInZip( unzFile file, const string &rootDir ){    // Read info for the current file    char filenameInZip[256];    unz_file_info fileInfo;    if( unzGetCurrentFileInfo( file, &fileInfo, filenameInZip,                               sizeof( filenameInZip), NULL, 0, NULL, 0 )        != UNZ_OK )    {        return false;    }    // Convert the file name to lower case, because some winamp skins    // use the wrong case...    for( size_t i=0; i< strlen( filenameInZip ); i++)    {        filenameInZip[i] = tolower( filenameInZip[i] );    }    // Allocate the buffer    void *pBuffer = malloc( ZIP_BUFFER_SIZE );    if( !pBuffer )    {        msg_Err( getIntf(), "failed to allocate memory" );        return false;    }    // Get the path of the file    OSFactory *pOsFactory = OSFactory::instance( getIntf() );    string fullPath = rootDir        + pOsFactory->getDirSeparator()        + fixDirSeparators( filenameInZip );    string basePath = getFilePath( fullPath );    // Extract the file if is not a directory    if( basePath != fullPath )    {        if( unzOpenCurrentFile( file ) )        {            free( pBuffer );            return false;        }        makedir( basePath.c_str() );        FILE *fout = fopen( fullPath.c_str(), "wb" );        if( fout == NULL )        {            msg_Err( getIntf(), "error opening %s", fullPath.c_str() );            free( pBuffer );            return false;        }        // Extract the current file        int n;        do        {            n = unzReadCurrentFile( file, pBuffer, ZIP_BUFFER_SIZE );            if( n < 0 )            {                msg_Err( getIntf(), "error while reading zip file" );                free( pBuffer );                return false;            }            else if( n > 0 )            {                if( fwrite( pBuffer, n , 1, fout) != 1 )                {                    msg_Err( getIntf(), "error while writing %s",                             fullPath.c_str() );                    free( pBuffer );                    return false;                }            }        } while( n > 0 );        fclose(fout);        if( unzCloseCurrentFile( file ) != UNZ_OK )        {            free( pBuffer );            return false;        }    }    free( pBuffer );    return true;}bool ThemeLoader::extract( const string &fileName ){    bool result = true;    char *tmpdir = tempnam( NULL, "vlt" );    string tempPath = tmpdir;    free( tmpdir );    // Extract the file in a temporary directory    if( ! extractTarGz( fileName, tempPath ) &&        ! extractZip( fileName, tempPath ) )    {        deleteTempFiles( tempPath );        return false;    }    string path;    string xmlFile;    OSFactory *pOsFactory = OSFactory::instance( getIntf() );    // Find the XML file in the theme    if( findFile( tempPath, DEFAULT_XML_FILE, xmlFile ) )    {        path = getFilePath( xmlFile );    }    else    {        // No XML file, check if it is a winamp2 skin        string mainBmp;        if( findFile( tempPath, "main.bmp", mainBmp ) )        {            msg_Dbg( getIntf(), "trying to load a winamp2 skin" );            path = getFilePath( mainBmp );            // Look for winamp2.xml in the resource path            list<string> resPath = pOsFactory->getResourcePath();            list<string>::const_iterator it;            for( it = resPath.begin(); it != resPath.end(); it++ )            {                if( findFile( sToLocale( *it ), WINAMP2_XML_FILE, xmlFile ) )                    break;            }        }    }    if( !xmlFile.empty() )    {        // Parse the XML file        if (! parse( path, xmlFile ) )        {            msg_Err( getIntf(), "error while parsing %s", xmlFile.c_str() );            result = false;        }    }    else    {        msg_Err( getIntf(), "no XML found in theme %s", fileName.c_str() );        result = false;    }    // Clean-up    deleteTempFiles( tempPath );    return result;}void ThemeLoader::deleteTempFiles( const string &path ){    OSFactory::instance( getIntf() )->rmDir( path );}#endif // HAVE_ZLIB_Hbool ThemeLoader::parse( const string &path, const string &xmlFile ){    // File loaded    msg_Dbg( getIntf(), "using skin file: %s", xmlFile.c_str() );    // Start the parser    SkinParser parser( getIntf(), xmlFile, path );    if( ! parser.parse() )    {        msg_Err( getIntf(), "failed to parse %s", xmlFile.c_str() );        return false;    }    // Build and store the theme    Builder builder( getIntf(), parser.getData(), path );    getIntf()->p_sys->p_theme = builder.build();    return true;}string ThemeLoader::getFilePath( const string &rFullPath ){    OSFactory *pOsFactory = OSFactory::instance( getIntf() );    const string &sep = pOsFactory->getDirSeparator();    // Find the last separator ('/' or '\')    string::size_type p = rFullPath.rfind( sep, rFullPath.size() );    string basePath;    if( p != string::npos )    {        if( p < rFullPath.size() - 1)        {            basePath = rFullPath.substr( 0, p );        }        else        {            basePath = rFullPath;        }    }    return basePath;}string ThemeLoader::fixDirSeparators( const string &rPath ){    OSFactory *pOsFactory = OSFactory::instance( getIntf() );    const string &sep = pOsFactory->getDirSeparator();    string::size_type p = rPath.find( "/", 0 );    string newPath = rPath;    while( p != string::npos )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -