www.pudn.com > MP3CORD.rar > player.cpp


/*____________________________________________________________________________ 
         
        FreeAmp - The Free MP3 Player 
 
        Portions Copyright (C) 1998-1999 EMusic.com 
 
        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., 675 Mass Ave, Cambridge, MA 02139, USA. 
         
        $Id: player.cpp,v 1.172 2000/01/20 00:48:45 robert Exp $ 
____________________________________________________________________________*/ 
 
#include  
#include  
#include  
#include  
#include  
#include   
#ifdef WIN32 
#include  
#define MKDIR(z) mkdir(z) 
#else 
#define MKDIR(z) mkdir(z, 0755) 
#endif 
 
#include "config.h" 
#include "event.h" 
#include "lmc.h" 
#include "player.h" 
#include "thread.h" 
#include "debug.h" 
#include "ui.h" 
#include "queue.h" 
#include "semaphore.h" 
#include "eventdata.h" 
#include "registrar.h" 
#include "preferences.h" 
#include "properties.h" 
#include "facontext.h" 
#include "log.h" 
#include "pmo.h" 
#include "utility.h" 
#include "downloadmanager.h" 
 
#define DB Debug_v("%s:%d\n", __FILE__, __LINE__); 
 
Player   *Player::m_thePlayer = NULL; 
 
const char *szPlaylistExt = ".M3U"; 
const char *themeExtension = "fat"; 
 
#define SEND_NORMAL_EVENT(e) { Event *ev = new Event(e); GetUIManipLock();    \ 
                               SendToUI(ev); ReleaseUIManipLock(); delete ev; \ 
                             } 
 
 
Player * 
Player:: 
GetPlayer(FAContext *context) 
{ 
    if (m_thePlayer == NULL) 
        m_thePlayer = new Player(context); 
    return m_thePlayer; 
} 
 
Player:: 
Player(FAContext *context): 
EventQueue() 
{ 
    m_context = context; 
    m_context->player = this; 
    // cout << "Creating player..." << endl; 
    m_eventSem = new Semaphore(); 
    m_eventQueue = new Queue < Event * >(); 
    // cout << "Created queue" << endl; 
    m_eventServiceThread = NULL; 
    // cout << "Started event thread" << endl; 
    m_uiList = new vector < UserInterface * >; 
    // cout << "Created Lists" << endl; 
    m_uiManipLock = new Mutex(); 
    m_lmcMutex = new Mutex(); 
    m_pmiMutex = new Mutex(); 
    m_pmoMutex = new Mutex(); 
    m_uiMutex = new Mutex(); 
    // cout << "Created mutex" << endl; 
    m_imQuitting = 0; 
    m_quitWaitingFor = 0; 
    m_plm = new PlaylistManager(m_context); 
    m_playerState = PlayerState_Stopped; 
 
    m_lmcRegistry = NULL; 
    m_pmiRegistry = NULL; 
    m_pmoRegistry = NULL; 
    m_uiRegistry = NULL; 
 
    m_lmcExtensions = NULL; 
 
    m_browserUI = NULL; 
    m_downloadUI = NULL; 
 
    m_pmo = NULL; 
    m_lmc = NULL; 
    m_ui = NULL; 
 
    m_argUIList = new vector < char *>(); 
 
    m_argc = 0; 
    m_argv = NULL; 
    m_pTermSem = NULL; 
 
    m_didUsage = false; 
    m_autoplay = true; 
 
    m_props.RegisterPropertyWatcher("pcm_volume", (PropertyWatcher *) this); 
 
    m_context->plm = m_plm; 
    m_context->props = &m_props; 
    m_context->target = (EventQueue *) this; 
 
    m_musicCatalog = new MusicCatalog(m_context); 
    m_context->catalog = m_musicCatalog; 
 
    // make sure the db dir exists so we have a place to store our  
    // stuff 
 
    char* tempDir = new char[_MAX_PATH]; 
    uint32 length = _MAX_PATH; 
    struct stat st; 
 
    m_context->prefs->GetPrefString(kDatabaseDirPref, tempDir, &length); 
 
    if(-1 == stat(tempDir, &st)) 
    { 
        MKDIR(tempDir); 
    } 
 
    string freeampdir = tempDir; 
    freeampdir += DIR_MARKER_STR; 
    freeampdir += "metadatabase"; 
    m_musicCatalog->SetDatabase(freeampdir.c_str()); 
 
    // make sure the music dir exists so we have a place to store our  
    // stuff 
 
    length = _MAX_PATH; 
    m_context->prefs->GetPrefString(kSaveMusicDirPref, tempDir, &length); 
 
    if(-1 == stat(tempDir, &st)) 
    { 
        MKDIR(tempDir); 
    } 
 
    delete [] tempDir; 
    m_dlm = new DownloadManager(m_context); 
    m_context->downloadManager = m_dlm; 
} 
 
#define TYPICAL_DELETE(x) /*printf("deleting...\n");*/ if (x) { delete x; x = NULL; } 
 
Player:: 
~Player() 
{ 
    TYPICAL_DELETE(m_dlm); 
 
    TYPICAL_DELETE(m_pTermSem); 
 
    if(m_argUIList) 
    { 
        vector::iterator i = m_argUIList->begin(); 
 
        for (; i != m_argUIList->end(); i++) 
            delete [] *i;  
 
        delete m_argUIList; 
 
        m_argUIList = NULL; 
    } 
 
    if(m_eventServiceThread) 
    { 
        m_eventServiceThread->Join(); 
        delete    m_eventServiceThread; 
 
        m_eventServiceThread = NULL; 
    } 
 
    if(m_pmo) 
    { 
        m_pmo->Pause(); 
        delete    m_pmo; 
 
        m_pmo = NULL; 
    } 
 
    TYPICAL_DELETE(m_eventSem); 
    TYPICAL_DELETE(m_eventQueue); 
 
    // Delete CIOs 
    if(m_uiList) 
    { 
        vector::iterator i = m_uiList->begin(); 
 
        for (; i != m_uiList->end(); i++) 
            delete *i;  
        delete m_uiList; 
 
        m_uiList = NULL; 
    } 
 
    TYPICAL_DELETE(m_plm); 
    TYPICAL_DELETE(m_uiManipLock); 
    TYPICAL_DELETE(m_lmcMutex); 
    TYPICAL_DELETE(m_pmiMutex); 
    TYPICAL_DELETE(m_pmoMutex); 
    TYPICAL_DELETE(m_uiMutex); 
    TYPICAL_DELETE(m_lmcRegistry); 
    TYPICAL_DELETE(m_pmiRegistry); 
    TYPICAL_DELETE(m_pmoRegistry); 
    TYPICAL_DELETE(m_uiRegistry); 
    TYPICAL_DELETE(m_lmcExtensions); 
    TYPICAL_DELETE(m_musicCatalog); 
} 
 
