//////////////////////////////////////////////////////////////////////// // This file is part of the mp3car-0.1.1 package // Linux LCD-client for the mp3 server box // http://www.igalaxie.com/ltt/mp3 //////////////////////////////////////////////////////////////////////// // // 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. ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // File: appbase.cc ////////////////////////////////////////////////////////////////////////// // Description: Basic application object ////////////////////////////////////////////////////////////////////////// // History: created 05.01.2000 ////////////////////////////////////////////////////////////////////////// // Copyright: 2000 Sebastian Poetschke ////////////////////////////////////////////////////////////////////////// #include #include #include #include "appbase.h" #include "adisplay.h" #include "acontrol.h" #include "dbclient.h" #include "sbclient.h" #include "commands.h" #include "imenu.h" #include "iartists.h" #include "isongs.h" #include "igenres.h" #include "istatus.h" #include "ialbums.h" ///////////////////////////////////////////////////////////////// // Constructor ///////////////////////////////////////////////////////////////// appBase::appBase(ADisplay *pDspDrv, AControl *pCtlDrv, mysqlClient * pDBC, mp3sbClient * pSBC) { pDB = pDBC; pSB = pSBC; pDisplay = pDspDrv; pControl = pCtlDrv; m_tControlMsg = time(NULL); } ///////////////////////////////////////////////////////////////// // Destructor ///////////////////////////////////////////////////////////////// appBase::~appBase() { } ///////////////////////////////////////////////////////////////// // Public Interface ///////////////////////////////////////////////////////////////// bool appBase::Initialize() { // Initialize display driver. if (pDisplay) { if (!pDisplay->Initialize()) return false; pDisplay->Backlight( true ); pDisplay->Contrast( 80 ); pDisplay->Cursor( false ); pDisplay->Blink( false ); pDisplay->Cursor( false ); pDisplay->ClearScreen(); pDisplay->Write(" MP3CAR v0.1 ", 2, 1); //sleep(2); } else return false; if (pthread_mutex_init(&m_pThreadMutex, NULL)!=0) { pDisplay->ClearScreen(); pDisplay->Write("Mutex init failed", 1, 1); return false; } // Initialize control driver. if (pControl) { if (!pControl->Initialize(this)) { pDisplay->ClearScreen(); pDisplay->Write("IR init failed", 1, 1); return false; } } else return false; // Connect serverbox and database client if ( pDB!=NULL && pSB!=NULL ) { if (pDB->Connect()==false) { pDisplay->ClearScreen(); pDisplay->Write("DB init failed", 1, 1); return false; } if (pSB->Connect(this, 15)==false) { pDisplay->ClearScreen(); pDisplay->Write("IR init failed", 1, 1); return false; } } else return false; // Create the menu window. appWin *pWin = dynamic_cast (new iMenu(this)); if (pWin) AppStack.insert(AppStack.end(), 1, pWin); else return false; return true; } bool appBase::CreateApp(unsigned int AppID) { switch (AppID) { case APP_MENU: { appWin *pWin = dynamic_cast (new iMenu(this)); if (pWin) { AppStack.insert(AppStack.end(), 1, pWin); return true; } else return false; } case APP_ARTISTS: { appWin *pWin = dynamic_cast (new iArtists(this)); if (pWin) { AppStack.insert(AppStack.end(), 1, pWin); return true; } else return false; } case APP_SONGS: { appWin *pWin = dynamic_cast (new iSongs(this)); if (pWin) { AppStack.insert(AppStack.end(), 1, pWin); return true; } else return false; } case APP_GENRES: { appWin *pWin = dynamic_cast (new iGenres(this)); if (pWin) { AppStack.insert(AppStack.end(), 1, pWin); return true; } else return false; } case APP_ALBUMS: { appWin *pWin = dynamic_cast (new iAlbums(this)); if (pWin) { AppStack.insert(AppStack.end(), 1, pWin); return true; } else return false; } case APP_STATUS: { appWin *pWin = dynamic_cast (new iStatus(this)); if (pWin) { AppStack.insert(AppStack.end(), 1, pWin); return true; } else return false; } } return false; } bool appBase::CreateApp(unsigned int AppID, char * Data) { switch (AppID) { case APP_MENU: { appWin *pWin = dynamic_cast (new iMenu(this, Data)); if (pWin) { AppStack.insert(AppStack.end(), 1, pWin); return true; } else return false; } case APP_ARTISTS: { appWin *pWin = dynamic_cast (new iArtists(this, Data)); if (pWin) { AppStack.insert(AppStack.end(), 1, pWin); return true; } else return false; } case APP_SONGS: { appWin *pWin = dynamic_cast (new iSongs(this, Data)); if (pWin) { AppStack.insert(AppStack.end(), 1, pWin); return true; } else return false; } case APP_GENRES: { appWin *pWin = dynamic_cast (new iGenres(this, Data)); if (pWin) { AppStack.insert(AppStack.end(), 1, pWin); return true; } else return false; } case APP_ALBUMS: { appWin *pWin = dynamic_cast (new iAlbums(this, Data)); if (pWin) { AppStack.insert(AppStack.end(), 1, pWin); return true; } else return false; } case APP_STATUS: { appWin *pWin = dynamic_cast (new iStatus(this, Data)); if (pWin) { AppStack.insert(AppStack.end(), 1, pWin); return true; } else return false; } } return false; } void appBase::Execute() { // active application should process user input while (AppStack.size()>0) { ScheduleStatus(); if (AppStack[AppStack.size()-1]->WinProc(GetMessage())==true) { appWin *pWin = AppStack[AppStack.size()-1]; AppStack.erase(AppStack.end()-1, AppStack.end()); delete pWin; if (AppStack.size()>0) // update underlaying dialog AppStack[AppStack.size()-1]->WinProc(CMD_SHOWDLG); } usleep(1); } pDisplay->ClearScreen(); pDisplay->Write("Exit gracefully", 1, 1); } bool appBase::SpoolMessage(unsigned int msg ) { // put the message into the queue // but take care about multithreading pthread_mutex_lock(&m_pThreadMutex); // save time stamp of control actions if (msg==CMD_OK || msg==CMD_CANCEL || msg==CMD_LEFT || msg==CMD_RIGHT || msg==CMD_UP || msg==CMD_DOWN) m_tControlMsg = time(NULL); MessageQueue.insert(MessageQueue.end(), 1, msg); pthread_mutex_unlock(&m_pThreadMutex); return true; } mysqlClient * appBase::GetDB() { return pDB; } mp3sbClient * appBase::GetSB() { return pSB; } ADisplay * appBase::GetDisplay() { return pDisplay; } ///////////////////////////////////////////////////////////////// // Protected member functions ///////////////////////////////////////////////////////////////// unsigned int appBase::GetMessage() { // return the latest message from the queue // and erase it from the bag unsigned int cmd = CMD_IDLE; pthread_mutex_lock(&m_pThreadMutex); if (MessageQueue.size()>0) { cmd = MessageQueue[0]; MessageQueue.erase(MessageQueue.begin()); } pthread_mutex_unlock(&m_pThreadMutex); return cmd; } void appBase::ScheduleStatus() { // we have at least one app running (menu is always active) if (AppStack.size()>=1) { // check if a status window is already running if (AppStack[AppStack.size()-1]->Type()!=APP_STATUS) { // when did the user last control action if (time(NULL)-m_tControlMsg>7) CreateApp(APP_STATUS); } } }