Merge pull request #3831 from xhaggi/epg-past-data
[vuplus_xbmc] / xbmc / ApplicationMessenger.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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/>.
18  *
19  */
20
21 #include "system.h"
22 #include "ApplicationMessenger.h"
23 #include "Application.h"
24
25 #include "LangInfo.h"
26 #include "PlayListPlayer.h"
27 #include "Util.h"
28 #include "pictures/GUIWindowSlideShow.h"
29 #include "interfaces/Builtins.h"
30 #include "interfaces/generic/ScriptInvocationManager.h"
31 #include "network/Network.h"
32 #include "utils/log.h"
33 #include "utils/URIUtils.h"
34 #include "utils/Variant.h"
35 #include "guilib/GUIWindowManager.h"
36 #include "settings/AdvancedSettings.h"
37 #include "settings/Settings.h"
38 #include "FileItem.h"
39 #include "guilib/GUIDialog.h"
40 #include "guilib/Key.h"
41 #include "GUIInfoManager.h"
42 #include "utils/Splash.h"
43 #include "cores/IPlayer.h"
44 #include "cores/VideoRenderers/RenderManager.h"
45 #include "cores/AudioEngine/AEFactory.h"
46 #include "music/tags/MusicInfoTag.h"
47
48 #include "peripherals/Peripherals.h"
49 #include "powermanagement/PowerManager.h"
50
51 #ifdef TARGET_WINDOWS
52 #include "WIN32Util.h"
53 #define CHalManager CWIN32Util
54 #elif defined(TARGET_DARWIN)
55 #include "osx/CocoaInterface.h"
56 #endif
57 #include "addons/AddonCallbacks.h"
58 #include "addons/AddonCallbacksGUI.h"
59 #include "storage/MediaManager.h"
60 #include "guilib/LocalizeStrings.h"
61 #include "threads/SingleLock.h"
62
63 #include "playlists/PlayList.h"
64
65 #include "pvr/PVRManager.h"
66 #include "windows/GUIWindowLoginScreen.h"
67
68 #include "utils/GlobalsHandling.h"
69 #if defined(TARGET_ANDROID)
70   #include "xbmc/android/activity/XBMCApp.h"
71 #endif
72
73 using namespace PVR;
74 using namespace std;
75 using namespace MUSIC_INFO;
76 using namespace PERIPHERALS;
77
78 CDelayedMessage::CDelayedMessage(ThreadMessage& msg, unsigned int delay) : CThread("DelayedMessage")
79 {
80   m_msg.dwMessage  = msg.dwMessage;
81   m_msg.dwParam1   = msg.dwParam1;
82   m_msg.dwParam2   = msg.dwParam2;
83   m_msg.waitEvent  = msg.waitEvent;
84   m_msg.lpVoid     = msg.lpVoid;
85   m_msg.strParam   = msg.strParam;
86   m_msg.params     = msg.params;
87
88   m_delay = delay;
89 }
90
91 void CDelayedMessage::Process()
92 {
93   Sleep(m_delay);
94
95   if (!m_bStop)
96     CApplicationMessenger::Get().SendMessage(m_msg, false);
97 }
98
99
100 CApplicationMessenger& CApplicationMessenger::Get()
101 {
102   return s_messenger;
103 }
104
105 CApplicationMessenger::CApplicationMessenger()
106 {
107 }
108
109 CApplicationMessenger::~CApplicationMessenger()
110 {
111   Cleanup();
112 }
113
114 void CApplicationMessenger::Cleanup()
115 {
116   CSingleLock lock (m_critSection);
117
118   while (m_vecMessages.size() > 0)
119   {
120     ThreadMessage* pMsg = m_vecMessages.front();
121
122     if (pMsg->waitEvent)
123       pMsg->waitEvent->Set();
124
125     delete pMsg;
126     m_vecMessages.pop();
127   }
128
129   while (m_vecWindowMessages.size() > 0)
130   {
131     ThreadMessage* pMsg = m_vecWindowMessages.front();
132
133     if (pMsg->waitEvent)
134       pMsg->waitEvent->Set();
135
136     delete pMsg;
137     m_vecWindowMessages.pop();
138   }
139 }
140
141 void CApplicationMessenger::SendMessage(ThreadMessage& message, bool wait)
142 {
143   message.waitEvent.reset();
144   boost::shared_ptr<CEvent> waitEvent;
145   if (wait)
146   { // check that we're not being called from our application thread, else we'll be waiting
147     // forever!
148     if (!g_application.IsCurrentThread())
149     {
150       message.waitEvent.reset(new CEvent(true));
151       waitEvent = message.waitEvent;
152     }
153     else
154     {
155       //OutputDebugString("Attempting to wait on a SendMessage() from our application thread will cause lockup!\n");
156       //OutputDebugString("Sending immediately\n");
157       ProcessMessage(&message);
158       return;
159     }
160   }
161
162   CSingleLock lock (m_critSection);
163
164   if (g_application.m_bStop)
165   {
166     if (message.waitEvent)
167       message.waitEvent.reset();
168     return;
169   }
170
171   ThreadMessage* msg = new ThreadMessage();
172   msg->dwMessage = message.dwMessage;
173   msg->dwParam1 = message.dwParam1;
174   msg->dwParam2 = message.dwParam2;
175   msg->waitEvent = message.waitEvent;
176   msg->lpVoid = message.lpVoid;
177   msg->strParam = message.strParam;
178   msg->params = message.params;
179
180   if (msg->dwMessage == TMSG_DIALOG_DOMODAL)
181     m_vecWindowMessages.push(msg);
182   else
183     m_vecMessages.push(msg);
184   lock.Leave();  // this releases the lock on the vec of messages and
185                  //   allows the ProcessMessage to execute and therefore
186                  //   delete the message itself. Therefore any accesss
187                  //   of the message itself after this point consittutes
188                  //   a race condition (yarc - "yet another race condition")
189                  //
190   if (waitEvent) // ... it just so happens we have a spare reference to the
191                  //  waitEvent ... just for such contingencies :)
192   { 
193     // ensure the thread doesn't hold the graphics lock
194     CSingleExit exit(g_graphicsContext);
195     waitEvent->Wait();
196   }
197 }
198
199 void CApplicationMessenger::ProcessMessages()
200 {
201   // process threadmessages
202   CSingleLock lock (m_critSection);
203   while (m_vecMessages.size() > 0)
204   {
205     ThreadMessage* pMsg = m_vecMessages.front();
206     //first remove the message from the queue, else the message could be processed more then once
207     m_vecMessages.pop();
208
209     //Leave here as the message might make another
210     //thread call processmessages or sendmessage
211
212     boost::shared_ptr<CEvent> waitEvent = pMsg->waitEvent; 
213     lock.Leave(); // <- see the large comment in SendMessage ^
214
215     ProcessMessage(pMsg);
216     if (waitEvent)
217       waitEvent->Set();
218     delete pMsg;
219
220     lock.Enter();
221   }
222 }
223
224 void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg)
225 {
226   switch (pMsg->dwMessage)
227   {
228     case TMSG_SHUTDOWN:
229       {
230         switch (CSettings::Get().GetInt("powermanagement.shutdownstate"))
231         {
232           case POWERSTATE_SHUTDOWN:
233             Powerdown();
234             break;
235
236           case POWERSTATE_SUSPEND:
237             Suspend();
238             break;
239
240           case POWERSTATE_HIBERNATE:
241             Hibernate();
242             break;
243
244           case POWERSTATE_QUIT:
245             Quit();
246             break;
247
248           case POWERSTATE_MINIMIZE:
249             Minimize();
250             break;
251
252           case TMSG_RENDERER_FLUSH:
253             g_renderManager.Flush();
254             break;
255         }
256       }
257       break;
258
259     case TMSG_POWERDOWN:
260       {
261         g_application.Stop(EXITCODE_POWERDOWN);
262         g_powerManager.Powerdown();
263       }
264       break;
265
266     case TMSG_QUIT:
267       {
268         g_application.Stop(EXITCODE_QUIT);
269       }
270       break;
271
272     case TMSG_HIBERNATE:
273       {
274         g_PVRManager.SetWakeupCommand();
275         g_powerManager.Hibernate();
276       }
277       break;
278
279     case TMSG_SUSPEND:
280       {
281         g_PVRManager.SetWakeupCommand();
282         g_powerManager.Suspend();
283       }
284       break;
285
286     case TMSG_RESTART:
287     case TMSG_RESET:
288       {
289         g_application.Stop(EXITCODE_REBOOT);
290         g_powerManager.Reboot();
291       }
292       break;
293
294     case TMSG_RESTARTAPP:
295       {
296 #if defined(TARGET_WINDOWS) || defined(TARGET_LINUX)
297         g_application.Stop(EXITCODE_RESTARTAPP);
298 #endif
299       }
300       break;
301
302     case TMSG_INHIBITIDLESHUTDOWN:
303       {
304         g_application.InhibitIdleShutdown(pMsg->dwParam1 != 0);
305       }
306       break;
307
308     case TMSG_ACTIVATESCREENSAVER:
309       {
310         g_application.ActivateScreenSaver();
311       }
312       break;
313
314     case TMSG_MEDIA_PLAY:
315       {
316         // first check if we were called from the PlayFile() function
317         if (pMsg->lpVoid && pMsg->dwParam2 == 0)
318         {
319           CFileItem *item = (CFileItem *)pMsg->lpVoid;
320           g_application.PlayFile(*item, pMsg->dwParam1 != 0);
321           delete item;
322           return;
323         }
324         // restore to previous window if needed
325         if (g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
326             g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
327             g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION)
328           g_windowManager.PreviousWindow();
329
330         g_application.ResetScreenSaver();
331         g_application.WakeUpScreenSaverAndDPMS();
332
333         //g_application.StopPlaying();
334         // play file
335         if(pMsg->lpVoid)
336         {
337           CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
338
339           if (list->Size() > 0)
340           {
341             int playlist = PLAYLIST_MUSIC;
342             for (int i = 0; i < list->Size(); i++)
343             {
344               if ((*list)[i]->IsVideo())
345               {
346                 playlist = PLAYLIST_VIDEO;
347                 break;
348               }
349             }
350
351             g_playlistPlayer.ClearPlaylist(playlist);
352             g_playlistPlayer.SetCurrentPlaylist(playlist);
353             //For single item lists try PlayMedia. This covers some more cases where a playlist is not appropriate
354             //It will fall through to PlayFile
355             if (list->Size() == 1 && !(*list)[0]->IsPlayList())
356               g_application.PlayMedia(*((*list)[0]), playlist);
357             else
358             {
359               // Handle "shuffled" option if present
360               if (list->HasProperty("shuffled") && list->GetProperty("shuffled").isBoolean())
361                 g_playlistPlayer.SetShuffle(playlist, list->GetProperty("shuffled").asBoolean(), false);
362               // Handle "repeat" option if present
363               if (list->HasProperty("repeat") && list->GetProperty("repeat").isInteger())
364                 g_playlistPlayer.SetRepeat(playlist, (PLAYLIST::REPEAT_STATE)list->GetProperty("repeat").asInteger(), false);
365
366               g_playlistPlayer.Add(playlist, (*list));
367               g_playlistPlayer.Play(pMsg->dwParam1);
368             }
369           }
370
371           delete list;
372         }
373         else if (pMsg->dwParam1 == PLAYLIST_MUSIC || pMsg->dwParam1 == PLAYLIST_VIDEO)
374         {
375           if (g_playlistPlayer.GetCurrentPlaylist() != (int)pMsg->dwParam1)
376             g_playlistPlayer.SetCurrentPlaylist(pMsg->dwParam1);
377
378           PlayListPlayerPlay(pMsg->dwParam2);
379         }
380       }
381       break;
382
383     case TMSG_MEDIA_RESTART:
384       g_application.Restart(true);
385       break;
386
387     case TMSG_PICTURE_SHOW:
388       {
389         CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
390         if (!pSlideShow) return ;
391
392         // stop playing file
393         if (g_application.m_pPlayer->IsPlayingVideo()) g_application.StopPlaying();
394
395         if (g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO)
396           g_windowManager.PreviousWindow();
397
398         g_application.ResetScreenSaver();
399         g_application.WakeUpScreenSaverAndDPMS();
400
401         g_graphicsContext.Lock();
402
403         if (g_windowManager.GetActiveWindow() != WINDOW_SLIDESHOW)
404           g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
405         if (URIUtils::IsZIP(pMsg->strParam) || URIUtils::IsRAR(pMsg->strParam)) // actually a cbz/cbr
406         {
407           CFileItemList items;
408           CStdString strPath;
409           if (URIUtils::IsZIP(pMsg->strParam))
410             URIUtils::CreateArchivePath(strPath, "zip", pMsg->strParam.c_str(), "");
411           else
412             URIUtils::CreateArchivePath(strPath, "rar", pMsg->strParam.c_str(), "");
413
414           CUtil::GetRecursiveListing(strPath, items, g_advancedSettings.m_pictureExtensions);
415           if (items.Size() > 0)
416           {
417             pSlideShow->Reset();
418             for (int i=0;i<items.Size();++i)
419             {
420               pSlideShow->Add(items[i].get());
421             }
422             pSlideShow->Select(items[0]->GetPath());
423           }
424         }
425         else
426         {
427           CFileItem item(pMsg->strParam, false);
428           pSlideShow->Reset();
429           pSlideShow->Add(&item);
430           pSlideShow->Select(pMsg->strParam);
431         }
432         g_graphicsContext.Unlock();
433       }
434       break;
435
436     case TMSG_PICTURE_SLIDESHOW:
437       {
438         CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
439         if (!pSlideShow) return ;
440
441         if (g_application.m_pPlayer->IsPlayingVideo())
442           g_application.StopPlaying();
443
444         g_graphicsContext.Lock();
445         pSlideShow->Reset();
446
447         CFileItemList items;
448         CStdString strPath = pMsg->strParam;
449         CStdString extensions = g_advancedSettings.m_pictureExtensions;
450         if (pMsg->dwParam1)
451           extensions += "|.tbn";
452         CUtil::GetRecursiveListing(strPath, items, extensions);
453
454         if (items.Size() > 0)
455         {
456           for (int i=0;i<items.Size();++i)
457             pSlideShow->Add(items[i].get());
458           pSlideShow->StartSlideShow(); //Start the slideshow!
459         }
460
461         if (g_windowManager.GetActiveWindow() != WINDOW_SLIDESHOW)
462         {
463           if(items.Size() == 0)
464           {
465             CSettings::Get().SetString("screensaver.mode", "screensaver.xbmc.builtin.dim");
466             g_application.ActivateScreenSaver();
467           }
468           else
469             g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
470         }
471
472         g_graphicsContext.Unlock();
473       }
474       break;
475
476     case TMSG_SETLANGUAGE:
477       g_application.SetLanguage(pMsg->strParam);
478       break;
479     case TMSG_MEDIA_STOP:
480       {
481         // restore to previous window if needed
482         bool stopSlideshow = true;
483         bool stopVideo = true;
484         bool stopMusic = true;
485         if (pMsg->dwParam1 >= PLAYLIST_MUSIC && pMsg->dwParam1 <= PLAYLIST_PICTURE)
486         {
487           stopSlideshow = (pMsg->dwParam1 == PLAYLIST_PICTURE);
488           stopVideo = (pMsg->dwParam1 == PLAYLIST_VIDEO);
489           stopMusic = (pMsg->dwParam1 == PLAYLIST_MUSIC);
490         }
491
492         if ((stopSlideshow && g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW) ||
493             (stopVideo && g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO) ||
494             (stopMusic && g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION))
495           g_windowManager.PreviousWindow();
496
497         g_application.ResetScreenSaver();
498         g_application.WakeUpScreenSaverAndDPMS();
499
500         // stop playing file
501         if (g_application.m_pPlayer->IsPlaying()) g_application.StopPlaying();
502       }
503       break;
504
505     case TMSG_MEDIA_PAUSE:
506       if (g_application.m_pPlayer->HasPlayer())
507       {
508         g_application.ResetScreenSaver();
509         g_application.WakeUpScreenSaverAndDPMS();
510         g_application.m_pPlayer->Pause();
511       }
512       break;
513
514     case TMSG_MEDIA_UNPAUSE:
515       if (g_application.m_pPlayer->IsPausedPlayback())
516       {
517         g_application.ResetScreenSaver();
518         g_application.WakeUpScreenSaverAndDPMS();
519         g_application.m_pPlayer->Pause();
520       }
521       break;
522
523     case TMSG_MEDIA_PAUSE_IF_PLAYING:
524       if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused())
525       {
526         g_application.ResetScreenSaver();
527         g_application.WakeUpScreenSaverAndDPMS();
528         g_application.m_pPlayer->Pause();
529       }
530       break;
531
532     case TMSG_SWITCHTOFULLSCREEN:
533       if( g_windowManager.GetActiveWindow() != WINDOW_FULLSCREEN_VIDEO )
534         g_application.SwitchToFullScreen();
535       break;
536
537     case TMSG_TOGGLEFULLSCREEN:
538       g_graphicsContext.Lock();
539       g_graphicsContext.ToggleFullScreenRoot();
540       g_graphicsContext.Unlock();
541       break;
542
543     case TMSG_MINIMIZE:
544       g_application.Minimize();
545       break;
546
547     case TMSG_EXECUTE_OS:
548       /* Suspend AE temporarily so exclusive or hog-mode sinks */
549       /* don't block external player's access to audio device  */
550       if (!CAEFactory::Suspend())
551       {
552         CLog::Log(LOGNOTICE, "%s: Failed to suspend AudioEngine before launching external program",__FUNCTION__);
553       }
554 #if defined( TARGET_POSIX) && !defined(TARGET_DARWIN)
555       CUtil::RunCommandLine(pMsg->strParam.c_str(), (pMsg->dwParam1 == 1));
556 #elif defined(TARGET_WINDOWS)
557       CWIN32Util::XBMCShellExecute(pMsg->strParam.c_str(), (pMsg->dwParam1 == 1));
558 #endif
559       /* Resume AE processing of XBMC native audio */
560       if (!CAEFactory::Resume())
561       {
562         CLog::Log(LOGFATAL, "%s: Failed to restart AudioEngine after return from external player",__FUNCTION__);
563       }
564       break;
565
566     case TMSG_EXECUTE_SCRIPT:
567       CScriptInvocationManager::Get().Execute(pMsg->strParam);
568       break;
569
570     case TMSG_EXECUTE_BUILT_IN:
571       CBuiltins::Execute(pMsg->strParam.c_str());
572       break;
573
574     case TMSG_PLAYLISTPLAYER_PLAY:
575       if (pMsg->dwParam1 != (unsigned int) -1)
576         g_playlistPlayer.Play(pMsg->dwParam1);
577       else
578         g_playlistPlayer.Play();
579       break;
580
581     case TMSG_PLAYLISTPLAYER_PLAY_SONG_ID:
582       if (pMsg->dwParam1 != (unsigned int) -1)
583       {
584         bool *result = (bool*)pMsg->lpVoid;
585         *result = g_playlistPlayer.PlaySongId(pMsg->dwParam1);
586       }
587       else
588         g_playlistPlayer.Play();
589       break;
590
591     case TMSG_PLAYLISTPLAYER_NEXT:
592       g_playlistPlayer.PlayNext();
593       break;
594
595     case TMSG_PLAYLISTPLAYER_PREV:
596       g_playlistPlayer.PlayPrevious();
597       break;
598
599     case TMSG_PLAYLISTPLAYER_ADD:
600       if(pMsg->lpVoid)
601       {
602         CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
603
604         g_playlistPlayer.Add(pMsg->dwParam1, (*list));
605         delete list;
606       }
607       break;
608
609     case TMSG_PLAYLISTPLAYER_INSERT:
610       if (pMsg->lpVoid)
611       {
612         CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
613         g_playlistPlayer.Insert(pMsg->dwParam1, (*list), pMsg->dwParam2);
614         delete list;
615       }
616       break;
617
618     case TMSG_PLAYLISTPLAYER_REMOVE:
619       if (pMsg->dwParam1 != (unsigned int) -1)
620         g_playlistPlayer.Remove(pMsg->dwParam1,pMsg->dwParam2);
621       break;
622
623     case TMSG_PLAYLISTPLAYER_CLEAR:
624       g_playlistPlayer.ClearPlaylist(pMsg->dwParam1);
625       break;
626
627     case TMSG_PLAYLISTPLAYER_SHUFFLE:
628       g_playlistPlayer.SetShuffle(pMsg->dwParam1, pMsg->dwParam2 > 0);
629       break;
630
631     case TMSG_PLAYLISTPLAYER_REPEAT:
632       g_playlistPlayer.SetRepeat(pMsg->dwParam1, (PLAYLIST::REPEAT_STATE)pMsg->dwParam2);
633       break;
634
635     case TMSG_PLAYLISTPLAYER_GET_ITEMS:
636       if (pMsg->lpVoid)
637       {
638         PLAYLIST::CPlayList playlist = g_playlistPlayer.GetPlaylist(pMsg->dwParam1);
639         CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
640
641         for (int i = 0; i < playlist.size(); i++)
642           list->Add(CFileItemPtr(new CFileItem(*playlist[i])));
643       }
644       break;
645
646     case TMSG_PLAYLISTPLAYER_SWAP:
647       if (pMsg->lpVoid)
648       {
649         vector<int> *indexes = (vector<int> *)pMsg->lpVoid;
650         if (indexes->size() == 2)
651           g_playlistPlayer.Swap(pMsg->dwParam1, indexes->at(0), indexes->at(1));
652         delete indexes;
653       }
654       break;
655
656     // Window messages below here...
657     case TMSG_DIALOG_DOMODAL:  //doModel of window
658       {
659         CGUIDialog* pDialog = (CGUIDialog*)g_windowManager.GetWindow(pMsg->dwParam1);
660         if (!pDialog) return ;
661         pDialog->DoModal();
662       }
663       break;
664
665     case TMSG_NETWORKMESSAGE:
666       {
667         g_application.getNetwork().NetworkMessage((CNetwork::EMESSAGE)pMsg->dwParam1, (int)pMsg->dwParam2);
668       }
669       break;
670
671     case TMSG_GUI_DO_MODAL:
672       {
673         CGUIDialog *pDialog = (CGUIDialog *)pMsg->lpVoid;
674         if (pDialog)
675           pDialog->DoModal((int)pMsg->dwParam1, pMsg->strParam);
676       }
677       break;
678
679     case TMSG_GUI_SHOW:
680       {
681         CGUIDialog *pDialog = (CGUIDialog *)pMsg->lpVoid;
682         if (pDialog)
683           pDialog->Show();
684       }
685       break;
686
687     case TMSG_GUI_WINDOW_CLOSE:
688       {
689         CGUIWindow *window = (CGUIWindow *)pMsg->lpVoid;
690         if (window)
691           window->Close(pMsg->dwParam2 & 0x1 ? true : false, pMsg->dwParam1, pMsg->dwParam2 & 0x2 ? true : false);
692       }
693       break;
694
695     case TMSG_GUI_ACTIVATE_WINDOW:
696       {
697         g_windowManager.ActivateWindow(pMsg->dwParam1, pMsg->params, pMsg->dwParam2 > 0);
698       }
699       break;
700
701     case TMSG_GUI_ADDON_DIALOG:
702       {
703         if (pMsg->lpVoid)
704         { // TODO: This is ugly - really these python dialogs should just be normal XBMC dialogs
705           ((ADDON::CGUIAddonWindowDialog *) pMsg->lpVoid)->Show_Internal(pMsg->dwParam2 > 0);
706         }
707       }
708       break;
709
710 #ifdef HAS_PYTHON
711     case TMSG_GUI_PYTHON_DIALOG:
712       {
713         // This hack is not much better but at least I don't need to make ApplicationMessenger
714         //  know about Addon (Python) specific classes.
715         CAction caction(pMsg->dwParam1);
716         ((CGUIWindow*)pMsg->lpVoid)->OnAction(caction);
717       }
718       break;
719 #endif
720
721     case TMSG_GUI_ACTION:
722       {
723         if (pMsg->lpVoid)
724         {
725           CAction *action = (CAction *)pMsg->lpVoid;
726           if (pMsg->dwParam1 == WINDOW_INVALID)
727             g_application.OnAction(*action);
728           else
729           {
730             CGUIWindow *pWindow = g_windowManager.GetWindow(pMsg->dwParam1);  
731             if (pWindow)
732               pWindow->OnAction(*action);
733             else
734               CLog::Log(LOGWARNING, "Failed to get window with ID %i to send an action to", pMsg->dwParam1);
735           }
736           delete action;
737         }
738       }
739       break;
740
741     case TMSG_GUI_MESSAGE:
742       {
743         if (pMsg->lpVoid)
744         {
745           CGUIMessage *message = (CGUIMessage *)pMsg->lpVoid;
746           g_windowManager.SendMessage(*message, pMsg->dwParam1);
747           delete message;
748         }
749       }
750       break;
751
752     case TMSG_GUI_INFOLABEL:
753       {
754         if (pMsg->lpVoid)
755         {
756           vector<CStdString> *infoLabels = (vector<CStdString> *)pMsg->lpVoid;
757           for (unsigned int i = 0; i < pMsg->params.size(); i++)
758             infoLabels->push_back(g_infoManager.GetLabel(g_infoManager.TranslateString(pMsg->params[i])));
759         }
760       }
761       break;
762     case TMSG_GUI_INFOBOOL:
763       {
764         if (pMsg->lpVoid)
765         {
766           vector<bool> *infoLabels = (vector<bool> *)pMsg->lpVoid;
767           for (unsigned int i = 0; i < pMsg->params.size(); i++)
768             infoLabels->push_back(g_infoManager.EvaluateBool(pMsg->params[i]));
769         }
770       }
771       break;
772
773     case TMSG_CALLBACK:
774       {
775         ThreadMessageCallback *callback = (ThreadMessageCallback*)pMsg->lpVoid;
776         callback->callback(callback->userptr);
777       }
778       break;
779
780     case TMSG_VOLUME_SHOW:
781       {
782         CAction action((int)pMsg->dwParam1);
783         g_application.ShowVolumeBar(&action);
784       }
785       break;
786
787     case TMSG_SPLASH_MESSAGE:
788       {
789         if (g_application.GetSplash())
790           g_application.GetSplash()->Show(pMsg->strParam);
791       }
792       break;
793       
794     case TMSG_DISPLAY_SETUP:
795     {
796       *((bool*)pMsg->lpVoid) = g_application.InitWindow();
797       g_application.SetRenderGUI(true);
798     }
799     break;
800     
801     case TMSG_DISPLAY_DESTROY:
802     {
803       *((bool*)pMsg->lpVoid) = g_application.DestroyWindow();
804       g_application.SetRenderGUI(false);
805     }
806     break;
807
808     case TMSG_UPDATE_CURRENT_ITEM:
809     {
810       CFileItem* item = (CFileItem*)pMsg->lpVoid;
811       if (!item)
812         return;
813       if (pMsg->dwParam1 == 1 && item->HasMusicInfoTag()) // only grab music tag
814         g_infoManager.SetCurrentSongTag(*item->GetMusicInfoTag());
815       else if (pMsg->dwParam1 == 2 && item->HasVideoInfoTag()) // only grab video tag
816         g_infoManager.SetCurrentVideoTag(*item->GetVideoInfoTag());
817       else
818         g_infoManager.SetCurrentItem(*item);
819       delete item;
820       break;
821     }
822
823     case TMSG_LOADPROFILE:
824     {
825       CGUIWindowLoginScreen::LoadProfile(pMsg->dwParam1);
826       break;
827     }
828     case TMSG_CECTOGGLESTATE:
829     {
830       *((bool*)pMsg->lpVoid) = g_peripherals.ToggleDeviceState(STATE_SWITCH_TOGGLE);
831       break;
832     }
833     case TMSG_CECACTIVATESOURCE:
834     {
835       *((bool*)pMsg->lpVoid) = g_peripherals.ToggleDeviceState(STATE_ACTIVATE_SOURCE);
836       break;
837     }
838     case TMSG_CECSTANDBY:
839     {
840       *((bool*)pMsg->lpVoid) = g_peripherals.ToggleDeviceState(STATE_STANDBY);
841       break;
842     }
843     case TMSG_START_ANDROID_ACTIVITY:
844     {
845 #if defined(TARGET_ANDROID)
846       if (pMsg->params.size())
847       {
848         CXBMCApp::StartActivity(pMsg->params[0],
849                                 pMsg->params.size() > 1 ? pMsg->params[1] : "",
850                                 pMsg->params.size() > 2 ? pMsg->params[2] : "",
851                                 pMsg->params.size() > 3 ? pMsg->params[3] : "");
852       }
853 #endif
854       break;
855     }
856   }
857 }
858
859 void CApplicationMessenger::ProcessWindowMessages()
860 {
861   CSingleLock lock (m_critSection);
862   //message type is window, process window messages
863   while (m_vecWindowMessages.size() > 0)
864   {
865     ThreadMessage* pMsg = m_vecWindowMessages.front();
866     //first remove the message from the queue, else the message could be processed more then once
867     m_vecWindowMessages.pop();
868
869     // leave here in case we make more thread messages from this one
870
871     boost::shared_ptr<CEvent> waitEvent = pMsg->waitEvent;
872     lock.Leave(); // <- see the large comment in SendMessage ^
873
874     ProcessMessage(pMsg);
875     if (waitEvent)
876       waitEvent->Set();
877     delete pMsg;
878
879     lock.Enter();
880   }
881 }
882
883 int CApplicationMessenger::SetResponse(CStdString response)
884 {
885   CSingleLock lock (m_critBuffer);
886   bufferResponse=response;
887   lock.Leave();
888   return 0;
889 }
890
891 CStdString CApplicationMessenger::GetResponse()
892 {
893   CStdString tmp;
894   CSingleLock lock (m_critBuffer);
895   tmp=bufferResponse;
896   lock.Leave();
897   return tmp;
898 }
899
900 void CApplicationMessenger::ExecBuiltIn(const CStdString &command, bool wait)
901 {
902   ThreadMessage tMsg = {TMSG_EXECUTE_BUILT_IN};
903   tMsg.strParam = command;
904   SendMessage(tMsg, wait);
905 }
906
907 void CApplicationMessenger::MediaPlay(string filename)
908 {
909   CFileItem item(filename, false);
910   MediaPlay(item);
911 }
912
913 void CApplicationMessenger::MediaPlay(const CFileItem &item)
914 {
915   CFileItemList list;
916   list.Add(CFileItemPtr(new CFileItem(item)));
917
918   MediaPlay(list);
919 }
920
921 void CApplicationMessenger::MediaPlay(const CFileItemList &list, int song)
922 {
923   ThreadMessage tMsg = {TMSG_MEDIA_PLAY};
924   CFileItemList* listcopy = new CFileItemList();
925   listcopy->Copy(list);
926   tMsg.lpVoid = (void*)listcopy;
927   tMsg.dwParam1 = song;
928   tMsg.dwParam2 = 1;
929   SendMessage(tMsg, true);
930 }
931
932 void CApplicationMessenger::MediaPlay(int playlistid, int song /* = -1 */)
933 {
934   ThreadMessage tMsg = {TMSG_MEDIA_PLAY};
935   tMsg.lpVoid = NULL;
936   tMsg.dwParam1 = playlistid;
937   tMsg.dwParam2 = song;
938   SendMessage(tMsg, true);
939 }
940
941 void CApplicationMessenger::PlayFile(const CFileItem &item, bool bRestart /*= false*/)
942 {
943   ThreadMessage tMsg = {TMSG_MEDIA_PLAY};
944   CFileItem *pItem = new CFileItem(item);
945   tMsg.lpVoid = (void *)pItem;
946   tMsg.dwParam1 = bRestart ? 1 : 0;
947   tMsg.dwParam2 = 0;
948   SendMessage(tMsg, false);
949 }
950
951 void CApplicationMessenger::MediaStop(bool bWait /* = true */, int playlistid /* = -1 */)
952 {
953   ThreadMessage tMsg = {TMSG_MEDIA_STOP};
954   tMsg.dwParam1 = playlistid;
955   SendMessage(tMsg, bWait);
956 }
957
958 void CApplicationMessenger::MediaPause()
959 {
960   ThreadMessage tMsg = {TMSG_MEDIA_PAUSE};
961   SendMessage(tMsg, true);
962 }
963
964 void CApplicationMessenger::MediaUnPause()
965 {
966   ThreadMessage tMsg = {TMSG_MEDIA_UNPAUSE};
967   SendMessage(tMsg, true);
968 }
969
970 void CApplicationMessenger::MediaPauseIfPlaying()
971 {
972   ThreadMessage tMsg = {TMSG_MEDIA_PAUSE_IF_PLAYING};
973   SendMessage(tMsg, true);
974 }
975
976 void CApplicationMessenger::MediaRestart(bool bWait)
977 {
978   ThreadMessage tMsg = {TMSG_MEDIA_RESTART};
979   SendMessage(tMsg, bWait);
980 }
981
982 void CApplicationMessenger::PlayListPlayerPlay()
983 {
984   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_PLAY, (unsigned int) -1};
985   SendMessage(tMsg, true);
986 }
987
988 void CApplicationMessenger::PlayListPlayerPlay(int iSong)
989 {
990   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_PLAY, (unsigned int)iSong};
991   SendMessage(tMsg, true);
992 }
993
994 bool CApplicationMessenger::PlayListPlayerPlaySongId(int songId)
995 {
996   bool returnState;
997   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_PLAY_SONG_ID, (unsigned int)songId};
998   tMsg.lpVoid = (void *)&returnState;
999   SendMessage(tMsg, true);
1000   return returnState;
1001 }
1002
1003 void CApplicationMessenger::PlayListPlayerNext()
1004 {
1005   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_NEXT};
1006   SendMessage(tMsg, true);
1007 }
1008
1009 void CApplicationMessenger::PlayListPlayerPrevious()
1010 {
1011   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_PREV};
1012   SendMessage(tMsg, true);
1013 }
1014
1015 void CApplicationMessenger::PlayListPlayerAdd(int playlist, const CFileItem &item)
1016 {
1017   CFileItemList list;
1018   list.Add(CFileItemPtr(new CFileItem(item)));
1019
1020   PlayListPlayerAdd(playlist, list);
1021 }
1022
1023 void CApplicationMessenger::PlayListPlayerAdd(int playlist, const CFileItemList &list)
1024 {
1025   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_ADD};
1026   CFileItemList* listcopy = new CFileItemList();
1027   listcopy->Copy(list);
1028   tMsg.lpVoid = (void*)listcopy;
1029   tMsg.dwParam1 = playlist;
1030   SendMessage(tMsg, true);
1031 }
1032
1033 void CApplicationMessenger::PlayListPlayerInsert(int playlist, const CFileItem &item, int index)
1034 {
1035   CFileItemList list;
1036   list.Add(CFileItemPtr(new CFileItem(item)));
1037   PlayListPlayerInsert(playlist, list, index);
1038 }
1039
1040 void CApplicationMessenger::PlayListPlayerInsert(int playlist, const CFileItemList &list, int index)
1041 {
1042   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_INSERT};
1043   CFileItemList* listcopy = new CFileItemList();
1044   listcopy->Copy(list);
1045   tMsg.lpVoid = (void *)listcopy;
1046   tMsg.dwParam1 = playlist;
1047   tMsg.dwParam2 = index;
1048   SendMessage(tMsg, true);
1049 }
1050
1051 void CApplicationMessenger::PlayListPlayerRemove(int playlist, int position)
1052 {
1053   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_REMOVE, (unsigned int)playlist, (unsigned int)position};
1054   SendMessage(tMsg, true);
1055 }
1056
1057 void CApplicationMessenger::PlayListPlayerClear(int playlist)
1058 {
1059   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_CLEAR};
1060   tMsg.dwParam1 = playlist;
1061   SendMessage(tMsg, true);
1062 }
1063
1064 void CApplicationMessenger::PlayListPlayerShuffle(int playlist, bool shuffle)
1065 {
1066   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_SHUFFLE};
1067   tMsg.dwParam1 = playlist;
1068   tMsg.dwParam2 = shuffle ? 1 : 0;
1069   SendMessage(tMsg, true);
1070 }
1071
1072 void CApplicationMessenger::PlayListPlayerGetItems(int playlist, CFileItemList &list)
1073 {
1074   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_GET_ITEMS};
1075   tMsg.dwParam1 = playlist;
1076   tMsg.lpVoid = (void *)&list;
1077   SendMessage(tMsg, true);
1078 }
1079
1080 void CApplicationMessenger::PlayListPlayerSwap(int playlist, int indexItem1, int indexItem2)
1081 {
1082   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_SWAP};
1083   tMsg.dwParam1 = playlist;
1084   vector<int> *indexes = new vector<int>();
1085   indexes->push_back(indexItem1);
1086   indexes->push_back(indexItem2);
1087   tMsg.lpVoid = (void *)indexes;
1088   SendMessage(tMsg, true);
1089 }
1090
1091 void CApplicationMessenger::PlayListPlayerRepeat(int playlist, int repeatState)
1092 {
1093   ThreadMessage tMsg = {TMSG_PLAYLISTPLAYER_REPEAT};
1094   tMsg.dwParam1 = playlist;
1095   tMsg.dwParam2 = repeatState;
1096   SendMessage(tMsg, true);
1097 }
1098
1099 void CApplicationMessenger::PictureShow(string filename)
1100 {
1101   ThreadMessage tMsg = {TMSG_PICTURE_SHOW};
1102   tMsg.strParam = filename;
1103   SendMessage(tMsg);
1104 }
1105
1106 void CApplicationMessenger::PictureSlideShow(string pathname, bool addTBN /* = false */)
1107 {
1108   unsigned int dwMessage = TMSG_PICTURE_SLIDESHOW;
1109   ThreadMessage tMsg = {dwMessage};
1110   tMsg.strParam = pathname;
1111   tMsg.dwParam1 = addTBN ? 1 : 0;
1112   SendMessage(tMsg);
1113 }
1114
1115 void CApplicationMessenger::SetGUILanguage(const std::string &strLanguage)
1116 {
1117   ThreadMessage tMsg = {TMSG_SETLANGUAGE};
1118   tMsg.strParam = strLanguage;
1119   SendMessage(tMsg);
1120 }
1121
1122 void CApplicationMessenger::Shutdown()
1123 {
1124   ThreadMessage tMsg = {TMSG_SHUTDOWN};
1125   SendMessage(tMsg);
1126 }
1127
1128 void CApplicationMessenger::Powerdown()
1129 {
1130   ThreadMessage tMsg = {TMSG_POWERDOWN};
1131   SendMessage(tMsg);
1132 }
1133
1134 void CApplicationMessenger::Quit()
1135 {
1136   ThreadMessage tMsg = {TMSG_QUIT};
1137   SendMessage(tMsg);
1138 }
1139
1140 void CApplicationMessenger::Hibernate()
1141 {
1142   ThreadMessage tMsg = {TMSG_HIBERNATE};
1143   SendMessage(tMsg);
1144 }
1145
1146 void CApplicationMessenger::Suspend()
1147 {
1148   ThreadMessage tMsg = {TMSG_SUSPEND};
1149   SendMessage(tMsg);
1150 }
1151
1152 void CApplicationMessenger::Restart()
1153 {
1154   ThreadMessage tMsg = {TMSG_RESTART};
1155   SendMessage(tMsg);
1156 }
1157
1158 void CApplicationMessenger::Reset()
1159 {
1160   ThreadMessage tMsg = {TMSG_RESET};
1161   SendMessage(tMsg);
1162 }
1163
1164 void CApplicationMessenger::RestartApp()
1165 {
1166   ThreadMessage tMsg = {TMSG_RESTARTAPP};
1167   SendMessage(tMsg);
1168 }
1169
1170 void CApplicationMessenger::InhibitIdleShutdown(bool inhibit)
1171 {
1172   ThreadMessage tMsg = {TMSG_INHIBITIDLESHUTDOWN, (unsigned int)inhibit};
1173   SendMessage(tMsg);
1174 }
1175
1176 void CApplicationMessenger::ActivateScreensaver()
1177 {
1178   ThreadMessage tMsg = {TMSG_ACTIVATESCREENSAVER};
1179   SendMessage(tMsg);
1180 }
1181
1182 void CApplicationMessenger::NetworkMessage(unsigned int dwMessage, unsigned int dwParam)
1183 {
1184   ThreadMessage tMsg = {TMSG_NETWORKMESSAGE, dwMessage, dwParam};
1185   SendMessage(tMsg);
1186 }
1187
1188 void CApplicationMessenger::SwitchToFullscreen()
1189 {
1190   /* FIXME: ideally this call should return upon a successfull switch but currently
1191      is causing deadlocks between the dvdplayer destructor and the rendermanager
1192   */
1193   ThreadMessage tMsg = {TMSG_SWITCHTOFULLSCREEN};
1194   SendMessage(tMsg, false);
1195 }
1196
1197 void CApplicationMessenger::Minimize(bool wait)
1198 {
1199   ThreadMessage tMsg = {TMSG_MINIMIZE};
1200   SendMessage(tMsg, wait);
1201 }
1202
1203 void CApplicationMessenger::DoModal(CGUIDialog *pDialog, int iWindowID, const CStdString &param)
1204 {
1205   ThreadMessage tMsg = {TMSG_GUI_DO_MODAL};
1206   tMsg.lpVoid = pDialog;
1207   tMsg.dwParam1 = (unsigned int)iWindowID;
1208   tMsg.strParam = param;
1209   SendMessage(tMsg, true);
1210 }
1211
1212 void CApplicationMessenger::ExecOS(const CStdString &command, bool waitExit)
1213 {
1214   ThreadMessage tMsg = {TMSG_EXECUTE_OS};
1215   tMsg.strParam = command;
1216   tMsg.dwParam1 = (unsigned int)waitExit;
1217   SendMessage(tMsg, false);
1218 }
1219
1220 void CApplicationMessenger::UserEvent(int code)
1221 {
1222   ThreadMessage tMsg = {(unsigned int)code};
1223   SendMessage(tMsg, false);
1224 }
1225
1226 void CApplicationMessenger::Show(CGUIDialog *pDialog)
1227 {
1228   ThreadMessage tMsg = {TMSG_GUI_SHOW};
1229   tMsg.lpVoid = pDialog;
1230   SendMessage(tMsg, true);
1231 }
1232
1233 void CApplicationMessenger::Close(CGUIWindow *window, bool forceClose, bool waitResult /*= true*/, int nextWindowID /*= 0*/, bool enableSound /*= true*/)
1234 {
1235   ThreadMessage tMsg = {TMSG_GUI_WINDOW_CLOSE, (unsigned int)nextWindowID};
1236   tMsg.dwParam2 = (unsigned int)((forceClose ? 0x01 : 0) | (enableSound ? 0x02 : 0));
1237   tMsg.lpVoid = window;
1238   SendMessage(tMsg, waitResult);
1239 }
1240
1241 void CApplicationMessenger::ActivateWindow(int windowID, const vector<CStdString> &params, bool swappingWindows)
1242 {
1243   ThreadMessage tMsg = {TMSG_GUI_ACTIVATE_WINDOW, (unsigned int)windowID, swappingWindows ? 1u : 0u};
1244   tMsg.params = params;
1245   SendMessage(tMsg, true);
1246 }
1247
1248 void CApplicationMessenger::SendAction(const CAction &action, int windowID, bool waitResult)
1249 {
1250   ThreadMessage tMsg = {TMSG_GUI_ACTION};
1251   tMsg.dwParam1 = windowID;
1252   tMsg.lpVoid = new CAction(action);
1253   SendMessage(tMsg, waitResult);
1254 }
1255
1256 void CApplicationMessenger::SendGUIMessage(const CGUIMessage &message, int windowID, bool waitResult)
1257 {
1258   ThreadMessage tMsg = {TMSG_GUI_MESSAGE};
1259   tMsg.dwParam1 = windowID == WINDOW_INVALID ? 0 : windowID;
1260   tMsg.lpVoid = new CGUIMessage(message);
1261   SendMessage(tMsg, waitResult);
1262 }
1263
1264 vector<CStdString> CApplicationMessenger::GetInfoLabels(const vector<CStdString> &properties)
1265 {
1266   vector<CStdString> infoLabels;
1267
1268   ThreadMessage tMsg = {TMSG_GUI_INFOLABEL};
1269   tMsg.params = properties;
1270   tMsg.lpVoid = (void*)&infoLabels;
1271   SendMessage(tMsg, true);
1272   return infoLabels;
1273 }
1274
1275 vector<bool> CApplicationMessenger::GetInfoBooleans(const vector<CStdString> &properties)
1276 {
1277   vector<bool> infoLabels;
1278
1279   ThreadMessage tMsg = {TMSG_GUI_INFOBOOL};
1280   tMsg.params = properties;
1281   tMsg.lpVoid = (void*)&infoLabels;
1282   SendMessage(tMsg, true);
1283   return infoLabels;
1284 }
1285
1286 void CApplicationMessenger::ShowVolumeBar(bool up)
1287 {
1288   ThreadMessage tMsg = {TMSG_VOLUME_SHOW};
1289   tMsg.dwParam1 = up ? ACTION_VOLUME_UP : ACTION_VOLUME_DOWN;
1290   SendMessage(tMsg, false);
1291 }
1292
1293 void CApplicationMessenger::SetSplashMessage(const CStdString& message)
1294 {
1295   ThreadMessage tMsg = {TMSG_SPLASH_MESSAGE};
1296   tMsg.strParam = message;
1297   SendMessage(tMsg, true);
1298 }
1299
1300 void CApplicationMessenger::SetSplashMessage(int stringID)
1301 {
1302   SetSplashMessage(g_localizeStrings.Get(stringID));
1303 }
1304
1305 bool CApplicationMessenger::SetupDisplay()
1306 {
1307   bool result;
1308   
1309   ThreadMessage tMsg = {TMSG_DISPLAY_SETUP};
1310   tMsg.lpVoid = (void*)&result;
1311   SendMessage(tMsg, true);
1312   
1313   return result;
1314 }
1315
1316 bool CApplicationMessenger::DestroyDisplay()
1317 {
1318   bool result;
1319   
1320   ThreadMessage tMsg = {TMSG_DISPLAY_DESTROY};
1321   tMsg.lpVoid = (void*)&result;
1322   SendMessage(tMsg, true);
1323   
1324   return result;
1325 }
1326
1327 void CApplicationMessenger::SetCurrentSongTag(const CMusicInfoTag& tag)
1328 {
1329   CFileItem* item = new CFileItem(tag);
1330   ThreadMessage tMsg = {TMSG_UPDATE_CURRENT_ITEM};
1331   tMsg.dwParam1 = 1;
1332   tMsg.lpVoid = (void*)item;
1333   SendMessage(tMsg, false);
1334 }
1335
1336 void CApplicationMessenger::SetCurrentVideoTag(const CVideoInfoTag& tag)
1337 {
1338   CFileItem* item = new CFileItem(tag);
1339   ThreadMessage tMsg = {TMSG_UPDATE_CURRENT_ITEM};
1340   tMsg.dwParam1 = 2;
1341   tMsg.lpVoid = (void*)item;
1342   SendMessage(tMsg, false);
1343 }
1344
1345 void CApplicationMessenger::SetCurrentItem(const CFileItem& item)
1346 {
1347   CFileItem* item2 = new CFileItem(item);
1348   ThreadMessage tMsg = {TMSG_UPDATE_CURRENT_ITEM};
1349   tMsg.lpVoid = (void*)item2;
1350   SendMessage(tMsg, false);
1351 }
1352
1353 void CApplicationMessenger::LoadProfile(unsigned int idx)
1354 {
1355   ThreadMessage tMsg = {TMSG_LOADPROFILE};
1356   tMsg.dwParam1 = idx;
1357   SendMessage(tMsg, false);
1358 }
1359
1360 void CApplicationMessenger::StartAndroidActivity(const vector<CStdString> &params)
1361 {
1362   ThreadMessage tMsg = {TMSG_START_ANDROID_ACTIVITY};
1363   tMsg.params = params;
1364   SendMessage(tMsg, false);
1365 }
1366
1367 bool CApplicationMessenger::CECToggleState()
1368 {
1369   bool result;
1370
1371   ThreadMessage tMsg = {TMSG_CECTOGGLESTATE};
1372   tMsg.lpVoid = (void*)&result;
1373   SendMessage(tMsg, false);
1374
1375   return result;
1376 }
1377
1378 bool CApplicationMessenger::CECActivateSource()
1379 {
1380   bool result;
1381
1382   ThreadMessage tMsg = {TMSG_CECACTIVATESOURCE};
1383   tMsg.lpVoid = (void*)&result;
1384   SendMessage(tMsg, false);
1385
1386   return result;
1387 }
1388
1389 bool CApplicationMessenger::CECStandby()
1390 {
1391   bool result;
1392
1393   ThreadMessage tMsg = {TMSG_CECSTANDBY};
1394   tMsg.lpVoid = (void*)&result;
1395   SendMessage(tMsg, false);
1396
1397   return result;
1398 }