void       
Player:: 
SetTerminationSemaphore(Semaphore * pSem) 
{ 
    m_pTermSem = pSem; 
} 
 
/* 
    return true if parsing was successful, false otherwise.  
*/ 
 
typedef char *pchar; 
 
bool       
Player:: 
SetArgs(int32 argc, char **argv) 
{ 
    bool autoplay = false; 
    char* path = new char[_MAX_PATH]; 
    char* url = new char[_MAX_PATH]; 
 
    // remember these guys so we can use them later and elsewhere 
    m_argc = argc; 
    m_argv = argv; 
 
    m_context->argv = m_argv; 
    m_context->argc = m_argc; 
 
    // now parse them and pull out any args we know about 
    for (int32 i = 1; i < argc; i++) 
    { 
        char* arg = argv[i]; 
 
        // is this an option? 
        if(arg[0] == '-'  
#ifdef WIN32 
        	|| arg[0] == '/' 
#endif    
			) 
        { 
            switch(arg[1]) 
            { 
                // print help 
                case 'h': 
                case 'H': 
                case '-': 
                    if(!strcasecmp(arg + 1, "help") || !strcasecmp(arg + 2, "help")) 
                    { 
                        Usage(argv[0]); 
                        AcceptEvent(new Event(CMD_QuitPlayer)); 
                        return true; 
                    } 
                    break; 
 
                // autoplay 
                case 'p': 
                case 'P': 
                    if(!strcasecmp(arg + 1, "play")) 
                        autoplay = true; 
 
                // save streams 
                // shuffle 
                case 's': 
                case 'S': 
                    if(!strcasecmp(arg + 1, "save")) 
		                m_context->argFlags |= FAC_ARGFLAGS_SAVE_STREAMS; 
                    else if(!strcasecmp(arg + 1, "shuffle")) 
                        m_plm->SetShuffleMode(true); 
 
                    break; 
 
                // set UIs 
                case 'u': 
                case 'U': 
                { 
                    if(arg[2] == 'i' || arg[2] == 'I') 
                    { 
                        char* argUI = NULL; 
                         
                        i++; 
                        if(i >= argc) 
                        { 
                            Usage(argv[0]); 
                            AcceptEvent(new Event(CMD_QuitPlayer)); 
                            return false; 
                        } 
 
                        arg = argv[i]; 
 
                        argUI = new char[strlen(arg) + 1]; 
 
                        strcpy(argUI, arg); 
                         
                        m_argUIList->push_back(argUI); 
                    } 
 
                    break; 
                } 
 
                default: 
                    break; 
 
            } 
        } 
        else 
        { 
            // is this a URL we know how to handle 
            if( !strncasecmp(arg, "http://", 7) ||  
                !strncasecmp(arg, "rtp://", 6)) 
            { 
                m_plm->AddItem(arg); 
            } 
            else 
            { 
#ifdef WIN32 
                strcpy(path, arg); 
 
                HANDLE handle; 
                WIN32_FIND_DATA data; 
         
                handle = FindFirstFile(arg, &data); 
 
                // find long filename for item and 
                // expand wildcards... 
                if(handle != INVALID_HANDLE_VALUE) 
                { 
                    do 
                    { 
                        char* cp = NULL; 
                     
                        cp = strrchr(path, '\\'); 
 
                        if(cp) 
                            cp++; 
                        else  
                            cp = path; 
 
                        strcpy(cp, data.cFileName); 
 
 
                        // make sure we have an absolute path 
                        ResolvePath(&path); 
 
                        // format this path as a URL 
                        uint32 length = _MAX_PATH; 
                        FilePathToURL(path, url, &length); 
 
                        // who needs to get this, plm or dlm? 
                        bool giveToDLM = false; 
                        bool giveToTheme = false; 
                        char* extension = NULL; 
 
                        extension = strrchr(url, '.'); 
                        if(extension) 
                        { 
                            DownloadFormatInfo dlfi; 
                            uint32 i = 0; 
 
                            extension++; 
 
                            while(IsntError(m_dlm->GetSupportedDownloadFormats(&dlfi, i++))) 
                            { 
                                if(!strcasecmp(extension, dlfi.GetExtension())) 
                                { 
                                    giveToDLM = true; 
                                    break; 
                                } 
                            } 
                            if (strcasecmp(extension, themeExtension) == 0) 
                                giveToTheme = true;  
                        } 
 
 
                        if(giveToDLM) 
                            m_dlm->ReadDownloadFile(url); 
                        else 
                        if(giveToTheme) 
                        { 
                            char szSavedTheme[_MAX_PATH], szNewTheme[_MAX_PATH]; 
                            uint32 iLen = _MAX_PATH;    
 
                            m_context->prefs->GetPrefString(kThemePathPref,  
                                 szSavedTheme, &iLen); 
                            iLen = _MAX_PATH;    
                            URLToFilePath(url, szNewTheme, &iLen);  
                            m_context->prefs->SetPrefString(kThemePathPref,  
                               szNewTheme); 
 
                            AcceptEvent(new LoadThemeEvent(url, szSavedTheme)); 
                        } 
                        else  
                            m_plm->AddItem(url);  
 
                    }while(FindNextFile(handle, &data)); 
                    
                    FindClose(handle); 
                } 
                else // is this a URL we know how to handle ? 
                { 
                    // file not found? don't add it... 
                    continue; 
                } 
#else 
                strcpy(path, arg); 
                 
                //printf("Path: %s\r\n", path); 
                
                // make sure we have an absolute path 
                ResolvePath(&path); 
                
                //printf("Resolved: %s\r\n", path); 
 
                // format this path as a URL 
                uint32 length = _MAX_PATH; 
                FilePathToURL(path, url, &length); 
             
                //printf("URL: %s\r\n", url); 
 
                // who needs to get this, plm or dlm? 
                bool giveToDLM = false; 
                bool giveToTheme = false; 
                char* extension = NULL; 
 
                extension = strrchr(url, '.'); 
 
                if(extension) 
                { 
                    DownloadFormatInfo dlfi; 
                    uint32 i = 0; 
 
                    extension++; 
 
                    while(IsntError(m_dlm->GetSupportedDownloadFormats(&dlfi, i++))) 
                    { 
                        if(!strcasecmp(extension, dlfi.GetExtension())) 
                        { 
                            giveToDLM = true; 
                            break; 
                        } 
                    } 
                    if (strcasecmp(extension, themeExtension) == 0) 
                        giveToTheme = true;  
                } 
 
                if (giveToDLM)  
                    m_dlm->ReadDownloadFile(url); 
                else if (giveToTheme) 
                { 
                    char szSavedTheme[_MAX_PATH], szNewTheme[_MAX_PATH]; 
                    uint32 iLen = _MAX_PATH;    
 
                    m_context->prefs->GetPrefString(kThemePathPref,  
                                                    szSavedTheme, &iLen); 
                    iLen = _MAX_PATH;    
                    URLToFilePath(url, szNewTheme, &iLen);  
                    m_context->prefs->SetPrefString(kThemePathPref, szNewTheme); 
 
                    AcceptEvent(new LoadThemeEvent(url, szSavedTheme)); 
                } 
                else  
                { 
                    m_plm->AddItem(url);  
               	}	 
#endif 
            } 
        } 
    } 
 
    delete [] path; 
    delete [] url; 
 
    return true; 
} 
 
