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