#endif
#define DEFAULT_XML_FILE "theme.xml"
+#define WINAMP2_XML_FILE "winamp2.xml"
#define ZIP_BUFFER_SIZE 4096
{
// 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( fileName ) && ! parse( fileName ) )
+ if( ! extract( fileName ) && ! parse( path, fileName ) )
return false;
#else
- if( ! parse( fileName ) )
+ if( ! parse( path, fileName ) )
return false;
#endif
// Get the path of the file
string fullPath = rootDir + "/" + filenameInZip;
- string::size_type pos = fullPath.rfind( '/' );
- string basePath;
- if( pos != string::npos )
- {
- if( pos < fullPath.size() - 1)
- {
- basePath = fullPath.substr( 0, pos );
- }
- else
- {
- basePath = fullPath;
- }
- }
+ string basePath = getFilePath( fullPath );
// Extract the file if is not a directory
- if( pos != fullPath.size() - 1 )
+ if( basePath != fullPath )
{
if( unzOpenCurrentFile( file ) )
{
bool ThemeLoader::extract( const string &fileName )
{
+ bool result = true;
char *tmpdir = tempnam( NULL, "vlt" );
string tempPath = tmpdir;
free( tmpdir );
! extractZip( fileName, tempPath ) )
return false;
- // Find the XML file and parse it
+ string path;
string xmlFile;
- if( ! findThemeFile( tempPath, xmlFile ) || ! parse( xmlFile ) )
+ OSFactory *pOsFactory = OSFactory::instance( getIntf() );
+ // Find the XML file in the theme
+ if( findFile( tempPath, DEFAULT_XML_FILE, xmlFile ) )
{
- msg_Err( getIntf(), "%s doesn't contain a " DEFAULT_XML_FILE " file",
- fileName.c_str() );
- deleteTempFiles( tempPath );
- return false;
+ path = getFilePath( xmlFile );
+ }
+ else
+ {
+ // No XML file, assume it is a winamp2 skin
+ path = tempPath;
+
+ // 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( *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 true;
+ return result;
}
#endif // HAVE_ZLIB_H
-bool ThemeLoader::parse( const string &xmlFile )
+bool ThemeLoader::parse( const string &path, const string &xmlFile )
{
// File loaded
msg_Dbg( getIntf(), "Using skin file: %s", xmlFile.c_str() );
- // Extract the path of the XML file
- string path;
- const string &sep = OSFactory::instance( getIntf() )->getDirSeparator();
- string::size_type p = xmlFile.rfind( sep, xmlFile.size() );
- if( p != string::npos )
- {
- path = xmlFile.substr( 0, p + 1 );
- }
- else
- {
- path = "";
- }
-
// Start the parser
SkinParser parser( getIntf(), xmlFile, path );
if( ! parser.parse() )
}
-bool ThemeLoader::findThemeFile( const string &rootDir, string &themeFilePath )
+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;
+}
+
+
+bool ThemeLoader::findFile( const string &rootDir, const string &rFileName,
+ string &themeFilePath )
{
// Path separator
const string &sep = OSFactory::instance( getIntf() )->getDirSeparator();
if( 0 )
#endif
{
- // Can we find the theme file in this subdirectory?
- if( findThemeFile( newURI, themeFilePath ) )
+ // Can we find the file in this subdirectory?
+ if( findFile( newURI, rFileName, themeFilePath ) )
{
closedir( pCurrDir );
return true;
else
{
// Found the theme file?
- if( string( DEFAULT_XML_FILE ) ==
- string( pDirContent->d_name ) )
+ if( rFileName == string( pDirContent->d_name ) )
{
themeFilePath = newURI;
closedir( pCurrDir );
--- /dev/null
+<!DOCTYPE Theme PUBLIC "-//VideoLAN//DTD VLC Skins V2.0//EN" "skins.dtd">
+
+<Theme version="2.0" magnet="9" alpha="255">
+ <ThemeInfo name="Winamp2" author="Cyril Deguet"/>
+
+ <Bitmap id="main" file="main.bmp" alphacolor="#FF0000" />
+ <Bitmap id="cbuttons" file="cbuttons.bmp" alphacolor="#FF0000">
+ <SubBitmap id="previous_up" x="0" y="0" width="23" height="18" />
+ <SubBitmap id="previous_down" x="0" y="18" width="23" height="18" />
+ <SubBitmap id="play_up" x="23" y="0" width="23" height="18" />
+ <SubBitmap id="play_down" x="23" y="18" width="23" height="18" />
+ <SubBitmap id="pause_up" x="46" y="0" width="23" height="18" />
+ <SubBitmap id="pause_down" x="46" y="18" width="23" height="18" />
+ <SubBitmap id="stop_up" x="69" y="0" width="23" height="18" />
+ <SubBitmap id="stop_down" x="69" y="18" width="23" height="18" />
+ <SubBitmap id="next_up" x="92" y="0" width="22" height="18" />
+ <SubBitmap id="next_down" x="92" y="18" width="22" height="18" />
+ <SubBitmap id="eject_up" x="114" y="0" width="22" height="16" />
+ <SubBitmap id="eject_down" x="114" y="16" width="22" height="16" />
+ </Bitmap>
+ <Bitmap id="titlebar" file="titlebar.bmp" alphacolor="#FF0000" >
+ <SubBitmap id="quit_up" x="18" y="0" width="9" height="9" />
+ <SubBitmap id="quit_down" x="18" y="9" width="9" height="9" />
+ </Bitmap>
+ <BitmapFont id="digits_font" file="nums_ex.bmp" type="digits"/>
+ <BitmapFont id="text_font" file="text.bmp" type="text"/>
+
+ <Window id="mainWindow" x="400" y="50">
+ <Layout id="bigLayout" width="275" height="116">
+ <Group x="0" y="0">
+ <Image x="0" y="0" image="main" action="move" />
+ <Text font="digits_font" x="30" y="26" width="75" text="$T"/>
+ <Text font="text_font" x="111" y="27" width="155" text="$N"/>
+ <Button x="263" y="3" up="quit_up" down="quit_down" over="quit_up" action="vlc.quit()" tooltiptext="Quit" />
+ <Button x="16" y="88" up="previous_up" down="previous_down" action="playlist.previous()" tooltiptext="Previous" />
+ <Button x="39" y="88" up="play_up" down="play_down" action="vlc.play()" tooltiptext="Play" />
+ <Button x="62" y="88" up="pause_up" down="pause_down" action="vlc.pause()" tooltiptext="Pause" />
+ <Button x="85" y="88" up="stop_up" down="stop_down" action="vlc.stop()" tooltiptext="Stop" />
+ <Button x="108" y="88" up="next_up" down="next_down" action="playlist.next()" tooltiptext="Next" />
+ <Button x="136" y="88" up="eject_up" down="eject_down" action="dialogs.fileSimple()" tooltiptext="Open" />
+ </Group>
+ </Layout>
+ </Window>
+
+</Theme>