void       
Player:: 
Usage(const char *progname) 
{ 
    if(m_didUsage) 
        return; 
 
    printf(The_BRANDING " version " FREEAMP_VERSION " -- Usage:\n\n"); 
    printf("%s [-save] [-ui ]  " 
      "[MP3 file/stream] ...\n\n", progname); 
    printf("Example command line:\n\n"); 
    printf("   %s -ui freeamp.ui mysong1.mp3 mysong2.mp3\n\n", progname); 
 
    m_didUsage = true; 
} 
 
int32      
Player:: 
CompareNames(const char *p1, const char *p2) 
{ 
// windows plugins and unix plugins are named differently... 
#if defined( WIN32 ) || defined ( __BEOS__ ) 
    return strcasecmp(p1, p2); 
#else 
    // ut << "Comparing: " << p1 << " to " << p2 << endl; 
    if (strcmp(p1, p2)) 
    { 
        // no direct match, try w/ .ui appended... 
        char      foo[512]; 
 
        sprintf(foo, "%s.ui", p2); 
        // ut << "Comparing: " << p1 << " to " << foo << endl; 
        if (strcmp(p1, foo)) 
        { 
            // no plugin.ui match, try  plugin-arch.ui 
            char      foo[512]; 
 
            sprintf(foo, "%s.ui", p2); 
            // cout << "Comparing: " << p1 << " to " << foo << endl; 
            if (strcmp(p1, foo)) 
            { 
                // no match 
                return 1; 
            } 
            else 
            { 
                return 0; 
            } 
        } 
        else 
        { 
            return 0; 
        } 
    } 
    else 
    { 
        return 0; 
    } 
#endif 
} 
 
void       
Player:: 
Run() 
{ 
   uint32    uiListIndex = 0; 
   char     *name = NULL; 
   uint32    len = 256; 
   Error     error = kError_NoErr; 
   int32     uisActivated = 0; 
   bool      bValue; 
 
   m_context->prefs->GetUseDebugLog(&bValue); 
   if (bValue) 
      m_context->log->Open(); 
    
   m_context->prefs->GetLogInput(&bValue); 
   if (bValue) 
      m_context->log->AddLogLevel(LogInput); 
    
   m_context->prefs->GetLogOutput(&bValue); 
   if (bValue) 
      m_context->log->AddLogLevel(LogOutput); 
    
   m_context->prefs->GetLogDecode(&bValue); 
   if (bValue) 
      m_context->log->AddLogLevel(LogDecode); 
    
   m_context->prefs->GetLogPerformance(&bValue); 
   if (bValue) 
      m_context->log->AddLogLevel(LogPerf); 
 
   bool loadSecondaryUIs = true; 
 
   // which ui should we instantiate first?? 
   if (m_argUIList->size() == 0) 
   { 
      const char *pref = kUIPref; 
      name = new char[len]; 
 
#ifdef unix 
      if (!getenv("DISPLAY")) { 
	  pref = kTextUIPref; 
          loadSecondaryUIs = false; 
      } 
#endif 
      while ((error = m_context->prefs->GetPrefString(pref, name, &len)) == 
             kError_BufferTooSmall) 
      { 
         delete[] name; 
         len++; 
 
         name = new char[len]; 
      } 
#ifdef unix 
#ifndef HAVE_GTK 
      if (!strcmp("freeamp.ui", name)) { 
          pref = kTextUIPref; 
 
          while ((error = m_context->prefs->GetPrefString(pref, name, &len)) == 
                 kError_BufferTooSmall) 
          { 
              delete [] name; 
              len++; 
 
              name = new char[len]; 
          } 
      } 
#endif 
#endif 
   } 
   else 
   { 
      char *orig = (*m_argUIList)[uiListIndex++]; 
	  // RAK: This pointer is later re-used when the size of the 
      // contents may have changed. See comment below. 
      name = new char[strlen(orig) + 1]; 
 
      strcpy(name, orig); 
   } 
 
#ifdef HAVE_GTK 
   if (strcmp("freeamp.ui", name)) 
       loadSecondaryUIs = false; 
#endif 
 
   len = 255; 
   char *downloadName = new char[len]; 
   while  ((error = m_context->prefs->GetPrefString(kDownloadManagerUIPref, 
                                                    downloadName, &len)) == 
           kError_BufferTooSmall) 
   { 
       delete[] downloadName; 
       len++; 
      
       downloadName = new char[len]; 
   } 
 
   len = 255; 
   char *musicBrowserName = new char[len]; 
   while  ((error = m_context->prefs->GetPrefString(kMusicBrowserUIPref,  
                                                    musicBrowserName, &len)) == 
           kError_BufferTooSmall) 
   { 
       delete[] musicBrowserName; 
       len++; 
 
       musicBrowserName = new char[len]; 
   } 
 
#ifdef WIN32 
   len = 255; 
   char *toolbarName = new char[len]; 
   while  ((error = m_context->prefs->GetPrefString(kToolbarUIPref, 
                                                    toolbarName, &len)) == 
           kError_BufferTooSmall) 
   { 
       delete[] toolbarName; 
       len++; 
      
       toolbarName = new char[len]; 
   } 
#endif 
 
   if (IsntError(error)) 
   { 
      while (*name) 
      { 
         RegistryItem *item = NULL; 
//       UserInterface *ui = NULL; 
         int32     i = 0; 
 
         while (NULL != (item = m_uiRegistry->GetItem(i++))) 
         { 
            if (!CompareNames(item->Name(), downloadName) && loadSecondaryUIs) 
            { 
               m_ui = (UserInterface *) item->InitFunction()(m_context); 
 
               Error er = m_ui->Init(SECONDARY_UI_STARTUP); 
               if (IsntError(er))  
               { 
                   RegisterActiveUI(m_ui); 
                   m_downloadUI = m_ui; 
               } 
               else  
               { 
                   delete m_ui; 
                   m_ui = NULL; 
               } 
            } 
            else if (!CompareNames(item->Name(), musicBrowserName) &&  
                     loadSecondaryUIs) 
            { 
               m_ui = (UserInterface *) item->InitFunction()(m_context); 
               
               Error er = m_ui->Init(SECONDARY_UI_STARTUP); 
               if (IsntError(er)) 
               { 
                   RegisterActiveUI(m_ui); 
                   m_browserUI = m_ui; 
               } 
               else 
               { 
                   delete m_ui; 
                   m_ui = NULL; 
               } 
            } 
#ifdef WIN32  
            else 
            if (!CompareNames(item->Name(), toolbarName)) 
            { 
               m_ui = (UserInterface *) item->InitFunction()(m_context); 
 
               Error er = m_ui->Init(SECONDARY_UI_STARTUP); 
               if (IsntError(er))  
                   RegisterActiveUI(m_ui); 
               else  
               { 
                   delete m_ui; 
                   m_ui = NULL; 
               } 
            } 
#endif             
            else if (!CompareNames(item->Name(), name)) 
            { 
               m_ui = (UserInterface *) item->InitFunction()(m_context); 
 
               //m_ui->SetPropManager((Properties *) this); 
               //m_ui->SetPlaylistManager(m_plm); 
               //m_ui->SetArgs(m_argc, m_argv); 
               Error     er = m_ui->Init((uisActivated == 0) ? PRIMARY_UI 
					 : SECONDARY_UI_STARTUP); 
               if (IsntError(er)) 
               { 
                  RegisterActiveUI(m_ui); 
                  uisActivated++; 
               } 
               else 
               { 
                  delete    m_ui; 
 
                  m_ui = NULL; 
               } 
           //    break;  Don't think this'll work now... 
            } 
         } 
 
         if(uiListIndex < m_argUIList->size()) 
         { 
            char *p = (*m_argUIList)[uiListIndex++]; 
             
            // RAK: Boundschecker was pissed about this. This copy 
            // may be larger than the space allocated on line 524 
            // So, delete the old pointer and create a new one. 
            delete name; 
            name = new char[strlen(p) + 1]; 
             
            strcpy(name, p); 
         } 
         else 
         { 
            *name = '\0'; 
         } 
      } 
 
      if (!uisActivated) 
      { 
#ifdef WIN32 
         MessageBox(NULL, The_BRANDING" cannot find a valid user interface module.\r\n" 
                          "Please make sure that " the_BRANDING" is installed correctly.\r\n" 
                          "You may wish to remove and reinstall " the_BRANDING" to fix this problem", 
                          BRANDING" Error", MB_OK); 
#else 
         const char *thePath = getenv(FREEAMP_PATH_ENV); 
 
         if (thePath == NULL) 
          thePath = m_context->prefs->GetLibDirs(); 
         cerr << "No UI plugin in '" << thePath << "' matched 'plugins/" << name << "' or 'plugins/" << name << ".ui.'" << endl; 
         cerr << The_BRANDING << " will quit." << endl; 
#endif 
         Event    *e = new Event(CMD_QuitPlayer); 
 
         AcceptEvent(e); 
         e = new Event(INFO_ReadyToDieUI); 
         AcceptEvent(e); 
      } 
   } 
   m_eventServiceThread = Thread::CreateThread(); 
   m_eventServiceThread->Create(Player::EventServiceThreadFunc, this); 
 
   delete[] name; 
   delete[] musicBrowserName; 
   delete[] downloadName; 
#ifdef WIN32 
   delete[] toolbarName; 
#endif 
} 
 
