2 * Copyright (C) 2005-2012 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
22 #include "ApplicationMessenger.h"
23 #include "Application.h"
25 #include "PlayListPlayer.h"
28 #include "interfaces/python/XBPython.h"
30 #include "pictures/GUIWindowSlideShow.h"
31 #include "interfaces/Builtins.h"
32 #include "network/Network.h"
33 #include "utils/log.h"
34 #include "utils/URIUtils.h"
35 #include "utils/Variant.h"
36 #include "guilib/GUIWindowManager.h"
37 #include "settings/Settings.h"
38 #include "settings/GUISettings.h"
40 #include "guilib/GUIDialog.h"
41 #include "GUIInfoManager.h"
42 #include "utils/Splash.h"
43 #include "cores/VideoRenderers/RenderManager.h"
44 #include "cores/AudioEngine/AEFactory.h"
45 #include "music/tags/MusicInfoTag.h"
47 #include "powermanagement/PowerManager.h"
50 #include "WIN32Util.h"
51 #define CHalManager CWIN32Util
52 #elif defined(TARGET_DARWIN)
53 #include "osx/CocoaInterface.h"
55 #include "addons/AddonCallbacks.h"
56 #include "addons/AddonCallbacksGUI.h"
57 #include "storage/MediaManager.h"
58 #include "guilib/LocalizeStrings.h"
59 #include "threads/SingleLock.h"
61 #include "playlists/PlayList.h"
64 #include "pvr/PVRManager.h"
65 #include "windows/GUIWindowLoginScreen.h"
69 using namespace MUSIC_INFO;
71 CDelayedMessage::CDelayedMessage(ThreadMessage& msg, unsigned int delay) : CThread("CDelayedMessage")
73 m_msg.dwMessage = msg.dwMessage;
74 m_msg.dwParam1 = msg.dwParam1;
75 m_msg.dwParam2 = msg.dwParam2;
76 m_msg.waitEvent = msg.waitEvent;
77 m_msg.lpVoid = msg.lpVoid;
78 m_msg.strParam = msg.strParam;
79 m_msg.params = msg.params;
84 void CDelayedMessage::Process()
89 CApplicationMessenger::Get().SendMessage(m_msg, false);
92 CApplicationMessenger& CApplicationMessenger::Get()
94 static CApplicationMessenger s_messenger;
98 CApplicationMessenger::CApplicationMessenger()
102 CApplicationMessenger::~CApplicationMessenger()
107 void CApplicationMessenger::Cleanup()
109 CSingleLock lock (m_critSection);
111 while (m_vecMessages.size() > 0)
113 ThreadMessage* pMsg = m_vecMessages.front();
116 pMsg->waitEvent->Set();
122 while (m_vecWindowMessages.size() > 0)
124 ThreadMessage* pMsg = m_vecWindowMessages.front();
127 pMsg->waitEvent->Set();
130 m_vecWindowMessages.pop();
134 void CApplicationMessenger::SendMessage(ThreadMessage& message, bool wait)
136 message.waitEvent.reset();
137 boost::shared_ptr<CEvent> waitEvent;
139 { // check that we're not being called from our application thread, else we'll be waiting
141 if (!g_application.IsCurrentThread())
143 message.waitEvent.reset(new CEvent(true));
144 waitEvent = message.waitEvent;
148 //OutputDebugString("Attempting to wait on a SendMessage() from our application thread will cause lockup!\n");
149 //OutputDebugString("Sending immediately\n");
150 ProcessMessage(&message);
155 CSingleLock lock (m_critSection);
157 if (g_application.m_bStop)
159 if (message.waitEvent)
160 message.waitEvent.reset();
164 ThreadMessage* msg = new ThreadMessage();
165 msg->dwMessage = message.dwMessage;
166 msg->dwParam1 = message.dwParam1;
167 msg->dwParam2 = message.dwParam2;
168 msg->waitEvent = message.waitEvent;
169 msg->lpVoid = message.lpVoid;
170 msg->strParam = message.strParam;
171 msg->params = message.params;
173 if (msg->dwMessage == TMSG_DIALOG_DOMODAL)
174 m_vecWindowMessages.push(msg);
176 m_vecMessages.push(msg);
177 lock.Leave(); // this releases the lock on the vec of messages and
178 // allows the ProcessMessage to execute and therefore
179 // delete the message itself. Therefore any accesss
180 // of the message itself after this point consittutes
181 // a race condition (yarc - "yet another race condition")
183 if (waitEvent) // ... it just so happens we have a spare reference to the
184 // waitEvent ... just for such contingencies :)
186 // ensure the thread doesn't hold the graphics lock
187 CSingleExit exit(g_graphicsContext);
192 void CApplicationMessenger::ProcessMessages()
194 // process threadmessages
195 CSingleLock lock (m_critSection);
196 while (m_vecMessages.size() > 0)
198 ThreadMessage* pMsg = m_vecMessages.front();
199 //first remove the message from the queue, else the message could be processed more then once
202 //Leave here as the message might make another
203 //thread call processmessages or sendmessage
205 boost::shared_ptr<CEvent> waitEvent = pMsg->waitEvent;
206 lock.Leave(); // <- see the large comment in SendMessage ^
208 ProcessMessage(pMsg);
217 void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg)
219 switch (pMsg->dwMessage)
223 switch (g_guiSettings.GetInt("powermanagement.shutdownstate"))
225 case POWERSTATE_SHUTDOWN:
229 case POWERSTATE_SUSPEND:
233 case POWERSTATE_HIBERNATE:
237 case POWERSTATE_QUIT:
241 case POWERSTATE_MINIMIZE:
245 case TMSG_RENDERER_FLUSH:
246 g_renderManager.Flush();
254 g_application.Stop(EXITCODE_POWERDOWN);
255 g_powerManager.Powerdown();
261 g_application.Stop(EXITCODE_QUIT);
267 g_PVRManager.SetWakeupCommand();
268 g_powerManager.Hibernate();
274 g_PVRManager.SetWakeupCommand();
275 g_powerManager.Suspend();
282 g_application.Stop(EXITCODE_REBOOT);
283 g_powerManager.Reboot();
287 case TMSG_RESTARTAPP:
289 #if defined(TARGET_WINDOWS) || defined(TARGET_LINUX)
290 g_application.Stop(EXITCODE_RESTARTAPP);
295 case TMSG_INHIBITIDLESHUTDOWN:
297 g_application.InhibitIdleShutdown(pMsg->dwParam1 != 0);
301 case TMSG_MEDIA_PLAY:
303 // first check if we were called from the PlayFile() function
304 if (pMsg->lpVoid && pMsg->dwParam2 == 0)
306 CFileItem *item = (CFileItem *)pMsg->lpVoid;
307 g_application.PlayFile(*item, pMsg->dwParam1 != 0);
311 // restore to previous window if needed
312 if (g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
313 g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
314 g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION)
315 g_windowManager.PreviousWindow();
317 g_application.ResetScreenSaver();
318 g_application.WakeUpScreenSaverAndDPMS();
320 //g_application.StopPlaying();
324 CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
326 if (list->Size() > 0)
328 int playlist = PLAYLIST_MUSIC;
329 for (int i = 0; i < list->Size(); i++)
331 if ((*list)[i]->IsVideo())
333 playlist = PLAYLIST_VIDEO;
338 g_playlistPlayer.ClearPlaylist(playlist);
339 g_playlistPlayer.SetCurrentPlaylist(playlist);
340 //For single item lists try PlayMedia. This covers some more cases where a playlist is not appropriate
341 //It will fall through to PlayFile
342 if (list->Size() == 1 && !(*list)[0]->IsPlayList())
343 g_application.PlayMedia(*((*list)[0]), playlist);
346 // Handle "shuffled" option if present
347 if (list->HasProperty("shuffled") && list->GetProperty("shuffled").isBoolean())
348 g_playlistPlayer.SetShuffle(playlist, list->GetProperty("shuffled").asBoolean(), false);
349 // Handle "repeat" option if present
350 if (list->HasProperty("repeat") && list->GetProperty("repeat").isInteger())
351 g_playlistPlayer.SetRepeat(playlist, (PLAYLIST::REPEAT_STATE)list->GetProperty("repeat").asInteger(), false);
353 g_playlistPlayer.Add(playlist, (*list));
354 g_playlistPlayer.Play(pMsg->dwParam1);
360 else if (pMsg->dwParam1 == PLAYLIST_MUSIC || pMsg->dwParam1 == PLAYLIST_VIDEO)
362 if (g_playlistPlayer.GetCurrentPlaylist() != (int)pMsg->dwParam1)
363 g_playlistPlayer.SetCurrentPlaylist(pMsg->dwParam1);
365 PlayListPlayerPlay(pMsg->dwParam2);
370 case TMSG_MEDIA_RESTART:
371 g_application.Restart(true);
374 case TMSG_PICTURE_SHOW:
376 CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
377 if (!pSlideShow) return ;
380 if (g_application.IsPlayingVideo()) g_application.StopPlaying();
382 if (g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO)
383 g_windowManager.PreviousWindow();
385 g_application.ResetScreenSaver();
386 g_application.WakeUpScreenSaverAndDPMS();
388 g_graphicsContext.Lock();
390 if (g_windowManager.GetActiveWindow() != WINDOW_SLIDESHOW)
391 g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
392 if (URIUtils::IsZIP(pMsg->strParam) || URIUtils::IsRAR(pMsg->strParam)) // actually a cbz/cbr
396 if (URIUtils::IsZIP(pMsg->strParam))
397 URIUtils::CreateArchivePath(strPath, "zip", pMsg->strParam.c_str(), "");
399 URIUtils::CreateArchivePath(strPath, "rar", pMsg->strParam.c_str(), "");
401 CUtil::GetRecursiveListing(strPath, items, g_settings.m_pictureExtensions);
402 if (items.Size() > 0)
405 for (int i=0;i<items.Size();++i)
407 pSlideShow->Add(items[i].get());
409 pSlideShow->Select(items[0]->GetPath());
414 CFileItem item(pMsg->strParam, false);
416 pSlideShow->Add(&item);
417 pSlideShow->Select(pMsg->strParam);
419 g_graphicsContext.Unlock();
423 case TMSG_PICTURE_SLIDESHOW:
425 CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
426 if (!pSlideShow) return ;
428 if (g_application.IsPlayingVideo())
429 g_application.StopPlaying();
431 g_graphicsContext.Lock();
435 CStdString strPath = pMsg->strParam;
436 CStdString extensions = g_settings.m_pictureExtensions;
438 extensions += "|.tbn";
439 CUtil::GetRecursiveListing(strPath, items, extensions);
441 if (items.Size() > 0)
443 for (int i=0;i<items.Size();++i)
444 pSlideShow->Add(items[i].get());
445 pSlideShow->StartSlideShow(); //Start the slideshow!
448 if (g_windowManager.GetActiveWindow() != WINDOW_SLIDESHOW)
450 if(items.Size() == 0)
452 g_guiSettings.SetString("screensaver.mode", "screensaver.xbmc.builtin.dim");
453 g_application.ActivateScreenSaver();
456 g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
459 g_graphicsContext.Unlock();
463 case TMSG_SETLANGUAGE:
464 g_guiSettings.SetLanguage(pMsg->strParam);
466 case TMSG_MEDIA_STOP:
468 // restore to previous window if needed
469 if (g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
470 g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
471 g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION)
472 g_windowManager.PreviousWindow();
474 g_application.ResetScreenSaver();
475 g_application.WakeUpScreenSaverAndDPMS();
478 if (g_application.IsPlaying()) g_application.StopPlaying();
482 case TMSG_MEDIA_PAUSE:
483 if (g_application.m_pPlayer)
485 g_application.ResetScreenSaver();
486 g_application.WakeUpScreenSaverAndDPMS();
487 g_application.m_pPlayer->Pause();
491 case TMSG_MEDIA_UNPAUSE:
492 if (g_application.IsPaused())
494 g_application.ResetScreenSaver();
495 g_application.WakeUpScreenSaverAndDPMS();
496 g_application.m_pPlayer->Pause();
500 case TMSG_SWITCHTOFULLSCREEN:
501 if( g_windowManager.GetActiveWindow() != WINDOW_FULLSCREEN_VIDEO )
502 g_application.SwitchToFullScreen();
505 case TMSG_TOGGLEFULLSCREEN:
506 g_graphicsContext.Lock();
507 g_graphicsContext.ToggleFullScreenRoot();
508 g_graphicsContext.Unlock();
512 g_application.Minimize();
515 case TMSG_EXECUTE_OS:
516 /* Suspend AE temporarily so exclusive or hog-mode sinks */
517 /* don't block external player's access to audio device */
518 if (!CAEFactory::Suspend())
520 CLog::Log(LOGNOTICE, "%s: Failed to suspend AudioEngine before launching external program",__FUNCTION__);
522 #if defined( _LINUX) && !defined(TARGET_DARWIN)
523 CUtil::RunCommandLine(pMsg->strParam.c_str(), (pMsg->dwParam1 == 1));
524 #elif defined(_WIN32)
525 CWIN32Util::XBMCShellExecute(pMsg->strParam.c_str(), (pMsg->dwParam1 == 1));
527 /* Resume AE processing of XBMC native audio */
528 if (!CAEFactory::Resume())
530 CLog::Log(LOGFATAL, "%s: Failed to restart AudioEngine after return from external player",__FUNCTION__);
534 case TMSG_EXECUTE_SCRIPT:
536 g_pythonParser.evalFile(pMsg->strParam.c_str(),ADDON::AddonPtr());
540 case TMSG_EXECUTE_BUILT_IN:
541 CBuiltins::Execute(pMsg->strParam.c_str());
544 case TMSG_PLAYLISTPLAYER_PLAY:
545 if (pMsg->dwParam1 != (DWORD) -1)
546 g_playlistPlayer.Play(pMsg->dwParam1);
548 g_playlistPlayer.Play();
551 case TMSG_PLAYLISTPLAYER_PLAY_SONG_ID:
552 if (pMsg->dwParam1 != (DWORD) -1)
554 bool *result = (bool*)pMsg->lpVoid;
555 *result = g_playlistPlayer.PlaySongId(pMsg->dwParam1);
558 g_playlistPlayer.Play();
561 case TMSG_PLAYLISTPLAYER_NEXT:
562 g_playlistPlayer.PlayNext();
565 case TMSG_PLAYLISTPLAYER_PREV:
566 g_playlistPlayer.PlayPrevious();
569 case TMSG_PLAYLISTPLAYER_ADD:
572 CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
574 g_playlistPlayer.Add(pMsg->dwParam1, (*list));
579 case TMSG_PLAYLISTPLAYER_INSERT:
582 CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
583 g_playlistPlayer.Insert(pMsg->dwParam1, (*list), pMsg->dwParam2);
588 case TMSG_PLAYLISTPLAYER_REMOVE:
589 if (pMsg->dwParam1 != (DWORD) -1)
590 g_playlistPlayer.Remove(pMsg->dwParam1,pMsg->dwParam2);
593 case TMSG_PLAYLISTPLAYER_CLEAR:
594 g_playlistPlayer.ClearPlaylist(pMsg->dwParam1);
597 case TMSG_PLAYLISTPLAYER_SHUFFLE:
598 g_playlistPlayer.SetShuffle(pMsg->dwParam1, pMsg->dwParam2 > 0);
601 case TMSG_PLAYLISTPLAYER_REPEAT:
602 g_playlistPlayer.SetRepeat(pMsg->dwParam1, (PLAYLIST::REPEAT_STATE)pMsg->dwParam2);
605 case TMSG_PLAYLISTPLAYER_GET_ITEMS:
608 PLAYLIST::CPlayList playlist = g_playlistPlayer.GetPlaylist(pMsg->dwParam1);
609 CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
611 for (int i = 0; i < playlist.size(); i++)
612 list->Add(CFileItemPtr(new CFileItem(*playlist[i])));
616 case TMSG_PLAYLISTPLAYER_SWAP:
619 vector<int> *indexes = (vector<int> *)pMsg->lpVoid;
620 if (indexes->size() == 2)
621 g_playlistPlayer.Swap(pMsg->dwParam1, indexes->at(0), indexes->at(1));
626 // Window messages below here...
627 case TMSG_DIALOG_DOMODAL: //doModel of window
629 CGUIDialog* pDialog = (CGUIDialog*)g_windowManager.GetWindow(pMsg->dwParam1);
630 if (!pDialog) return ;
635 case TMSG_NETWORKMESSAGE:
637 g_application.getNetwork().NetworkMessage((CNetwork::EMESSAGE)pMsg->dwParam1, (int)pMsg->dwParam2);
641 case TMSG_GUI_DO_MODAL:
643 CGUIDialog *pDialog = (CGUIDialog *)pMsg->lpVoid;
645 pDialog->DoModal((int)pMsg->dwParam1, pMsg->strParam);
651 CGUIDialog *pDialog = (CGUIDialog *)pMsg->lpVoid;
657 case TMSG_GUI_WINDOW_CLOSE:
659 CGUIWindow *window = (CGUIWindow *)pMsg->lpVoid;
661 window->Close(pMsg->dwParam2 & 0x1 ? true : false, pMsg->dwParam1, pMsg->dwParam2 & 0x2 ? true : false);
665 case TMSG_GUI_ACTIVATE_WINDOW:
667 g_windowManager.ActivateWindow(pMsg->dwParam1, pMsg->params, pMsg->dwParam2 > 0);
671 case TMSG_GUI_ADDON_DIALOG:
674 { // TODO: This is ugly - really these python dialogs should just be normal XBMC dialogs
675 ((ADDON::CGUIAddonWindowDialog *) pMsg->lpVoid)->Show_Internal(pMsg->dwParam2 > 0);
680 case TMSG_GUI_PYTHON_DIALOG:
682 // This hack is not much better but at least I don't need to make ApplicationMessenger
683 // know about Addon (Python) specific classes.
684 CAction caction(pMsg->dwParam1);
685 ((CGUIWindow*)pMsg->lpVoid)->OnAction(caction);
689 case TMSG_GUI_ACTION:
693 CAction *action = (CAction *)pMsg->lpVoid;
694 if (pMsg->dwParam1 == WINDOW_INVALID)
695 g_application.OnAction(*action);
698 CGUIWindow *pWindow = g_windowManager.GetWindow(pMsg->dwParam1);
700 pWindow->OnAction(*action);
702 CLog::Log(LOGWARNING, "Failed to get window with ID %i to send an action to", pMsg->dwParam1);
709 case TMSG_GUI_MESSAGE:
713 CGUIMessage *message = (CGUIMessage *)pMsg->lpVoid;
714 g_windowManager.SendMessage(*message, pMsg->dwParam1);
720 case TMSG_GUI_INFOLABEL:
724 vector<CStdString> *infoLabels = (vector<CStdString> *)pMsg->lpVoid;
725 for (unsigned int i = 0; i < pMsg->params.size(); i++)
726 infoLabels->push_back(g_infoManager.GetLabel(g_infoManager.TranslateString(pMsg->params[i])));
730 case TMSG_GUI_INFOBOOL:
734 vector<bool> *infoLabels = (vector<bool> *)pMsg->lpVoid;
735 for (unsigned int i = 0; i < pMsg->params.size(); i++)
736 infoLabels->push_back(g_infoManager.EvaluateBool(pMsg->params[i]));
743 ThreadMessageCallback *callback = (ThreadMessageCallback*)pMsg->lpVoid;
744 callback->callback(callback->userptr);
748 case TMSG_VOLUME_SHOW:
750 CAction action((int)pMsg->dwParam1);
751 g_application.ShowVolumeBar(&action);
755 case TMSG_SPLASH_MESSAGE:
757 if (g_application.GetSplash())
758 g_application.GetSplash()->Show(pMsg->strParam);
762 case TMSG_DISPLAY_SETUP:
764 *((bool*)pMsg->lpVoid) = g_application.InitWindow();
765 g_application.SetRenderGUI(true);
769 case TMSG_DISPLAY_DESTROY:
771 *((bool*)pMsg->lpVoid) = g_application.DestroyWindow();
772 g_application.SetRenderGUI(false);
776 case TMSG_UPDATE_CURRENT_ITEM:
778 CFileItem* item = (CFileItem*)pMsg->lpVoid;
781 if (pMsg->dwParam1 == 1 && item->HasMusicInfoTag()) // only grab music tag
782 g_infoManager.SetCurrentSongTag(*item->GetMusicInfoTag());
783 else if (pMsg->dwParam1 == 2 && item->HasVideoInfoTag()) // only grab video tag
784 g_infoManager.SetCurrentVideoTag(*item->GetVideoInfoTag());
786 g_infoManager.SetCurrentItem(*item);
791 case TMSG_LOADPROFILE:
793 CGUIWindowLoginScreen::LoadProfile(pMsg->dwParam1);
799 void CApplicationMessenger::ProcessWindowMessages()
801 CSingleLock lock (m_critSection);
802 //message type is window, process window messages
803 while (m_vecWindowMessages.size() > 0)
805 ThreadMessage* pMsg = m_vecWindowMessages.front();
806 //first remove the message from the queue, else the message could be processed more then once
807 m_vecWindowMessages.pop();
809 // leave here in case we make more thread messages from this one
811 boost::shared_ptr<CEvent> waitEvent = pMsg->waitEvent;
812 lock.Leave(); // <- see the large comment in SendMessage ^
814 ProcessMessage(pMsg);
823 int CApplicationMessenger::SetResponse(CStdString response)
825 CSingleLock lock (m_critBuffer);
826 bufferResponse=response;
831 CStdString CApplicationMessenger::GetResponse()
834 CSingleLock lock (m_critBuffer);
840 void CApplicationMessenger::ExecBuiltIn(const CStdString &command, bool wait)
842 ThreadMessage tMsg = {TMSG_EXECUTE_BUILT_IN};
843 tMsg.strParam = command;
844 SendMessage(tMsg, wait);
847 void CApplicationMessenger::MediaPlay(string filename)
849 CFileItem item(filename, false);
853 void CApplicationMessenger::MediaPlay(const CFileItem &item)
856 list.Add(CFileItemPtr(new CFileItem(item)));
861 void CApplicationMessenger::MediaPlay(const CFileItemList &list, int song)
863 ThreadMessage tMsg = {TMSG_MEDIA_PLAY};
864 CFileItemList* listcopy = new CFileItemList();
865 listcopy->Copy(list);
866 tMsg.lpVoid = (void*)listcopy;
867 tMsg.dwParam1 = song;
869 SendMessage(tMsg, true);
872 void CApplicationMessenger::MediaPlay(int playlistid, int song /* = -1 */)
874 ThreadMessage tMsg = {TMSG_MEDIA_PLAY};
876 tMsg.dwParam1 = playlistid;
877 tMsg.dwParam2 = song;
878 SendMessage(tMsg, true);
881 void CApplicationMessenger::PlayFile(const CFileItem &item, bool bRestart /*= false*/)
883 ThreadMessage tMsg = {TMSG_MEDIA_PLAY};
884 CFileItem *pItem = new CFileItem(item);
885 tMsg.lpVoid = (void *)pItem;
886 tMsg.dwParam1 = bRestart ? 1 : 0;
888 SendMessage(tMsg, false);
891 void CApplicationMessenger::MediaStop(bool bWait /* = true */)
893 ThreadMessage tMsg = {TMSG_MEDIA_STOP};
894 SendMessage(tMsg, bWait);
897 void CApplicationMessenger::MediaPause()
899 ThreadMessage tMsg = {TMSG_MEDIA_PAUSE};
900 SendMessage(tMsg, true);
903 void CApplicationMessenger::MediaRestart(bool bWait)
905 ThreadMessage tMsg = {TMSG_MEDIA_RESTART};
906 SendMessage(tMsg, bWait);
909 void CApplicationMessenger::PlayListPlayerPlay()
911 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_PLAY, (DWORD) -1};
912 SendMessage(tMsg, true);
915 void CApplicationMessenger::PlayListPlayerPlay(int iSong)
917 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_PLAY, (DWORD)iSong};
918 SendMessage(tMsg, true);
921 bool CApplicationMessenger::PlayListPlayerPlaySongId(int songId)
924 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_PLAY_SONG_ID, (DWORD)songId};
925 tMsg.lpVoid = (void *)&returnState;
926 SendMessage(tMsg, true);
930 void CApplicationMessenger::PlayListPlayerNext()
932 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_NEXT};
933 SendMessage(tMsg, true);
936 void CApplicationMessenger::PlayListPlayerPrevious()
938 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_PREV};
939 SendMessage(tMsg, true);
942 void CApplicationMessenger::PlayListPlayerAdd(int playlist, const CFileItem &item)
945 list.Add(CFileItemPtr(new CFileItem(item)));
947 PlayListPlayerAdd(playlist, list);
950 void CApplicationMessenger::PlayListPlayerAdd(int playlist, const CFileItemList &list)
952 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_ADD};
953 CFileItemList* listcopy = new CFileItemList();
954 listcopy->Copy(list);
955 tMsg.lpVoid = (void*)listcopy;
956 tMsg.dwParam1 = playlist;
957 SendMessage(tMsg, true);
960 void CApplicationMessenger::PlayListPlayerInsert(int playlist, const CFileItem &item, int index)
963 list.Add(CFileItemPtr(new CFileItem(item)));
964 PlayListPlayerInsert(playlist, list, index);
967 void CApplicationMessenger::PlayListPlayerInsert(int playlist, const CFileItemList &list, int index)
969 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_INSERT};
970 CFileItemList* listcopy = new CFileItemList();
971 listcopy->Copy(list);
972 tMsg.lpVoid = (void *)listcopy;
973 tMsg.dwParam1 = playlist;
974 tMsg.dwParam2 = index;
975 SendMessage(tMsg, true);
978 void CApplicationMessenger::PlayListPlayerRemove(int playlist, int position)
980 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_REMOVE, (DWORD)playlist, (DWORD)position};
981 SendMessage(tMsg, true);
984 void CApplicationMessenger::PlayListPlayerClear(int playlist)
986 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_CLEAR};
987 tMsg.dwParam1 = playlist;
988 SendMessage(tMsg, true);
991 void CApplicationMessenger::PlayListPlayerShuffle(int playlist, bool shuffle)
993 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_SHUFFLE};
994 tMsg.dwParam1 = playlist;
995 tMsg.dwParam2 = shuffle ? 1 : 0;
996 SendMessage(tMsg, true);
999 void CApplicationMessenger::PlayListPlayerGetItems(int playlist, CFileItemList &list)
1001 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_GET_ITEMS};
1002 tMsg.dwParam1 = playlist;
1003 tMsg.lpVoid = (void *)&list;
1004 SendMessage(tMsg, true);
1007 void CApplicationMessenger::PlayListPlayerSwap(int playlist, int indexItem1, int indexItem2)
1009 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_SWAP};
1010 tMsg.dwParam1 = playlist;
1011 vector<int> *indexes = new vector<int>();
1012 indexes->push_back(indexItem1);
1013 indexes->push_back(indexItem2);
1014 tMsg.lpVoid = (void *)indexes;
1015 SendMessage(tMsg, true);
1018 void CApplicationMessenger::PlayListPlayerRepeat(int playlist, int repeatState)
1020 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_REPEAT};
1021 tMsg.dwParam1 = playlist;
1022 tMsg.dwParam2 = repeatState;
1023 SendMessage(tMsg, true);
1026 void CApplicationMessenger::PictureShow(string filename)
1028 ThreadMessage tMsg = {TMSG_PICTURE_SHOW};
1029 tMsg.strParam = filename;
1033 void CApplicationMessenger::PictureSlideShow(string pathname, bool addTBN /* = false */)
1035 DWORD dwMessage = TMSG_PICTURE_SLIDESHOW;
1036 ThreadMessage tMsg = {dwMessage};
1037 tMsg.strParam = pathname;
1038 tMsg.dwParam1 = addTBN ? 1 : 0;
1042 void CApplicationMessenger::SetGUILanguage(const std::string &strLanguage)
1044 ThreadMessage tMsg = {TMSG_SETLANGUAGE};
1045 tMsg.strParam = strLanguage;
1049 void CApplicationMessenger::Shutdown()
1051 ThreadMessage tMsg = {TMSG_SHUTDOWN};
1055 void CApplicationMessenger::Powerdown()
1057 ThreadMessage tMsg = {TMSG_POWERDOWN};
1061 void CApplicationMessenger::Quit()
1063 ThreadMessage tMsg = {TMSG_QUIT};
1067 void CApplicationMessenger::Hibernate()
1069 ThreadMessage tMsg = {TMSG_HIBERNATE};
1073 void CApplicationMessenger::Suspend()
1075 ThreadMessage tMsg = {TMSG_SUSPEND};
1079 void CApplicationMessenger::Restart()
1081 ThreadMessage tMsg = {TMSG_RESTART};
1085 void CApplicationMessenger::Reset()
1087 ThreadMessage tMsg = {TMSG_RESET};
1091 void CApplicationMessenger::RestartApp()
1093 ThreadMessage tMsg = {TMSG_RESTARTAPP};
1097 void CApplicationMessenger::InhibitIdleShutdown(bool inhibit)
1099 ThreadMessage tMsg = {TMSG_INHIBITIDLESHUTDOWN, (DWORD)inhibit};
1103 void CApplicationMessenger::NetworkMessage(DWORD dwMessage, DWORD dwParam)
1105 ThreadMessage tMsg = {TMSG_NETWORKMESSAGE, dwMessage, dwParam};
1109 void CApplicationMessenger::SwitchToFullscreen()
1111 /* FIXME: ideally this call should return upon a successfull switch but currently
1112 is causing deadlocks between the dvdplayer destructor and the rendermanager
1114 ThreadMessage tMsg = {TMSG_SWITCHTOFULLSCREEN};
1115 SendMessage(tMsg, false);
1118 void CApplicationMessenger::Minimize(bool wait)
1120 ThreadMessage tMsg = {TMSG_MINIMIZE};
1121 SendMessage(tMsg, wait);
1124 void CApplicationMessenger::DoModal(CGUIDialog *pDialog, int iWindowID, const CStdString ¶m)
1126 ThreadMessage tMsg = {TMSG_GUI_DO_MODAL};
1127 tMsg.lpVoid = pDialog;
1128 tMsg.dwParam1 = (DWORD)iWindowID;
1129 tMsg.strParam = param;
1130 SendMessage(tMsg, true);
1133 void CApplicationMessenger::ExecOS(const CStdString command, bool waitExit)
1135 ThreadMessage tMsg = {TMSG_EXECUTE_OS};
1136 tMsg.strParam = command;
1137 tMsg.dwParam1 = (DWORD)waitExit;
1138 SendMessage(tMsg, false);
1141 void CApplicationMessenger::UserEvent(int code)
1143 ThreadMessage tMsg = {(DWORD)code};
1144 SendMessage(tMsg, false);
1147 void CApplicationMessenger::Show(CGUIDialog *pDialog)
1149 ThreadMessage tMsg = {TMSG_GUI_SHOW};
1150 tMsg.lpVoid = pDialog;
1151 SendMessage(tMsg, true);
1154 void CApplicationMessenger::Close(CGUIWindow *window, bool forceClose, bool waitResult /*= true*/, int nextWindowID /*= 0*/, bool enableSound /*= true*/)
1156 ThreadMessage tMsg = {TMSG_GUI_WINDOW_CLOSE, (DWORD)nextWindowID};
1157 tMsg.dwParam2 = (DWORD)((forceClose ? 0x01 : 0) | (enableSound ? 0x02 : 0));
1158 tMsg.lpVoid = window;
1159 SendMessage(tMsg, waitResult);
1162 void CApplicationMessenger::ActivateWindow(int windowID, const vector<CStdString> ¶ms, bool swappingWindows)
1164 ThreadMessage tMsg = {TMSG_GUI_ACTIVATE_WINDOW, (DWORD)windowID, swappingWindows ? 1u : 0u};
1165 tMsg.params = params;
1166 SendMessage(tMsg, true);
1169 void CApplicationMessenger::SendAction(const CAction &action, int windowID, bool waitResult)
1171 ThreadMessage tMsg = {TMSG_GUI_ACTION};
1172 tMsg.dwParam1 = windowID;
1173 tMsg.lpVoid = new CAction(action);
1174 SendMessage(tMsg, waitResult);
1177 void CApplicationMessenger::SendGUIMessage(const CGUIMessage &message, int windowID, bool waitResult)
1179 ThreadMessage tMsg = {TMSG_GUI_MESSAGE};
1180 tMsg.dwParam1 = windowID == WINDOW_INVALID ? 0 : windowID;
1181 tMsg.lpVoid = new CGUIMessage(message);
1182 SendMessage(tMsg, waitResult);
1185 vector<CStdString> CApplicationMessenger::GetInfoLabels(const vector<CStdString> &properties)
1187 vector<CStdString> infoLabels;
1189 ThreadMessage tMsg = {TMSG_GUI_INFOLABEL};
1190 tMsg.params = properties;
1191 tMsg.lpVoid = (void*)&infoLabels;
1192 SendMessage(tMsg, true);
1196 vector<bool> CApplicationMessenger::GetInfoBooleans(const vector<CStdString> &properties)
1198 vector<bool> infoLabels;
1200 ThreadMessage tMsg = {TMSG_GUI_INFOBOOL};
1201 tMsg.params = properties;
1202 tMsg.lpVoid = (void*)&infoLabels;
1203 SendMessage(tMsg, true);
1207 void CApplicationMessenger::ShowVolumeBar(bool up)
1209 ThreadMessage tMsg = {TMSG_VOLUME_SHOW};
1210 tMsg.dwParam1 = up ? ACTION_VOLUME_UP : ACTION_VOLUME_DOWN;
1211 SendMessage(tMsg, false);
1214 void CApplicationMessenger::SetSplashMessage(const CStdString& message)
1216 ThreadMessage tMsg = {TMSG_SPLASH_MESSAGE};
1217 tMsg.strParam = message;
1218 SendMessage(tMsg, true);
1221 void CApplicationMessenger::SetSplashMessage(int stringID)
1223 SetSplashMessage(g_localizeStrings.Get(stringID));
1226 bool CApplicationMessenger::SetupDisplay()
1230 ThreadMessage tMsg = {TMSG_DISPLAY_SETUP};
1231 tMsg.lpVoid = (void*)&result;
1232 SendMessage(tMsg, true);
1237 bool CApplicationMessenger::DestroyDisplay()
1241 ThreadMessage tMsg = {TMSG_DISPLAY_DESTROY};
1242 tMsg.lpVoid = (void*)&result;
1243 SendMessage(tMsg, true);
1248 void CApplicationMessenger::SetCurrentSongTag(const CMusicInfoTag& tag)
1250 CFileItem* item = new CFileItem(tag);
1251 ThreadMessage tMsg = {TMSG_UPDATE_CURRENT_ITEM};
1253 tMsg.lpVoid = (void*)item;
1254 SendMessage(tMsg, false);
1257 void CApplicationMessenger::SetCurrentVideoTag(const CVideoInfoTag& tag)
1259 CFileItem* item = new CFileItem(tag);
1260 ThreadMessage tMsg = {TMSG_UPDATE_CURRENT_ITEM};
1262 tMsg.lpVoid = (void*)item;
1263 SendMessage(tMsg, false);
1266 void CApplicationMessenger::SetCurrentItem(const CFileItem& item)
1268 CFileItem* item2 = new CFileItem(item);
1269 ThreadMessage tMsg = {TMSG_UPDATE_CURRENT_ITEM};
1270 tMsg.lpVoid = (void*)item2;
1271 SendMessage(tMsg, false);
1274 void CApplicationMessenger::LoadProfile(unsigned int idx)
1276 ThreadMessage tMsg = {TMSG_LOADPROFILE};
1277 tMsg.dwParam1 = idx;
1278 SendMessage(tMsg, false);