2 * Copyright (C) 2005-2013 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"
26 #include "PlayListPlayer.h"
29 #include "interfaces/python/XBPython.h"
31 #include "pictures/GUIWindowSlideShow.h"
32 #include "interfaces/Builtins.h"
33 #include "network/Network.h"
34 #include "utils/log.h"
35 #include "utils/URIUtils.h"
36 #include "utils/Variant.h"
37 #include "guilib/GUIWindowManager.h"
38 #include "settings/AdvancedSettings.h"
39 #include "settings/Settings.h"
41 #include "guilib/GUIDialog.h"
42 #include "guilib/Key.h"
43 #include "GUIInfoManager.h"
44 #include "utils/Splash.h"
45 #include "cores/IPlayer.h"
46 #include "cores/VideoRenderers/RenderManager.h"
47 #include "cores/AudioEngine/AEFactory.h"
48 #include "music/tags/MusicInfoTag.h"
50 #include "powermanagement/PowerManager.h"
53 #include "WIN32Util.h"
54 #define CHalManager CWIN32Util
55 #elif defined(TARGET_DARWIN)
56 #include "osx/CocoaInterface.h"
58 #include "addons/AddonCallbacks.h"
59 #include "addons/AddonCallbacksGUI.h"
60 #include "storage/MediaManager.h"
61 #include "guilib/LocalizeStrings.h"
62 #include "threads/SingleLock.h"
64 #include "playlists/PlayList.h"
67 #include "pvr/PVRManager.h"
68 #include "windows/GUIWindowLoginScreen.h"
70 #include "utils/GlobalsHandling.h"
71 #if defined(TARGET_ANDROID)
72 #include "xbmc/android/activity/XBMCApp.h"
77 using namespace MUSIC_INFO;
79 CDelayedMessage::CDelayedMessage(ThreadMessage& msg, unsigned int delay) : CThread("DelayedMessage")
81 m_msg.dwMessage = msg.dwMessage;
82 m_msg.dwParam1 = msg.dwParam1;
83 m_msg.dwParam2 = msg.dwParam2;
84 m_msg.waitEvent = msg.waitEvent;
85 m_msg.lpVoid = msg.lpVoid;
86 m_msg.strParam = msg.strParam;
87 m_msg.params = msg.params;
92 void CDelayedMessage::Process()
97 CApplicationMessenger::Get().SendMessage(m_msg, false);
101 CApplicationMessenger& CApplicationMessenger::Get()
106 CApplicationMessenger::CApplicationMessenger()
110 CApplicationMessenger::~CApplicationMessenger()
115 void CApplicationMessenger::Cleanup()
117 CSingleLock lock (m_critSection);
119 while (m_vecMessages.size() > 0)
121 ThreadMessage* pMsg = m_vecMessages.front();
124 pMsg->waitEvent->Set();
130 while (m_vecWindowMessages.size() > 0)
132 ThreadMessage* pMsg = m_vecWindowMessages.front();
135 pMsg->waitEvent->Set();
138 m_vecWindowMessages.pop();
142 void CApplicationMessenger::SendMessage(ThreadMessage& message, bool wait)
144 message.waitEvent.reset();
145 boost::shared_ptr<CEvent> waitEvent;
147 { // check that we're not being called from our application thread, else we'll be waiting
149 if (!g_application.IsCurrentThread())
151 message.waitEvent.reset(new CEvent(true));
152 waitEvent = message.waitEvent;
156 //OutputDebugString("Attempting to wait on a SendMessage() from our application thread will cause lockup!\n");
157 //OutputDebugString("Sending immediately\n");
158 ProcessMessage(&message);
163 CSingleLock lock (m_critSection);
165 if (g_application.m_bStop)
167 if (message.waitEvent)
168 message.waitEvent.reset();
172 ThreadMessage* msg = new ThreadMessage();
173 msg->dwMessage = message.dwMessage;
174 msg->dwParam1 = message.dwParam1;
175 msg->dwParam2 = message.dwParam2;
176 msg->waitEvent = message.waitEvent;
177 msg->lpVoid = message.lpVoid;
178 msg->strParam = message.strParam;
179 msg->params = message.params;
181 if (msg->dwMessage == TMSG_DIALOG_DOMODAL)
182 m_vecWindowMessages.push(msg);
184 m_vecMessages.push(msg);
185 lock.Leave(); // this releases the lock on the vec of messages and
186 // allows the ProcessMessage to execute and therefore
187 // delete the message itself. Therefore any accesss
188 // of the message itself after this point consittutes
189 // a race condition (yarc - "yet another race condition")
191 if (waitEvent) // ... it just so happens we have a spare reference to the
192 // waitEvent ... just for such contingencies :)
194 // ensure the thread doesn't hold the graphics lock
195 CSingleExit exit(g_graphicsContext);
200 void CApplicationMessenger::ProcessMessages()
202 // process threadmessages
203 CSingleLock lock (m_critSection);
204 while (m_vecMessages.size() > 0)
206 ThreadMessage* pMsg = m_vecMessages.front();
207 //first remove the message from the queue, else the message could be processed more then once
210 //Leave here as the message might make another
211 //thread call processmessages or sendmessage
213 boost::shared_ptr<CEvent> waitEvent = pMsg->waitEvent;
214 lock.Leave(); // <- see the large comment in SendMessage ^
216 ProcessMessage(pMsg);
225 void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg)
227 switch (pMsg->dwMessage)
231 switch (CSettings::Get().GetInt("powermanagement.shutdownstate"))
233 case POWERSTATE_SHUTDOWN:
237 case POWERSTATE_SUSPEND:
241 case POWERSTATE_HIBERNATE:
245 case POWERSTATE_QUIT:
249 case POWERSTATE_MINIMIZE:
253 case TMSG_RENDERER_FLUSH:
254 g_renderManager.Flush();
262 g_application.Stop(EXITCODE_POWERDOWN);
263 g_powerManager.Powerdown();
269 g_application.Stop(EXITCODE_QUIT);
275 g_PVRManager.SetWakeupCommand();
276 g_powerManager.Hibernate();
282 g_PVRManager.SetWakeupCommand();
283 g_powerManager.Suspend();
290 g_application.Stop(EXITCODE_REBOOT);
291 g_powerManager.Reboot();
295 case TMSG_RESTARTAPP:
297 #if defined(TARGET_WINDOWS) || defined(TARGET_LINUX)
298 g_application.Stop(EXITCODE_RESTARTAPP);
303 case TMSG_INHIBITIDLESHUTDOWN:
305 g_application.InhibitIdleShutdown(pMsg->dwParam1 != 0);
309 case TMSG_ACTIVATESCREENSAVER:
311 g_application.ActivateScreenSaver();
315 case TMSG_MEDIA_PLAY:
317 // first check if we were called from the PlayFile() function
318 if (pMsg->lpVoid && pMsg->dwParam2 == 0)
320 CFileItem *item = (CFileItem *)pMsg->lpVoid;
321 g_application.PlayFile(*item, pMsg->dwParam1 != 0);
325 // restore to previous window if needed
326 if (g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
327 g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
328 g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION)
329 g_windowManager.PreviousWindow();
331 g_application.ResetScreenSaver();
332 g_application.WakeUpScreenSaverAndDPMS();
334 //g_application.StopPlaying();
338 CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
340 if (list->Size() > 0)
342 int playlist = PLAYLIST_MUSIC;
343 for (int i = 0; i < list->Size(); i++)
345 if ((*list)[i]->IsVideo())
347 playlist = PLAYLIST_VIDEO;
352 g_playlistPlayer.ClearPlaylist(playlist);
353 g_playlistPlayer.SetCurrentPlaylist(playlist);
354 //For single item lists try PlayMedia. This covers some more cases where a playlist is not appropriate
355 //It will fall through to PlayFile
356 if (list->Size() == 1 && !(*list)[0]->IsPlayList())
357 g_application.PlayMedia(*((*list)[0]), playlist);
360 // Handle "shuffled" option if present
361 if (list->HasProperty("shuffled") && list->GetProperty("shuffled").isBoolean())
362 g_playlistPlayer.SetShuffle(playlist, list->GetProperty("shuffled").asBoolean(), false);
363 // Handle "repeat" option if present
364 if (list->HasProperty("repeat") && list->GetProperty("repeat").isInteger())
365 g_playlistPlayer.SetRepeat(playlist, (PLAYLIST::REPEAT_STATE)list->GetProperty("repeat").asInteger(), false);
367 g_playlistPlayer.Add(playlist, (*list));
368 g_playlistPlayer.Play(pMsg->dwParam1);
374 else if (pMsg->dwParam1 == PLAYLIST_MUSIC || pMsg->dwParam1 == PLAYLIST_VIDEO)
376 if (g_playlistPlayer.GetCurrentPlaylist() != (int)pMsg->dwParam1)
377 g_playlistPlayer.SetCurrentPlaylist(pMsg->dwParam1);
379 PlayListPlayerPlay(pMsg->dwParam2);
384 case TMSG_MEDIA_RESTART:
385 g_application.Restart(true);
388 case TMSG_PICTURE_SHOW:
390 CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
391 if (!pSlideShow) return ;
394 if (g_application.IsPlayingVideo()) g_application.StopPlaying();
396 if (g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO)
397 g_windowManager.PreviousWindow();
399 g_application.ResetScreenSaver();
400 g_application.WakeUpScreenSaverAndDPMS();
402 g_graphicsContext.Lock();
404 if (g_windowManager.GetActiveWindow() != WINDOW_SLIDESHOW)
405 g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
406 if (URIUtils::IsZIP(pMsg->strParam) || URIUtils::IsRAR(pMsg->strParam)) // actually a cbz/cbr
410 if (URIUtils::IsZIP(pMsg->strParam))
411 URIUtils::CreateArchivePath(strPath, "zip", pMsg->strParam.c_str(), "");
413 URIUtils::CreateArchivePath(strPath, "rar", pMsg->strParam.c_str(), "");
415 CUtil::GetRecursiveListing(strPath, items, g_advancedSettings.m_pictureExtensions);
416 if (items.Size() > 0)
419 for (int i=0;i<items.Size();++i)
421 pSlideShow->Add(items[i].get());
423 pSlideShow->Select(items[0]->GetPath());
428 CFileItem item(pMsg->strParam, false);
430 pSlideShow->Add(&item);
431 pSlideShow->Select(pMsg->strParam);
433 g_graphicsContext.Unlock();
437 case TMSG_PICTURE_SLIDESHOW:
439 CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
440 if (!pSlideShow) return ;
442 if (g_application.IsPlayingVideo())
443 g_application.StopPlaying();
445 g_graphicsContext.Lock();
449 CStdString strPath = pMsg->strParam;
450 CStdString extensions = g_advancedSettings.m_pictureExtensions;
452 extensions += "|.tbn";
453 CUtil::GetRecursiveListing(strPath, items, extensions);
455 if (items.Size() > 0)
457 for (int i=0;i<items.Size();++i)
458 pSlideShow->Add(items[i].get());
459 pSlideShow->StartSlideShow(); //Start the slideshow!
462 if (g_windowManager.GetActiveWindow() != WINDOW_SLIDESHOW)
464 if(items.Size() == 0)
466 CSettings::Get().SetString("screensaver.mode", "screensaver.xbmc.builtin.dim");
467 g_application.ActivateScreenSaver();
470 g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
473 g_graphicsContext.Unlock();
477 case TMSG_SETLANGUAGE:
478 g_application.SetLanguage(pMsg->strParam);
480 case TMSG_MEDIA_STOP:
482 // restore to previous window if needed
483 bool stopSlideshow = true;
484 bool stopVideo = true;
485 bool stopMusic = true;
486 if (pMsg->dwParam1 >= PLAYLIST_MUSIC && pMsg->dwParam1 <= PLAYLIST_PICTURE)
488 stopSlideshow = (pMsg->dwParam1 == PLAYLIST_PICTURE);
489 stopVideo = (pMsg->dwParam1 == PLAYLIST_VIDEO);
490 stopMusic = (pMsg->dwParam1 == PLAYLIST_MUSIC);
493 if ((stopSlideshow && g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW) ||
494 (stopVideo && g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO) ||
495 (stopMusic && g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION))
496 g_windowManager.PreviousWindow();
498 g_application.ResetScreenSaver();
499 g_application.WakeUpScreenSaverAndDPMS();
502 if (g_application.IsPlaying()) g_application.StopPlaying();
506 case TMSG_MEDIA_PAUSE:
507 if (g_application.m_pPlayer)
509 g_application.ResetScreenSaver();
510 g_application.WakeUpScreenSaverAndDPMS();
511 g_application.m_pPlayer->Pause();
515 case TMSG_MEDIA_UNPAUSE:
516 if (g_application.IsPaused())
518 g_application.ResetScreenSaver();
519 g_application.WakeUpScreenSaverAndDPMS();
520 g_application.m_pPlayer->Pause();
524 case TMSG_MEDIA_PAUSE_IF_PLAYING:
525 if (g_application.IsPlaying() && !g_application.IsPaused())
527 g_application.ResetScreenSaver();
528 g_application.WakeUpScreenSaverAndDPMS();
529 g_application.m_pPlayer->Pause();
533 case TMSG_SWITCHTOFULLSCREEN:
534 if( g_windowManager.GetActiveWindow() != WINDOW_FULLSCREEN_VIDEO )
535 g_application.SwitchToFullScreen();
538 case TMSG_TOGGLEFULLSCREEN:
539 g_graphicsContext.Lock();
540 g_graphicsContext.ToggleFullScreenRoot();
541 g_graphicsContext.Unlock();
545 g_application.Minimize();
548 case TMSG_EXECUTE_OS:
549 /* Suspend AE temporarily so exclusive or hog-mode sinks */
550 /* don't block external player's access to audio device */
551 if (!CAEFactory::Suspend())
553 CLog::Log(LOGNOTICE, "%s: Failed to suspend AudioEngine before launching external program",__FUNCTION__);
555 #if defined( TARGET_POSIX) && !defined(TARGET_DARWIN)
556 CUtil::RunCommandLine(pMsg->strParam.c_str(), (pMsg->dwParam1 == 1));
557 #elif defined(TARGET_WINDOWS)
558 CWIN32Util::XBMCShellExecute(pMsg->strParam.c_str(), (pMsg->dwParam1 == 1));
560 /* Resume AE processing of XBMC native audio */
561 if (!CAEFactory::Resume())
563 CLog::Log(LOGFATAL, "%s: Failed to restart AudioEngine after return from external player",__FUNCTION__);
567 case TMSG_EXECUTE_SCRIPT:
569 g_pythonParser.evalFile(pMsg->strParam.c_str(),ADDON::AddonPtr());
573 case TMSG_EXECUTE_BUILT_IN:
574 CBuiltins::Execute(pMsg->strParam.c_str());
577 case TMSG_PLAYLISTPLAYER_PLAY:
578 if (pMsg->dwParam1 != (unsigned int) -1)
579 g_playlistPlayer.Play(pMsg->dwParam1);
581 g_playlistPlayer.Play();
584 case TMSG_PLAYLISTPLAYER_PLAY_SONG_ID:
585 if (pMsg->dwParam1 != (unsigned int) -1)
587 bool *result = (bool*)pMsg->lpVoid;
588 *result = g_playlistPlayer.PlaySongId(pMsg->dwParam1);
591 g_playlistPlayer.Play();
594 case TMSG_PLAYLISTPLAYER_NEXT:
595 g_playlistPlayer.PlayNext();
598 case TMSG_PLAYLISTPLAYER_PREV:
599 g_playlistPlayer.PlayPrevious();
602 case TMSG_PLAYLISTPLAYER_ADD:
605 CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
607 g_playlistPlayer.Add(pMsg->dwParam1, (*list));
612 case TMSG_PLAYLISTPLAYER_INSERT:
615 CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
616 g_playlistPlayer.Insert(pMsg->dwParam1, (*list), pMsg->dwParam2);
621 case TMSG_PLAYLISTPLAYER_REMOVE:
622 if (pMsg->dwParam1 != (unsigned int) -1)
623 g_playlistPlayer.Remove(pMsg->dwParam1,pMsg->dwParam2);
626 case TMSG_PLAYLISTPLAYER_CLEAR:
627 g_playlistPlayer.ClearPlaylist(pMsg->dwParam1);
630 case TMSG_PLAYLISTPLAYER_SHUFFLE:
631 g_playlistPlayer.SetShuffle(pMsg->dwParam1, pMsg->dwParam2 > 0);
634 case TMSG_PLAYLISTPLAYER_REPEAT:
635 g_playlistPlayer.SetRepeat(pMsg->dwParam1, (PLAYLIST::REPEAT_STATE)pMsg->dwParam2);
638 case TMSG_PLAYLISTPLAYER_GET_ITEMS:
641 PLAYLIST::CPlayList playlist = g_playlistPlayer.GetPlaylist(pMsg->dwParam1);
642 CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
644 for (int i = 0; i < playlist.size(); i++)
645 list->Add(CFileItemPtr(new CFileItem(*playlist[i])));
649 case TMSG_PLAYLISTPLAYER_SWAP:
652 vector<int> *indexes = (vector<int> *)pMsg->lpVoid;
653 if (indexes->size() == 2)
654 g_playlistPlayer.Swap(pMsg->dwParam1, indexes->at(0), indexes->at(1));
659 // Window messages below here...
660 case TMSG_DIALOG_DOMODAL: //doModel of window
662 CGUIDialog* pDialog = (CGUIDialog*)g_windowManager.GetWindow(pMsg->dwParam1);
663 if (!pDialog) return ;
668 case TMSG_NETWORKMESSAGE:
670 g_application.getNetwork().NetworkMessage((CNetwork::EMESSAGE)pMsg->dwParam1, (int)pMsg->dwParam2);
674 case TMSG_GUI_DO_MODAL:
676 CGUIDialog *pDialog = (CGUIDialog *)pMsg->lpVoid;
678 pDialog->DoModal((int)pMsg->dwParam1, pMsg->strParam);
684 CGUIDialog *pDialog = (CGUIDialog *)pMsg->lpVoid;
690 case TMSG_GUI_WINDOW_CLOSE:
692 CGUIWindow *window = (CGUIWindow *)pMsg->lpVoid;
694 window->Close(pMsg->dwParam2 & 0x1 ? true : false, pMsg->dwParam1, pMsg->dwParam2 & 0x2 ? true : false);
698 case TMSG_GUI_ACTIVATE_WINDOW:
700 g_windowManager.ActivateWindow(pMsg->dwParam1, pMsg->params, pMsg->dwParam2 > 0);
704 case TMSG_GUI_ADDON_DIALOG:
707 { // TODO: This is ugly - really these python dialogs should just be normal XBMC dialogs
708 ((ADDON::CGUIAddonWindowDialog *) pMsg->lpVoid)->Show_Internal(pMsg->dwParam2 > 0);
714 case TMSG_GUI_PYTHON_DIALOG:
716 // This hack is not much better but at least I don't need to make ApplicationMessenger
717 // know about Addon (Python) specific classes.
718 CAction caction(pMsg->dwParam1);
719 ((CGUIWindow*)pMsg->lpVoid)->OnAction(caction);
724 case TMSG_GUI_ACTION:
728 CAction *action = (CAction *)pMsg->lpVoid;
729 if (pMsg->dwParam1 == WINDOW_INVALID)
730 g_application.OnAction(*action);
733 CGUIWindow *pWindow = g_windowManager.GetWindow(pMsg->dwParam1);
735 pWindow->OnAction(*action);
737 CLog::Log(LOGWARNING, "Failed to get window with ID %i to send an action to", pMsg->dwParam1);
744 case TMSG_GUI_MESSAGE:
748 CGUIMessage *message = (CGUIMessage *)pMsg->lpVoid;
749 g_windowManager.SendMessage(*message, pMsg->dwParam1);
755 case TMSG_GUI_INFOLABEL:
759 vector<CStdString> *infoLabels = (vector<CStdString> *)pMsg->lpVoid;
760 for (unsigned int i = 0; i < pMsg->params.size(); i++)
761 infoLabels->push_back(g_infoManager.GetLabel(g_infoManager.TranslateString(pMsg->params[i])));
765 case TMSG_GUI_INFOBOOL:
769 vector<bool> *infoLabels = (vector<bool> *)pMsg->lpVoid;
770 for (unsigned int i = 0; i < pMsg->params.size(); i++)
771 infoLabels->push_back(g_infoManager.EvaluateBool(pMsg->params[i]));
778 ThreadMessageCallback *callback = (ThreadMessageCallback*)pMsg->lpVoid;
779 callback->callback(callback->userptr);
783 case TMSG_VOLUME_SHOW:
785 CAction action((int)pMsg->dwParam1);
786 g_application.ShowVolumeBar(&action);
790 case TMSG_SPLASH_MESSAGE:
792 if (g_application.GetSplash())
793 g_application.GetSplash()->Show(pMsg->strParam);
797 case TMSG_DISPLAY_SETUP:
799 *((bool*)pMsg->lpVoid) = g_application.InitWindow();
800 g_application.SetRenderGUI(true);
804 case TMSG_DISPLAY_DESTROY:
806 *((bool*)pMsg->lpVoid) = g_application.DestroyWindow();
807 g_application.SetRenderGUI(false);
811 case TMSG_UPDATE_CURRENT_ITEM:
813 CFileItem* item = (CFileItem*)pMsg->lpVoid;
816 if (pMsg->dwParam1 == 1 && item->HasMusicInfoTag()) // only grab music tag
817 g_infoManager.SetCurrentSongTag(*item->GetMusicInfoTag());
818 else if (pMsg->dwParam1 == 2 && item->HasVideoInfoTag()) // only grab video tag
819 g_infoManager.SetCurrentVideoTag(*item->GetVideoInfoTag());
821 g_infoManager.SetCurrentItem(*item);
826 case TMSG_LOADPROFILE:
828 CGUIWindowLoginScreen::LoadProfile(pMsg->dwParam1);
831 case TMSG_START_ANDROID_ACTIVITY:
833 #if defined(TARGET_ANDROID)
834 if (pMsg->params.size())
836 CXBMCApp::StartActivity(pMsg->params[0],
837 pMsg->params.size() > 1 ? pMsg->params[1] : "",
838 pMsg->params.size() > 2 ? pMsg->params[2] : "",
839 pMsg->params.size() > 3 ? pMsg->params[3] : "");
847 void CApplicationMessenger::ProcessWindowMessages()
849 CSingleLock lock (m_critSection);
850 //message type is window, process window messages
851 while (m_vecWindowMessages.size() > 0)
853 ThreadMessage* pMsg = m_vecWindowMessages.front();
854 //first remove the message from the queue, else the message could be processed more then once
855 m_vecWindowMessages.pop();
857 // leave here in case we make more thread messages from this one
859 boost::shared_ptr<CEvent> waitEvent = pMsg->waitEvent;
860 lock.Leave(); // <- see the large comment in SendMessage ^
862 ProcessMessage(pMsg);
871 int CApplicationMessenger::SetResponse(CStdString response)
873 CSingleLock lock (m_critBuffer);
874 bufferResponse=response;
879 CStdString CApplicationMessenger::GetResponse()
882 CSingleLock lock (m_critBuffer);
888 void CApplicationMessenger::ExecBuiltIn(const CStdString &command, bool wait)
890 ThreadMessage tMsg = {TMSG_EXECUTE_BUILT_IN};
891 tMsg.strParam = command;
892 SendMessage(tMsg, wait);
895 void CApplicationMessenger::MediaPlay(string filename)
897 CFileItem item(filename, false);
901 void CApplicationMessenger::MediaPlay(const CFileItem &item)
904 list.Add(CFileItemPtr(new CFileItem(item)));
909 void CApplicationMessenger::MediaPlay(const CFileItemList &list, int song)
911 ThreadMessage tMsg = {TMSG_MEDIA_PLAY};
912 CFileItemList* listcopy = new CFileItemList();
913 listcopy->Copy(list);
914 tMsg.lpVoid = (void*)listcopy;
915 tMsg.dwParam1 = song;
917 SendMessage(tMsg, true);
920 void CApplicationMessenger::MediaPlay(int playlistid, int song /* = -1 */)
922 ThreadMessage tMsg = {TMSG_MEDIA_PLAY};
924 tMsg.dwParam1 = playlistid;
925 tMsg.dwParam2 = song;
926 SendMessage(tMsg, true);
929 void CApplicationMessenger::PlayFile(const CFileItem &item, bool bRestart /*= false*/)
931 ThreadMessage tMsg = {TMSG_MEDIA_PLAY};
932 CFileItem *pItem = new CFileItem(item);
933 tMsg.lpVoid = (void *)pItem;
934 tMsg.dwParam1 = bRestart ? 1 : 0;
936 SendMessage(tMsg, false);
939 void CApplicationMessenger::MediaStop(bool bWait /* = true */, int playlistid /* = -1 */)
941 ThreadMessage tMsg = {TMSG_MEDIA_STOP};
942 tMsg.dwParam1 = playlistid;
943 SendMessage(tMsg, bWait);
946 void CApplicationMessenger::MediaPause()
948 ThreadMessage tMsg = {TMSG_MEDIA_PAUSE};
949 SendMessage(tMsg, true);
952 void CApplicationMessenger::MediaUnPause()
954 ThreadMessage tMsg = {TMSG_MEDIA_UNPAUSE};
955 SendMessage(tMsg, true);
958 void CApplicationMessenger::MediaPauseIfPlaying()
960 ThreadMessage tMsg = {TMSG_MEDIA_PAUSE_IF_PLAYING};
961 SendMessage(tMsg, true);
964 void CApplicationMessenger::MediaRestart(bool bWait)
966 ThreadMessage tMsg = {TMSG_MEDIA_RESTART};
967 SendMessage(tMsg, bWait);
970 void CApplicationMessenger::PlayListPlayerPlay()
972 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_PLAY, (unsigned int) -1};
973 SendMessage(tMsg, true);
976 void CApplicationMessenger::PlayListPlayerPlay(int iSong)
978 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_PLAY, (unsigned int)iSong};
979 SendMessage(tMsg, true);
982 bool CApplicationMessenger::PlayListPlayerPlaySongId(int songId)
985 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_PLAY_SONG_ID, (unsigned int)songId};
986 tMsg.lpVoid = (void *)&returnState;
987 SendMessage(tMsg, true);
991 void CApplicationMessenger::PlayListPlayerNext()
993 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_NEXT};
994 SendMessage(tMsg, true);
997 void CApplicationMessenger::PlayListPlayerPrevious()
999 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_PREV};
1000 SendMessage(tMsg, true);
1003 void CApplicationMessenger::PlayListPlayerAdd(int playlist, const CFileItem &item)
1006 list.Add(CFileItemPtr(new CFileItem(item)));
1008 PlayListPlayerAdd(playlist, list);
1011 void CApplicationMessenger::PlayListPlayerAdd(int playlist, const CFileItemList &list)
1013 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_ADD};
1014 CFileItemList* listcopy = new CFileItemList();
1015 listcopy->Copy(list);
1016 tMsg.lpVoid = (void*)listcopy;
1017 tMsg.dwParam1 = playlist;
1018 SendMessage(tMsg, true);
1021 void CApplicationMessenger::PlayListPlayerInsert(int playlist, const CFileItem &item, int index)
1024 list.Add(CFileItemPtr(new CFileItem(item)));
1025 PlayListPlayerInsert(playlist, list, index);
1028 void CApplicationMessenger::PlayListPlayerInsert(int playlist, const CFileItemList &list, int index)
1030 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_INSERT};
1031 CFileItemList* listcopy = new CFileItemList();
1032 listcopy->Copy(list);
1033 tMsg.lpVoid = (void *)listcopy;
1034 tMsg.dwParam1 = playlist;
1035 tMsg.dwParam2 = index;
1036 SendMessage(tMsg, true);
1039 void CApplicationMessenger::PlayListPlayerRemove(int playlist, int position)
1041 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_REMOVE, (unsigned int)playlist, (unsigned int)position};
1042 SendMessage(tMsg, true);
1045 void CApplicationMessenger::PlayListPlayerClear(int playlist)
1047 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_CLEAR};
1048 tMsg.dwParam1 = playlist;
1049 SendMessage(tMsg, true);
1052 void CApplicationMessenger::PlayListPlayerShuffle(int playlist, bool shuffle)
1054 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_SHUFFLE};
1055 tMsg.dwParam1 = playlist;
1056 tMsg.dwParam2 = shuffle ? 1 : 0;
1057 SendMessage(tMsg, true);
1060 void CApplicationMessenger::PlayListPlayerGetItems(int playlist, CFileItemList &list)
1062 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_GET_ITEMS};
1063 tMsg.dwParam1 = playlist;
1064 tMsg.lpVoid = (void *)&list;
1065 SendMessage(tMsg, true);
1068 void CApplicationMessenger::PlayListPlayerSwap(int playlist, int indexItem1, int indexItem2)
1070 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_SWAP};
1071 tMsg.dwParam1 = playlist;
1072 vector<int> *indexes = new vector<int>();
1073 indexes->push_back(indexItem1);
1074 indexes->push_back(indexItem2);
1075 tMsg.lpVoid = (void *)indexes;
1076 SendMessage(tMsg, true);
1079 void CApplicationMessenger::PlayListPlayerRepeat(int playlist, int repeatState)
1081 ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_REPEAT};
1082 tMsg.dwParam1 = playlist;
1083 tMsg.dwParam2 = repeatState;
1084 SendMessage(tMsg, true);
1087 void CApplicationMessenger::PictureShow(string filename)
1089 ThreadMessage tMsg = {TMSG_PICTURE_SHOW};
1090 tMsg.strParam = filename;
1094 void CApplicationMessenger::PictureSlideShow(string pathname, bool addTBN /* = false */)
1096 unsigned int dwMessage = TMSG_PICTURE_SLIDESHOW;
1097 ThreadMessage tMsg = {dwMessage};
1098 tMsg.strParam = pathname;
1099 tMsg.dwParam1 = addTBN ? 1 : 0;
1103 void CApplicationMessenger::SetGUILanguage(const std::string &strLanguage)
1105 ThreadMessage tMsg = {TMSG_SETLANGUAGE};
1106 tMsg.strParam = strLanguage;
1110 void CApplicationMessenger::Shutdown()
1112 ThreadMessage tMsg = {TMSG_SHUTDOWN};
1116 void CApplicationMessenger::Powerdown()
1118 ThreadMessage tMsg = {TMSG_POWERDOWN};
1122 void CApplicationMessenger::Quit()
1124 ThreadMessage tMsg = {TMSG_QUIT};
1128 void CApplicationMessenger::Hibernate()
1130 ThreadMessage tMsg = {TMSG_HIBERNATE};
1134 void CApplicationMessenger::Suspend()
1136 ThreadMessage tMsg = {TMSG_SUSPEND};
1140 void CApplicationMessenger::Restart()
1142 ThreadMessage tMsg = {TMSG_RESTART};
1146 void CApplicationMessenger::Reset()
1148 ThreadMessage tMsg = {TMSG_RESET};
1152 void CApplicationMessenger::RestartApp()
1154 ThreadMessage tMsg = {TMSG_RESTARTAPP};
1158 void CApplicationMessenger::InhibitIdleShutdown(bool inhibit)
1160 ThreadMessage tMsg = {TMSG_INHIBITIDLESHUTDOWN, (unsigned int)inhibit};
1164 void CApplicationMessenger::ActivateScreensaver()
1166 ThreadMessage tMsg = {TMSG_ACTIVATESCREENSAVER};
1170 void CApplicationMessenger::NetworkMessage(unsigned int dwMessage, unsigned int dwParam)
1172 ThreadMessage tMsg = {TMSG_NETWORKMESSAGE, dwMessage, dwParam};
1176 void CApplicationMessenger::SwitchToFullscreen()
1178 /* FIXME: ideally this call should return upon a successfull switch but currently
1179 is causing deadlocks between the dvdplayer destructor and the rendermanager
1181 ThreadMessage tMsg = {TMSG_SWITCHTOFULLSCREEN};
1182 SendMessage(tMsg, false);
1185 void CApplicationMessenger::Minimize(bool wait)
1187 ThreadMessage tMsg = {TMSG_MINIMIZE};
1188 SendMessage(tMsg, wait);
1191 void CApplicationMessenger::DoModal(CGUIDialog *pDialog, int iWindowID, const CStdString ¶m)
1193 ThreadMessage tMsg = {TMSG_GUI_DO_MODAL};
1194 tMsg.lpVoid = pDialog;
1195 tMsg.dwParam1 = (unsigned int)iWindowID;
1196 tMsg.strParam = param;
1197 SendMessage(tMsg, true);
1200 void CApplicationMessenger::ExecOS(const CStdString command, bool waitExit)
1202 ThreadMessage tMsg = {TMSG_EXECUTE_OS};
1203 tMsg.strParam = command;
1204 tMsg.dwParam1 = (unsigned int)waitExit;
1205 SendMessage(tMsg, false);
1208 void CApplicationMessenger::UserEvent(int code)
1210 ThreadMessage tMsg = {(unsigned int)code};
1211 SendMessage(tMsg, false);
1214 void CApplicationMessenger::Show(CGUIDialog *pDialog)
1216 ThreadMessage tMsg = {TMSG_GUI_SHOW};
1217 tMsg.lpVoid = pDialog;
1218 SendMessage(tMsg, true);
1221 void CApplicationMessenger::Close(CGUIWindow *window, bool forceClose, bool waitResult /*= true*/, int nextWindowID /*= 0*/, bool enableSound /*= true*/)
1223 ThreadMessage tMsg = {TMSG_GUI_WINDOW_CLOSE, (unsigned int)nextWindowID};
1224 tMsg.dwParam2 = (unsigned int)((forceClose ? 0x01 : 0) | (enableSound ? 0x02 : 0));
1225 tMsg.lpVoid = window;
1226 SendMessage(tMsg, waitResult);
1229 void CApplicationMessenger::ActivateWindow(int windowID, const vector<CStdString> ¶ms, bool swappingWindows)
1231 ThreadMessage tMsg = {TMSG_GUI_ACTIVATE_WINDOW, (unsigned int)windowID, swappingWindows ? 1u : 0u};
1232 tMsg.params = params;
1233 SendMessage(tMsg, true);
1236 void CApplicationMessenger::SendAction(const CAction &action, int windowID, bool waitResult)
1238 ThreadMessage tMsg = {TMSG_GUI_ACTION};
1239 tMsg.dwParam1 = windowID;
1240 tMsg.lpVoid = new CAction(action);
1241 SendMessage(tMsg, waitResult);
1244 void CApplicationMessenger::SendGUIMessage(const CGUIMessage &message, int windowID, bool waitResult)
1246 ThreadMessage tMsg = {TMSG_GUI_MESSAGE};
1247 tMsg.dwParam1 = windowID == WINDOW_INVALID ? 0 : windowID;
1248 tMsg.lpVoid = new CGUIMessage(message);
1249 SendMessage(tMsg, waitResult);
1252 vector<CStdString> CApplicationMessenger::GetInfoLabels(const vector<CStdString> &properties)
1254 vector<CStdString> infoLabels;
1256 ThreadMessage tMsg = {TMSG_GUI_INFOLABEL};
1257 tMsg.params = properties;
1258 tMsg.lpVoid = (void*)&infoLabels;
1259 SendMessage(tMsg, true);
1263 vector<bool> CApplicationMessenger::GetInfoBooleans(const vector<CStdString> &properties)
1265 vector<bool> infoLabels;
1267 ThreadMessage tMsg = {TMSG_GUI_INFOBOOL};
1268 tMsg.params = properties;
1269 tMsg.lpVoid = (void*)&infoLabels;
1270 SendMessage(tMsg, true);
1274 void CApplicationMessenger::ShowVolumeBar(bool up)
1276 ThreadMessage tMsg = {TMSG_VOLUME_SHOW};
1277 tMsg.dwParam1 = up ? ACTION_VOLUME_UP : ACTION_VOLUME_DOWN;
1278 SendMessage(tMsg, false);
1281 void CApplicationMessenger::SetSplashMessage(const CStdString& message)
1283 ThreadMessage tMsg = {TMSG_SPLASH_MESSAGE};
1284 tMsg.strParam = message;
1285 SendMessage(tMsg, true);
1288 void CApplicationMessenger::SetSplashMessage(int stringID)
1290 SetSplashMessage(g_localizeStrings.Get(stringID));
1293 bool CApplicationMessenger::SetupDisplay()
1297 ThreadMessage tMsg = {TMSG_DISPLAY_SETUP};
1298 tMsg.lpVoid = (void*)&result;
1299 SendMessage(tMsg, true);
1304 bool CApplicationMessenger::DestroyDisplay()
1308 ThreadMessage tMsg = {TMSG_DISPLAY_DESTROY};
1309 tMsg.lpVoid = (void*)&result;
1310 SendMessage(tMsg, true);
1315 void CApplicationMessenger::SetCurrentSongTag(const CMusicInfoTag& tag)
1317 CFileItem* item = new CFileItem(tag);
1318 ThreadMessage tMsg = {TMSG_UPDATE_CURRENT_ITEM};
1320 tMsg.lpVoid = (void*)item;
1321 SendMessage(tMsg, false);
1324 void CApplicationMessenger::SetCurrentVideoTag(const CVideoInfoTag& tag)
1326 CFileItem* item = new CFileItem(tag);
1327 ThreadMessage tMsg = {TMSG_UPDATE_CURRENT_ITEM};
1329 tMsg.lpVoid = (void*)item;
1330 SendMessage(tMsg, false);
1333 void CApplicationMessenger::SetCurrentItem(const CFileItem& item)
1335 CFileItem* item2 = new CFileItem(item);
1336 ThreadMessage tMsg = {TMSG_UPDATE_CURRENT_ITEM};
1337 tMsg.lpVoid = (void*)item2;
1338 SendMessage(tMsg, false);
1341 void CApplicationMessenger::LoadProfile(unsigned int idx)
1343 ThreadMessage tMsg = {TMSG_LOADPROFILE};
1344 tMsg.dwParam1 = idx;
1345 SendMessage(tMsg, false);
1348 void CApplicationMessenger::StartAndroidActivity(const vector<CStdString> ¶ms)
1350 ThreadMessage tMsg = {TMSG_START_ANDROID_ACTIVITY};
1351 tMsg.params = params;
1352 SendMessage(tMsg, false);