void  
Player:: 
EventServiceThreadFunc(void *pPlayer) 
{ 
   Player   *pP = (Player *) pPlayer; 
   Event    *pC; 
   int32     rtnVal = 0x0; 
 
   while (rtnVal == 0) 
   {                            // serviceEvent will return 1 if error or time 
      if (pP->m_eventQueue->Peek() == NULL) 
          pP->m_eventSem->Wait(); 
 
      pC = pP->m_eventQueue->Read(); 
      if (pC) 
      { 
         rtnVal = pP->ServiceEvent(pC); 
      } 
   } 
} 
 
int32      
Player:: 
RegisterActiveUI(UserInterface * ui) 
{ 
   GetUIManipLock(); 
   if (m_uiList && ui) 
   { 
      m_uiList->push_back(ui); 
      ReleaseUIManipLock(); 
      return 0; 
   } 
   else 
   { 
      ReleaseUIManipLock(); 
      return 255; 
   } 
} 
 
int32      
Player:: 
RegisterLMCs(Registry * registry) 
{ 
   int32     result = 0; 
 
   m_lmcMutex->Acquire(); 
 
   if (m_lmcRegistry) 
   { 
    Registrar::CleanupRegistry(m_lmcRegistry); 
      delete    m_lmcRegistry; 
   } 
 
   if (m_lmcExtensions) 
      delete m_lmcExtensions; 
 
   m_lmcExtensions = new HashTable; 
 
   m_lmcRegistry = registry; 
 
   RegistryItem *lmc_item; 
   LogicalMediaConverter *lmc; 
   int iItems = registry->CountItems(); 
 
   for (int iLoop = 0; iLoop < iItems; iLoop++) 
   { 
      RegistryItem* temp = registry->GetItem(iLoop); 
 
      lmc = (LogicalMediaConverter *)temp->InitFunction()(m_context); 
      vector *extList = lmc->GetExtensions(); 
 
      for (uint32 iextLoop = 0; iextLoop < extList->size(); iextLoop++) 
      { 
          lmc_item = new RegistryItem(*temp); 
          m_lmcExtensions->Insert((*extList)[iextLoop], lmc_item); 
      } 
 
      delete extList; 
      delete lmc; 
   } 
 
   m_lmcMutex->Release(); 
 
   return result; 
} 
 
int32      
Player:: 
RegisterPMIs(Registry * registry) 
{ 
   int32     result = 0; 
 
   m_pmiMutex->Acquire(); 
 
   if (m_pmiRegistry) 
   { 
    Registrar::CleanupRegistry(m_pmiRegistry); 
      delete    m_pmiRegistry; 
   } 
 
   m_pmiRegistry = registry; 
 
   m_pmiMutex->Release(); 
 
   return result; 
} 
 
int32      
Player:: 
RegisterPMOs(Registry * registry) 
{ 
   int32     result = 0; 
 
   m_pmoMutex->Acquire(); 
 
   if (m_pmoRegistry) 
   { 
    Registrar::CleanupRegistry(m_pmoRegistry); 
      delete    m_pmoRegistry; 
   } 
 
   m_pmoRegistry = registry; 
 
   m_pmoMutex->Release(); 
 
   return result; 
} 
 
int32      
Player:: 
RegisterUIs(Registry * registry) 
{ 
   int32     result = 0; 
 
   m_uiMutex->Acquire(); 
 
   if (m_uiRegistry) 
   { 
    Registrar::CleanupRegistry(m_uiRegistry); 
      delete    m_uiRegistry; 
   } 
 
   m_uiRegistry = registry; 
 
   m_uiMutex->Release(); 
 
   return result; 
} 
 
Registry*  
Player:: 
GetLMCRegistry() const 
{ 
    return m_lmcRegistry; 
} 
 
Registry*  
Player:: 
GetPMIRegistry() const 
{ 
    return m_pmiRegistry; 
} 
 
Registry*  
Player:: 
GetPMORegistry() const 
{ 
    return m_pmoRegistry; 
} 
 
Registry*   
Player:: 
GetUIRegistry() const 
{ 
    return m_uiRegistry; 
} 
 
void  
Player:: 
GetUIManipLock() 
{ 
   m_uiManipLock->Acquire(WAIT_FOREVER); 
} 
 
void  
Player:: 
ReleaseUIManipLock() 
{ 
   m_uiManipLock->Release(); 
} 
 
int32  
Player:: 
AcceptEvent(Event * e) 
{ 
   m_eventQueue->Write(e); 
   m_eventSem->Signal(); 
   return 0; 
} 
 
bool  
Player:: 
SetState(PlayerState ps) 
{ 
#if 0 
   printf("Player state: "); 
   switch(ps) 
   { 
       case PlayerState_Stopped: 
          printf("Stopped.\n"); 
          break; 
       case PlayerState_Paused: 
          printf("Paused.\n"); 
          break; 
       case PlayerState_Playing: 
          printf("Playing.\n"); 
          break; 
       default: 
          printf("Unknown.\n"); 
          break; 
   } 
#endif 
   if (ps == m_playerState) 
      return false; 
   m_playerState = ps; 
   return true; 
} 
 
char * 
Player:: 
GetExtension(const char *title) 
{ 
   char *temp_ext; 
   char *ext_return = NULL; 
 
   temp_ext = strrchr(title, '.'); 
   if (temp_ext) 
   { 
      temp_ext = temp_ext + 1; 
      ext_return = new char [strlen(temp_ext) + 1]; 
      strcpy(ext_return, temp_ext); 
      char *p = ext_return; 
      while (*p) { 
         *p = toupper(*p); 
         p++; 
      } 
   } 
   return ext_return; 
} 
 
bool 
Player:: 
IsSupportedExtension(const char *ext) 
{ 
   RegistryItem *lmc_item = m_lmcExtensions->Value(ext); 
 
   if (lmc_item) 
       return true; 
   return false; 
} 
 
RegistryItem * 
Player:: 
ChooseLMC(const char *szUrl, char *szTitle) 
{ 
   RegistryItem *lmc_item = NULL; 
   char     *iExt; 
 
 
   iExt = GetExtension(szUrl); 
   if (!iExt) 
      return lmc_item; 
 
   lmc_item = m_lmcExtensions->Value(iExt); 
 
   delete iExt; 
 
   return lmc_item; 
} 
 
RegistryItem * 
Player:: 
ChoosePMI(const char *szUrl, char *szTitle) 
{ 
   PhysicalMediaInput *pmi; 
   RegistryItem *pmi_item, *ret = NULL; 
   int       iLoop; 
   char     *szNewUrl = NULL; 
 
   if (strstr(szUrl, "://") == NULL) 
   { 
      szNewUrl = new char[strlen(szUrl) + strlen("file:// ") + 1]; 
 
      sprintf(szNewUrl, "file://%s", szUrl); 
 
      szUrl = szNewUrl; 
   } 
 
   for (iLoop = 0; iLoop < m_pmiRegistry->CountItems(); iLoop++) 
   { 
      pmi_item = m_pmiRegistry->GetItem(iLoop); 
 
      pmi = (PhysicalMediaInput *) pmi_item->InitFunction()(m_context); 
      if (pmi->CanHandle(szUrl, szTitle)) 
      { 
         ret = pmi_item; 
         delete pmi; 
 
         break; 
      } 
      delete pmi; 
   } 
 
   if (szNewUrl) 
      delete szNewUrl; 
 
   return ret; 
} 
 
void  
Player:: 
CreatePMO(const PlaylistItem * pc, Event * pC) 
{ 
   Error     error = kError_NoErr; 
   Event    *e; 
   PhysicalMediaOutput *pmo = NULL; 
   PhysicalMediaInput *pmi = NULL; 
   LogicalMediaConverter *lmc = NULL; 
   RegistryItem *pmi_item = NULL; 
   RegistryItem *lmc_item = NULL; 
   RegistryItem *item = NULL; 
 
   if (!pc) 
   { 
      m_plm->SetCurrentIndex(0); 
      if (m_pmo) 
      { 
         m_pmo->Pause(); 
         delete m_pmo; 
 
         m_pmo = NULL; 
      } 
      if (SetState(PlayerState_Stopped)) 
      { 
         SEND_NORMAL_EVENT(INFO_Stopped); 
      } 
      GetUIManipLock(); 
 
      e = new Event(INFO_PlaylistDonePlay); 
      SendToUI(e); 
 
      ReleaseUIManipLock(); 
 
      delete e; 
   } 
 
   if (m_pmo) 
   { 
      m_pmo->Pause(); 
      delete    m_pmo; 
 
      m_pmo = NULL; 
   } 
 
    
   pmi_item = ChoosePMI(pc->URL().c_str()); 
   if (!pmi_item) 
   { 
      char szErr[1024]; 
 
      sprintf(szErr, "Cannot determine what pmi to use for %s\n", pc->URL().c_str()); 
      m_context->log->Error(szErr); 
      AcceptEvent(new ErrorMessageEvent(szErr)); 
 
      return; 
   } 
 
   lmc_item = ChooseLMC(pc->URL().c_str()); 
   if (!lmc_item) 
   // FIXME: Should probably have a user definable default LMC 
      lmc_item = m_lmcRegistry->GetItem(0); 
 
   
   if (pmi_item) 
   { 
      pmi = (PhysicalMediaInput *) pmi_item->InitFunction()(m_context); 
      pmi->SetPropManager((Properties *) this); 
   } 
 
   char *extension = GetExtension(pc->URL().c_str()); 
   if (extension) { 
       if (!strncasecmp("CDA", extension, 3)) { 
           int32 i = 0; 
 
           while (NULL != (item = m_pmoRegistry->GetItem(i++))) 
           { 
               if (!strcmp("cd.pmo", item->Name())) 
               { 
                   break; 
               } 
           } 
       } 
   } 
 
   if (!item) { 
       char defaultPMO[256]; 
       uint32 size = sizeof(defaultPMO); 
 
       m_context->prefs->GetDefaultPMO(defaultPMO, &size); 
 
       int32 i = 0; 
 
       while (NULL != (item = m_pmoRegistry->GetItem(i++))) 
       { 
            if(!strcmp(defaultPMO, item->Name())) 
            { 
                break; 
            } 
       } 
   } 
 
   // if the default isn't around then just use first one  
   // is there a better way? 
   if(!item) 
      item = m_pmoRegistry->GetItem(0); 
 
   if (item) 
   { 
      pmo = (PhysicalMediaOutput *) item->InitFunction()(m_context); 
      pmo->SetPropManager((Properties *) this); 
   } 
 
   error = kError_NoErr; 
   if (lmc_item) 
   { 
      lmc = (LogicalMediaConverter *) lmc_item->InitFunction()(m_context); 
 
      lmc->SetPropManager((Properties *) this); 
   } 
 
   lmc->SetPMI(pmi); 
   lmc->SetPMO(pmo); 
 
   pmo->SetPMI(pmi); 
   pmo->SetLMC(lmc); 
 
   pmi = NULL; 
   m_lmc = lmc; 
   lmc = NULL; 
 
   error = pmo->SetTo(pc->URL().c_str()); 
   if (IsError(error)) 
   { 
      char szErr[1024]; 
 
      sprintf(szErr, "Cannot setup the audio decode process: %d\n", error); 
      m_context->log->Error(szErr); 
 
      goto epilogue; 
   } 
 
   m_pmo = pmo; 
   pmo = NULL; 
 
   epilogue: 
 
   if (pmo) 
   { 
       delete pmo; 
   } 
 
   if (pmi) 
   { 
       delete pmi; 
   } 
 
   if (lmc) 
   { 
       delete lmc; 
   } 
} 
 
void  
Player:: 
DoneOutputting(Event *pEvent) 
{ 
   // LMC or PMO sends this when its done 
   // outputting whatever.  Now, go on to next 
   // piece in playlist 
 
   if (m_pmo) 
   { 
      delete m_pmo; 
      m_pmo = NULL; 
   } 
 
   if (SetState(PlayerState_Stopped)) 
   { 
       SEND_NORMAL_EVENT(INFO_Stopped); 
   } 
 
   SEND_NORMAL_EVENT(INFO_DoneOutputting); 
 
   if (pEvent->Type() == INFO_DoneOutputtingDueToError && 
       (m_plm->GetRepeatMode() == kPlaylistMode_RepeatOne ||  
        (m_plm->GetRepeatMode() == kPlaylistMode_RepeatAll &&  
         m_plm->CountItems() == 1)))  
   { 
      m_plm->SetCurrentIndex(0); 
      SEND_NORMAL_EVENT(INFO_PlaylistDonePlay); 
      delete pEvent; 
       
      return; 
   } 
 
   if (m_plm->HasAnotherItem())  
   { 
      //AcceptEvent(new Event(CMD_NextMediaPiece)); 
      m_plm->GotoNextItem(false); 
 
      if (m_playerState == PlayerState_Paused) 
      { 
         AcceptEvent(new Event(CMD_PlayPaused)); 
      } 
      else 
      { 
         AcceptEvent(new Event(CMD_Play)); 
      } 
   } 
   else 
   { 
      m_plm->SetCurrentIndex(0); 
      SEND_NORMAL_EVENT(INFO_PlaylistDonePlay); 
   } 
   delete pEvent; 
} 
 
 
void  
Player:: 
Stop(Event *pEvent) 
{ 
    if (m_pmo) 
    { 
       m_pmo->Pause(); 
       delete    m_pmo; 
  
       m_pmo = NULL; 
    } 
 
    if (SetState(PlayerState_Stopped)) 
    { 
       SEND_NORMAL_EVENT(INFO_Stopped); 
    } 
 
    delete pEvent; 
} 
 
void 
Player:: 
GetVolume(Event *pEvent) 
{ 
    int iVolume = -1; 
 
    delete pEvent; 
    if (m_pmo)  
    { 
       iVolume = m_pmo->GetVolume(); 
       SendToUI(new VolumeEvent(INFO_VolumeInfo,iVolume)); 
    }    
} 
 
void 
Player:: 
SetVolume(Event *pEvent) 
{ 
    int32 v=((VolumeEvent *) pEvent)->GetVolume(); 
    if (m_pmo)  
        m_pmo->SetVolume(v); 
    delete pEvent; 
} 
 
void  
Player:: 
ChangePosition(Event *pEvent) 
{ 
    if (m_pmo) 
       m_pmo->ChangePosition(((ChangePositionEvent *) pEvent)->GetPosition()); 
 
    delete pEvent; 
} 
 
void  
Player:: 
HandleQueryState() 
{ 
    if (m_playerState == PlayerState_Playing) 
    { 
        SEND_NORMAL_EVENT(INFO_Playing); 
    } 
    else if (m_playerState == PlayerState_Stopped) 
    { 
        SEND_NORMAL_EVENT(INFO_Stopped); 
    } 
    else if (m_playerState == PlayerState_Paused) 
    { 
        SEND_NORMAL_EVENT(INFO_Paused); 
    } 
} 
 
void  
Player:: 
Play(Event *pEvent) 
{ 
    const PlaylistItem               *pItem; 
 
    if (m_playerState == PlayerState_Playing) 
    { 
       delete m_pmo; 
       m_pmo = NULL; 
 
       if (SetState(PlayerState_Stopped)) 
       { 
           SEND_NORMAL_EVENT(INFO_Stopped); 
       } 
    } 
 
    if (!m_pmo) 
    { 
       pItem = m_plm->GetCurrentItem(); 
       if (pItem) 
       { 
          CreatePMO(pItem, pEvent); 
       }    
 
       if (!m_pmo)  
          return; 
    } 
 
    if (pEvent->Type() == CMD_PlayPaused) 
    { 
        if (SetState(PlayerState_Paused)) 
        { 
           SEND_NORMAL_EVENT(INFO_Playing);  
           SEND_NORMAL_EVENT(INFO_Paused); 
        } 
    } 
    else 
    { 
        m_pmo->Resume(); 
        if (SetState(PlayerState_Playing)) 
        { 
           SEND_NORMAL_EVENT(INFO_Playing); 
        } 
    } 
 
    delete pEvent; 
} 
 
void  
Player:: 
Next(Event *pEvent) 
{ 
   if (m_playerState != PlayerState_Stopped) 
   { 
      AcceptEvent(new Event(CMD_Stop)); 
   } 
 
   m_plm->GotoNextItem(true); 
 
   if (m_playerState != PlayerState_Stopped) 
   { 
       if (m_playerState == PlayerState_Paused) 
       { 
          AcceptEvent(new Event(CMD_PlayPaused)); 
       }    
       else 
       {  
          AcceptEvent(new Event(CMD_Play)); 
       }    
   } 
 
   delete pEvent; 
} 
 
void  
Player:: 
Previous(Event *pEvent) 
{ 
   if (m_playerState != PlayerState_Stopped) 
   { 
      AcceptEvent(new Event(CMD_Stop)); 
   } 
 
   m_plm->GotoPreviousItem(true); 
 
   if (m_playerState != PlayerState_Stopped) 
   { 
       if (m_playerState == PlayerState_Paused) 
          AcceptEvent(new Event(CMD_PlayPaused)); 
       else 
          AcceptEvent(new Event(CMD_Play)); 
   } 
 
   delete pEvent; 
} 
 
void  
Player:: 
Pause(Event *pEvent) 
{ 
   if (m_pmo) 
   { 
      m_pmo->Pause(); 
      if (SetState(PlayerState_Paused)) 
         SEND_NORMAL_EVENT(INFO_Paused); 
   } 
   delete pEvent; 
} 
 
void  
Player:: 
UnPause(Event *pEvent) 
{ 
   if (m_pmo) 
   { 
      m_pmo->Resume(); 
      if (SetState(PlayerState_Playing)) 
         SEND_NORMAL_EVENT(INFO_Playing); 
   } 
   delete pEvent; 
} 
 
void  
Player:: 
TogglePause(Event *pEvent) 
{ 
    if (m_pmo) 
    { 
       if (m_playerState == PlayerState_Playing) 
           Pause(NULL); 
       else 
       if (m_playerState == PlayerState_Paused) 
           UnPause(NULL); 
    } 
 
    delete pEvent; 
} 
 
int  
Player:: 
Quit(Event *pEvent) 
{ 
   Event *pe; 
 
   Stop(NULL); 
   // 1) Set "I'm already quitting flag" (or exit if its already Set) 
   m_imQuitting = 1; 
   // 2) Get CIO/COO manipulation lock 
 
   GetUIManipLock(); 
   // 3) Count CIO/COO, put into m_quitWaitingFor. 
   m_quitWaitingFor = m_uiList->size(); 
   // 4) Send CMD_Cleanup event to all CIO/COOs 
 
   pe = new Event(CMD_Cleanup); 
 
   SendToUI(pe); 
   delete    pe; 
 
   delete  pEvent; 
 
   if (m_quitWaitingFor == 0) 
   { 
      if (m_pTermSem) 
      { 
         m_pTermSem->Signal(); 
      } 
      return 1; 
   } 
   else 
   { 
      ReleaseUIManipLock(); 
      return 0; 
   } 
} 
 
int  
Player:: 
ReadyToDieUI(Event *pEvent) 
{ 
   delete pEvent; 
 
   if (!m_imQuitting) 
       return 0; 
 
   m_quitWaitingFor--; 
   if (m_quitWaitingFor > 0) 
       return 0; 
 
   GetUIManipLock(); 
   if (m_pTermSem) 
      m_pTermSem->Signal(); 
 
   return 1; 
} 
 
void  
Player:: 
HandleMediaInfo(Event *pEvent) 
{ 
   MediaInfoEvent *pmvi; 
   Event          *pe = NULL; 
    
   GetUIManipLock(); 
 
   pmvi = (MediaInfoEvent *)pEvent; 
   pmvi->m_indexOfSong = m_plm->GetCurrentIndex() + 1;         // zero based 
   pmvi->m_totalSongs = m_plm->CountItems(); 
 
   SendToUI(pEvent); 
 
   for (uint32 foobar = 0; foobar < pmvi->m_childEvents->size(); foobar++) 
   { 
      pe = (*pmvi->m_childEvents)[foobar]; 
      SendToUI(pe); 
   } 
 
   ReleaseUIManipLock(); 
 
   delete pEvent; 
} 
 
void  
Player:: 
HandleMediaTimeInfo(Event *pEvent) 
{ 
   if (m_playerState == PlayerState_Playing) 
   { 
      GetUIManipLock(); 
      SendToUI(pEvent); 
      ReleaseUIManipLock(); 
   } 
 
   delete pEvent; 
} 
 
void  
Player:: 
SendEventToUI(Event *pEvent) 
{ 
   GetUIManipLock(); 
   SendToUI(pEvent); 
   ReleaseUIManipLock(); 
   delete pEvent; 
} 
 
void 
Player:: 
SendEventToCatalog(Event *pEvent) 
{ 
    if (m_musicCatalog) 
        m_musicCatalog->AcceptEvent(pEvent); 
} 
 
#define _EQUALIZER_ENABLE_ 
#ifdef  _EQUALIZER_ENABLE_ 
void  
Player:: 
SetEQData(Event *pEvent) 
{ 
   if (m_pmo) 
   { 
       if (((SetEqualizerDataEvent *) pEvent)->IsEQData()) 
           m_lmc->SetEQData(((SetEqualizerDataEvent *) pEvent)->GetEQData()); 
       else 
           m_lmc->SetEQData(((SetEqualizerDataEvent *) pEvent)->GetEnableState()); 
   } 
   delete pEvent; 
} 
#endif // _EQUALIZER_ENABLE_ 
#undef  _EQUALIZER_ENABLE_ 
 
#define _VISUAL_ENABLE_ 
#ifdef  _VISUAL_ENABLE_ 
void  
Player:: 
SendVisBuf(Event *pEvent) 
{ 
   if (m_playerState == PlayerState_Playing) 
   { 
      GetUIManipLock(); 
      SendToUI(pEvent); 
      ReleaseUIManipLock(); 
   } 
   delete pEvent; 
} 
#endif // _VISUAL_ENABLE_ 
#undef  _VISUAL_ENABLE_ 
 
void 
Player:: 
ToggleUI(Event *pEvent) 
{ 
   switch (pEvent->Type())  
   { 
      case CMD_ToggleDownloadUI: { 
           if (!m_downloadUI) { 
              delete pEvent; 
              return; 
           } 
           m_downloadUI->AcceptEvent(pEvent); 
           break; } 
      case CMD_TogglePlaylistUI:  
      case CMD_ToggleMusicBrowserUI: { 
           if (!m_browserUI) { 
              delete pEvent; 
              return; 
           } 
           m_browserUI->AcceptEvent(pEvent); 
           break; } 
      default: 
           break; 
   } 
   delete pEvent; 
}  
 
int32  
Player:: 
ServiceEvent(Event * pC) 
{ 
    if (!pC) 
    { 
      return 255; 
    } 
 
    //printf("Got event %d\n", pC->Type()); 
    switch (pC->Type()) 
    { 
        case INFO_DoneOutputtingDueToError: 
        case INFO_DoneOutputting: 
            DoneOutputting(pC); 
            break; 
 
        case CMD_Stop: 
            Stop(pC); 
            break; 
 
        case CMD_GetVolume: 
            GetVolume(pC); 
            break; 
 
        case CMD_SetVolume: 
            SetVolume(pC); 
            break; 
 
        case CMD_ChangePosition: 
            ChangePosition(pC); 
            break; 
 
        case CMD_PlayPaused: 
            Play(pC); 
            break; 
 
        case CMD_Play: 
            Play(pC); 
            break; 
 
        case CMD_NextMediaPiece: 
            Next(pC);  
            break; 
 
        case CMD_PrevMediaPiece: 
            Previous(pC); 
            break; 
 
        case CMD_Pause: 
            Pause(pC); 
            break; 
 
        case CMD_UnPause: 
            UnPause(pC); 
            break; 
 
        case CMD_TogglePause: 
            TogglePause(pC); 
            break; 
 
        case CMD_QuitPlayer: 
            return Quit(pC); 
 
        case CMD_QueryPlayerState: 
            HandleQueryState(); 
            break; 
 
        case INFO_ReadyToDieUI: 
            return ReadyToDieUI(pC); 
 
        case INFO_MediaInfo: 
            HandleMediaInfo(pC); 
            break; 
 
        case INFO_MediaTimeInfo: 
            HandleMediaTimeInfo(pC); 
            break; 
 
        case INFO_PlaylistItemUpdated: 
            SendEventToCatalog(pC); 
            SendEventToUI(pC); 
            break; 
 
        case INFO_UserMessage: 
        case INFO_StatusMessage: 
        case INFO_BrowserMessage: 
        case INFO_ErrorMessage: 
        case INFO_PrefsChanged: 
        case INFO_StreamInfo: 
        case INFO_PlaylistShuffle: 
        case INFO_PlaylistRepeat: 
        case INFO_PlaylistUpdated: 
        case INFO_PlaylistItemAdded: 
        case INFO_PlaylistItemsAdded: 
        case INFO_PlaylistItemRemoved: 
        case INFO_PlaylistItemMoved: 
        case INFO_PlaylistSorted: 
        case INFO_PlaylistCurrentItemInfo: 
        case INFO_BufferStatus: 
        case INFO_SearchMusicDone: 
        case INFO_DownloadItemAdded: 
        case INFO_DownloadItemRemoved: 
        case INFO_DownloadItemNewState: 
        case INFO_DownloadItemProgress: 
        case INFO_MusicCatalogTrackAdded: 
        case INFO_MusicCatalogTrackRemoved: 
        case INFO_MusicCatalogPlaylistAdded: 
        case INFO_MusicCatalogPlaylistRemoved: 
        case INFO_MusicCatalogTrackChanged: 
        case INFO_MusicCatalogCleared: 
        case CMD_AddFiles: 
        case CMD_LoadTheme: 
        case CMD_ShowPreferences: 
            SendEventToUI(pC); 
            break; 
 
        case CMD_ToggleDownloadUI: 
        case CMD_TogglePlaylistUI: 
        case CMD_ToggleMusicBrowserUI: 
            ToggleUI(pC); 
            break; 
 
#define _EQUALIZER_ENABLE_ 
#ifdef  _EQUALIZER_ENABLE_ 
        case CMD_SetEQData: 
            SetEQData(pC); 
            break; 
 
#endif // _EQUALIZER_ENABLE_ 
#undef  _EQUALIZER_ENABLE_ 
 
#define _VISUAL_ENABLE_ 
#ifdef  _VISUAL_ENABLE_ 
        case CMD_SendVisBuf: 
            SendVisBuf(pC); 
            break; 
#endif // _VISUAL_ENABLE_ 
#undef  _VISUAL_ENABLE_ 
 
        default: 
            m_context->log->Error("serviceEvent: Unknown event: %d\n", 
            pC->Type()); 
            delete  pC; 
            break; 
    } 
 
    return 0; 
} 
 
Error      
Player:: 
PropertyChange(const char *pProp, PropValue * ppv) 
{ 
   Error     rtn = kError_UnknownErr; 
 
   return rtn; 
} 
 
void       
Player:: 
SendToUI(Event * pe) 
{ 
   uint32     i; 
 
   for (i = 0; i < m_uiList->size(); i++) 
   { 
      (*m_uiList)[i]->AcceptEvent(pe); 
   } 
} 
 
Error      
Player:: 
GetProperty(const char *pProp, PropValue ** ppVal) 
{ 
   return m_props.GetProperty(pProp, ppVal); 
} 
 
Error      
Player:: 
SetProperty(const char *pProp, PropValue * pVal) 
{ 
   return m_props.SetProperty(pProp, pVal); 
} 
 
Error      
Player:: 
RegisterPropertyWatcher(const char *pProp, PropertyWatcher * pPropWatch) 
{ 
   return m_props.RegisterPropertyWatcher(pProp, pPropWatch); 
} 
 
Error      
Player:: 
RemovePropertyWatcher(const char *pProp, PropertyWatcher * pPropWatch) 
{ 
   return m_props.RemovePropertyWatcher(pProp, pPropWatch); 
} 
 
/* 
   void Player::testQueue() { 
   Event *pC; 
 
   pC = m_eventQueue->Read(); 
   if (pC) { 
   cout << "testQueue: First failed!!" << endl; 
   } else { 
   cout << "testQueue: First succeded!!" << endl; 
   } 
   cout << "testQueue: IsEmpty(): " << m_eventQueue->IsEmpty() << endl; 
 
   pC = new Event(CMD_Play); 
   AcceptEvent(pC); 
   pC = new Event(CMD_Play); 
   AcceptEvent(pC); 
   pC = new Event(CMD_NextMediaPiece); 
   AcceptEvent(pC); 
 
   pC = m_eventQueue->Read(); 
   cout << "testQueue: " << pC->GetEvent() << endl; 
   delete pC; 
   pC = m_eventQueue->Read(); 
   cout << "testQueue: " << pC->GetEvent() << endl; 
   delete pC; 
   cout << "testQueue: IsEmpty(): " << m_eventQueue->IsEmpty() << endl; 
   pC = m_eventQueue->Read(); 
   cout << "testQueue: " << pC->GetEvent() << endl; 
   delete pC; 
   pC = m_eventQueue->Read(); 
   if (pC) { 
   cout << "testQueue: Failed!!!" << endl; 
   } else { 
   cout << "testQueue: Final Succeeded!!" << endl; 
   } 
   cout << "testQueue: IsEmpty(): " << m_eventQueue->IsEmpty() << endl; 
   } 
 */