added: signal dbusserver to stop before joining the thread (other servers might follow)
[xbmc:paulepanters-xbmc.git] / XBMC / xbmc / Application.cpp
1 /*
2  *      Copyright (C) 2005-2008 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, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #include "Application.h"
23 #include "Splash.h"
24 #include "KeyboardLayoutConfiguration.h"
25 #include "LangInfo.h"
26 #include "Util.h"
27 #include "Picture.h"
28 #include "TextureManager.h"
29 #include "cores/PlayerCoreFactory.h"
30 #include "cores/dvdplayer/DVDFileInfo.h"
31 #include "PlayListPlayer.h"
32 #include "Autorun.h"
33 #ifdef HAS_LCD
34 #include "utils/LCDFactory.h"
35 #else
36 #include "GUILabelControl.h"  // needed for CInfoLabel
37 #include "GUIImage.h"
38 #endif
39 #include "GUIControlProfiler.h"
40 #include "LangCodeExpander.h"
41 #include "utils/GUIInfoManager.h"
42 #include "PlayListFactory.h"
43 #include "GUIFontManager.h"
44 #include "GUIColorManager.h"
45 #include "SkinInfo.h"
46 #ifdef HAS_PYTHON
47 #include "lib/libPython/XBPython.h"
48 #endif
49 #include "ButtonTranslator.h"
50 #include "GUIAudioManager.h"
51 #include "lib/libscrobbler/lastfmscrobbler.h"
52 #include "lib/libscrobbler/librefmscrobbler.h"
53 #include "GUIPassword.h"
54 #include "ApplicationMessenger.h"
55 #include "SectionLoader.h"
56 #include "cores/DllLoader/DllLoaderContainer.h"
57 #include "GUIUserMessages.h"
58 #include "FileSystem/DirectoryCache.h"
59 #include "FileSystem/StackDirectory.h"
60 #include "FileSystem/SpecialProtocol.h"
61 #include "FileSystem/DllLibCurl.h"
62 #include "FileSystem/CMythSession.h"
63 #include "FileSystem/PluginDirectory.h"
64 #ifdef HAS_FILESYSTEM_SAP
65 #include "FileSystem/SAPDirectory.h"
66 #endif
67 #ifdef HAS_FILESYSTEM_HTSP
68 #include "FileSystem/HTSPDirectory.h"
69 #endif
70 #include "utils/TuxBoxUtil.h"
71 #include "utils/SystemInfo.h"
72 #include "ApplicationRenderer.h"
73 #include "GUILargeTextureManager.h"
74 #include "LastFmManager.h"
75 #include "SmartPlaylist.h"
76 #include "FileSystem/RarManager.h"
77 #include "PlayList.h"
78 #include "WindowingFactory.h"
79 #include "PowerManager.h"
80 #include "DPMSSupport.h"
81 #include "Settings.h"
82 #include "AdvancedSettings.h"
83 #include "LocalizeStrings.h"
84 #include "CPUInfo.h"
85
86 #include "KeyboardStat.h"
87 #include "MouseStat.h"
88
89 #if defined(FILESYSTEM) && !defined(_LINUX)
90 #include "FileSystem/FileDAAP.h"
91 #endif
92 #ifdef HAS_UPNP
93 #include "UPnP.h"
94 #include "FileSystem/UPnPDirectory.h"
95 #endif
96 #if defined(_LINUX) && defined(HAS_FILESYSTEM_SMB)
97 #include "FileSystem/SMBDirectory.h"
98 #endif
99 #include "PartyModeManager.h"
100 #ifdef HAS_VIDEO_PLAYBACK
101 #include "cores/VideoRenderers/RenderManager.h"
102 #endif
103 #ifdef HAS_KARAOKE
104 #include "karaoke/karaokelyricsmanager.h"
105 #include "karaoke/GUIDialogKaraokeSongSelector.h"
106 #include "karaoke/GUIWindowKaraokeLyrics.h"
107 #endif
108 #include "AudioContext.h"
109 #include "GUIFontTTF.h"
110 #include "utils/Network.h"
111 #include "xbox/IoSupport.h"
112 #include "Zeroconf.h"
113 #include "ZeroconfBrowser.h"
114 #ifndef _LINUX
115 #include "utils/Win32Exception.h"
116 #endif
117 #ifdef HAS_WEB_SERVER
118 #include "lib/libGoAhead/XBMChttp.h"
119 #include "lib/libGoAhead/WebServer.h"
120 #endif
121 #ifdef HAS_FTP_SERVER
122 #include "lib/libfilezilla/xbfilezilla.h"
123 #endif
124 #ifdef HAS_TIME_SERVER
125 #include "utils/Sntp.h"
126 #endif
127 #ifdef HAS_EVENT_SERVER
128 #include "utils/EventServer.h"
129 #endif
130 #ifdef HAS_DBUS_SERVER
131 #include "utils/DbusServer.h"
132 #endif
133
134
135 // Windows includes
136 #include "GUIWindowManager.h"
137 #include "GUIWindowHome.h"
138 #include "GUIStandardWindow.h"
139 #include "GUIWindowSettings.h"
140 #include "GUIWindowFileManager.h"
141 #include "GUIWindowSettingsCategory.h"
142 #include "GUIWindowMusicPlaylist.h"
143 #include "GUIWindowMusicSongs.h"
144 #include "GUIWindowMusicNav.h"
145 #include "GUIWindowMusicPlaylistEditor.h"
146 #include "GUIWindowVideoPlaylist.h"
147 #include "GUIWindowMusicInfo.h"
148 #include "GUIWindowVideoInfo.h"
149 #include "GUIWindowVideoFiles.h"
150 #include "GUIWindowVideoNav.h"
151 #include "GUIWindowSettingsProfile.h"
152 #ifdef HAS_GL
153 #include "GUIWindowTestPatternGL.h"
154 #endif
155 #ifdef HAS_DX
156 #include "GUIWindowTestPatternDX.h"
157 #endif
158 #include "GUIWindowSettingsScreenCalibration.h"
159 #include "GUIWindowPrograms.h"
160 #include "GUIWindowPictures.h"
161 #include "GUIWindowScripts.h"
162 #include "GUIWindowWeather.h"
163 #include "GUIWindowLoginScreen.h"
164 #include "GUIWindowVisualisation.h"
165 #include "GUIWindowSystemInfo.h"
166 #include "GUIWindowScreensaver.h"
167 #include "GUIWindowSlideShow.h"
168 #include "GUIWindowStartup.h"
169 #include "GUIWindowFullScreen.h"
170 #include "GUIWindowOSD.h"
171 #include "GUIWindowMusicOverlay.h"
172 #include "GUIWindowVideoOverlay.h"
173
174 // Dialog includes
175 #include "GUIDialogMusicOSD.h"
176 #include "GUIDialogVisualisationSettings.h"
177 #include "GUIDialogVisualisationPresetList.h"
178 #include "GUIWindowScriptsInfo.h"
179 #include "GUIDialogNetworkSetup.h"
180 #include "GUIDialogMediaSource.h"
181 #include "GUIDialogVideoSettings.h"
182 #include "GUIDialogAudioSubtitleSettings.h"
183 #include "GUIDialogVideoBookmarks.h"
184 #include "GUIDialogProfileSettings.h"
185 #include "GUIDialogLockSettings.h"
186 #include "GUIDialogContentSettings.h"
187 #include "GUIDialogVideoScan.h"
188 #include "GUIDialogBusy.h"
189
190 #include "GUIDialogKeyboard.h"
191 #include "GUIDialogYesNo.h"
192 #include "GUIDialogOK.h"
193 #include "GUIDialogProgress.h"
194 #include "GUIDialogSelect.h"
195 #include "GUIDialogFileStacking.h"
196 #include "GUIDialogNumeric.h"
197 #include "GUIDialogGamepad.h"
198 #include "GUIDialogSubMenu.h"
199 #include "GUIDialogFavourites.h"
200 #include "GUIDialogButtonMenu.h"
201 #include "GUIDialogContextMenu.h"
202 #include "GUIDialogMusicScan.h"
203 #include "GUIDialogPlayerControls.h"
204 #include "GUIDialogSongInfo.h"
205 #include "GUIDialogSmartPlaylistEditor.h"
206 #include "GUIDialogSmartPlaylistRule.h"
207 #include "GUIDialogPictureInfo.h"
208 #include "GUIDialogPluginSettings.h"
209 #ifdef HAS_LINUX_NETWORK
210 #include "GUIDialogAccessPoints.h"
211 #endif
212 #include "GUIDialogFullScreenInfo.h"
213 #include "GUIDialogSlider.h"
214 #include "cores/dlgcache.h"
215
216 #ifdef HAS_PERFORMANCE_SAMPLE
217 #include "utils/PerformanceSample.h"
218 #else
219 #define MEASURE_FUNCTION
220 #endif
221
222 #ifdef HAS_SDL_AUDIO
223 #include <SDL/SDL_mixer.h>
224 #endif
225 #if defined(HAS_SDL) && defined(_WIN32)
226 #include <SDL/SDL_syswm.h>
227 #endif
228 #ifdef _WIN32
229 #include <shlobj.h>
230 #include "win32util.h"
231 #endif
232 #ifdef HAS_XRANDR
233 #include "XRandR.h"
234 #endif
235 #ifdef __APPLE__
236 #include "CocoaInterface.h"
237 #include "XBMCHelper.h"
238 #endif
239 #ifdef HAS_HAL
240 #include "linux/LinuxFileSystem.h"
241 #endif
242 #ifdef HAS_EVENT_SERVER
243 #include "utils/EventServer.h"
244 #endif
245 #ifdef HAVE_LIBVDPAU
246 #include "cores/dvdplayer/DVDCodecs/Video/VDPAU.h"
247 #endif
248 #ifdef HAS_DBUS_SERVER
249 #include "utils/DbusServer.h"
250 #endif
251
252 #ifdef HAS_DVD_DRIVE
253 #include "lib/libcdio/logging.h"
254 #endif
255
256 #include "MediaManager.h"
257
258 #ifdef _LINUX
259 #include "XHandle.h"
260 #endif
261
262 #ifdef HAS_LIRC
263 #include "common/LIRC.h"
264 #endif
265
266 using namespace std;
267 using namespace XFILE;
268 using namespace DIRECTORY;
269 #ifdef HAS_DVD_DRIVE
270 using namespace MEDIA_DETECT;
271 #endif
272 using namespace PLAYLIST;
273 using namespace VIDEO;
274 using namespace MUSIC_INFO;
275 #ifdef HAS_EVENT_SERVER
276 using namespace EVENTSERVER;
277 #endif
278 #ifdef HAS_DBUS_SERVER
279 using namespace DBUSSERVER;
280 #endif
281
282 // uncomment this if you want to use release libs in the debug build.
283 // Atm this saves you 7 mb of memory
284 #define USE_RELEASE_LIBS
285
286 #if defined(_WIN32)
287  #if defined(_DEBUG) && !defined(USE_RELEASE_LIBS)
288   #if defined(HAS_FILESYSTEM)
289     #pragma comment (lib,"../../xbmc/lib/libXBMS/libXBMSd.lib")    // SECTIONNAME=LIBXBMS
290     #pragma comment (lib,"../../xbmc/lib/libxdaap/libxdaapd.lib") // SECTIONNAME=LIBXDAAP
291     #pragma comment (lib,"../../xbmc/lib/libRTV/libRTVd_win32.lib")
292   #endif
293   #pragma comment (lib,"../../xbmc/lib/libGoAhead/goahead_win32d.lib") // SECTIONNAME=LIBHTTP
294   #pragma comment (lib,"../../xbmc/lib/sqLite/libSQLite3_win32d.lib")
295   #pragma comment (lib,"../../xbmc/lib/libshout/libshout_win32d.lib" )
296   #pragma comment (lib,"../../xbmc/lib/libcdio/libcdio_win32d.lib" )
297   #pragma comment (lib,"../../xbmc/lib/libiconv/libiconvd.lib")
298   #pragma comment (lib,"../../xbmc/lib/libfribidi/libfribidid.lib")
299   #pragma comment (lib,"../../xbmc/lib/libpcre/libpcred.lib")
300   #pragma comment (lib,"../../xbmc/lib/libsamplerate/libsamplerate_win32d.lib")
301  #else
302   #ifdef HAS_FILESYSTEM
303     #pragma comment (lib,"../../xbmc/lib/libXBMS/libXBMS.lib")
304     #pragma comment (lib,"../../xbmc/lib/libxdaap/libxdaap.lib")
305     #pragma comment (lib,"../../xbmc/lib/libRTV/libRTV_win32.lib")
306   #endif
307   #pragma comment (lib,"../../xbmc/lib/libGoAhead/goahead_win32.lib")
308   #pragma comment (lib,"../../xbmc/lib/sqLite/libSQLite3_win32.lib")
309   #pragma comment (lib,"../../xbmc/lib/libshout/libshout_win32.lib" )
310   #pragma comment (lib,"../../xbmc/lib/libcdio/libcdio_win32.lib" )
311   #pragma comment (lib,"../../xbmc/lib/libiconv/libiconv.lib")
312   #pragma comment (lib,"../../xbmc/lib/libfribidi/libfribidi.lib")
313   #pragma comment (lib,"../../xbmc/lib/libpcre/libpcre.lib")
314   #pragma comment (lib,"../../xbmc/lib/libsamplerate/libsamplerate_win32.lib")
315  #endif
316 #endif
317
318 #define MAX_FFWD_SPEED 5
319
320 CStdString g_LoadErrorStr;
321
322 //extern IDirectSoundRenderer* m_pAudioDecoder;
323 CApplication::CApplication(void) : m_itemCurrentFile(new CFileItem), m_progressTrackingItem(new CFileItem)
324 {
325   m_iPlaySpeed = 1;
326 #ifdef HAS_WEB_SERVER
327   m_pWebServer = NULL;
328   m_pXbmcHttp = NULL;
329   m_prevMedia="";
330 #endif
331   m_pFileZilla = NULL;
332   m_pPlayer = NULL;
333   m_bScreenSave = false;
334   m_dpms = NULL;
335   m_dpmsIsActive = false;
336   m_iScreenSaveLock = 0;
337   m_dwSkinTime = 0;
338   m_bInitializing = true;
339   m_eForcedNextPlayer = EPC_NONE;
340   m_strPlayListFile = "";
341   m_nextPlaylistItem = -1;
342   m_bPlaybackStarting = false;
343
344 #ifdef HAS_GLX
345   XInitThreads();
346 #endif
347
348   //true while we in IsPaused mode! Workaround for OnPaused, which must be add. after v2.0
349   m_bIsPaused = false;
350
351   m_bWasFullScreenBeforeMinimize = false;
352
353   /* for now always keep this around */
354 #ifdef HAS_KARAOKE
355   m_pKaraokeMgr = new CKaraokeLyricsManager();
356 #endif
357   m_currentStack = new CFileItemList;
358
359 #ifdef HAS_SDL
360   m_frameCount = 0;
361   m_frameMutex = SDL_CreateMutex();
362   m_frameCond = SDL_CreateCond();
363 #endif
364
365   m_bPresentFrame = false;
366   m_bPlatformDirectories = true;
367
368   m_bStandalone = false;
369   m_bEnableLegacyRes = false;
370   m_bRunResumeJobs = false;
371 #ifdef _WIN32
372   m_SSysParam = new CWIN32Util::SystemParams::SysParam;
373 #endif
374 }
375
376 CApplication::~CApplication(void)
377 {
378   delete m_currentStack;
379
380 #ifdef HAS_KARAOKE
381   delete m_pKaraokeMgr;
382 #endif
383
384 #ifdef HAS_SDL
385   if (m_frameMutex)
386     SDL_DestroyMutex(m_frameMutex);
387
388   if (m_frameCond)
389     SDL_DestroyCond(m_frameCond);
390 #endif
391   delete m_dpms;
392
393 #ifdef _WIN32
394   delete m_SSysParam;
395 #endif
396 }
397
398 bool CApplication::OnEvent(XBMC_Event& newEvent)
399 {
400   switch(newEvent.type)
401   {
402     case XBMC_QUIT:
403       if (!g_application.m_bStop)
404         g_application.getApplicationMessenger().Quit();
405       break;
406     case XBMC_KEYDOWN:
407     case XBMC_KEYUP:
408       g_Keyboard.HandleEvent(newEvent);
409       g_application.ProcessKeyboard();
410       break;
411     case XBMC_MOUSEBUTTONDOWN:
412     case XBMC_MOUSEBUTTONUP:
413     case XBMC_MOUSEMOTION:
414       g_Mouse.HandleEvent(newEvent);
415       g_application.ProcessMouse();
416       break;
417     case XBMC_VIDEORESIZE:
418       if (!g_application.m_bInitializing &&
419           !g_advancedSettings.m_fullScreen)
420       {
421         RESOLUTION res = RES_WINDOW;
422         g_settings.m_ResInfo[res].iWidth = newEvent.resize.w;
423         g_settings.m_ResInfo[res].iHeight = newEvent.resize.h;
424         g_graphicsContext.ResetOverscan(g_settings.m_ResInfo[res]); 
425         g_graphicsContext.SetVideoResolution(res, true);
426       }
427       break;
428   }
429   return true;
430 }
431
432 // This function does not return!
433 void CApplication::FatalErrorHandler(bool WindowSystemInitialized, bool MapDrives, bool InitNetwork)
434 {
435   // XBMC couldn't start for some reason...
436   // g_LoadErrorStr should contain the reason
437   fprintf(stderr, "Fatal error encountered, aborting\n");
438   fprintf(stderr, "Error log at %sxbmc.log\n", g_stSettings.m_logFolder.c_str());
439   abort();
440 }
441
442 extern "C" void __stdcall init_emu_environ();
443 extern "C" void __stdcall update_emu_environ();
444
445 //
446 // Utility function used to copy files from the application bundle
447 // over to the user data directory in Application Support/XBMC.
448 //
449 static void CopyUserDataIfNeeded(const CStdString &strPath, const CStdString &file)
450 {
451   CStdString destPath = CUtil::AddFileToFolder(strPath, file);
452   if (!CFile::Exists(destPath))
453   {
454     // need to copy it across
455     CStdString srcPath = CUtil::AddFileToFolder("special://xbmc/userdata/", file);
456     CFile::Cache(srcPath, destPath);
457   }
458 }
459
460 void CApplication::Preflight()
461 {
462   // run any platform preflight scripts.
463 #ifdef __APPLE__
464   CStdString install_path;
465
466   CUtil::GetHomePath(install_path);
467   setenv("XBMC_HOME", install_path.c_str(), 0);
468   install_path += "/tools/osx/preflight";
469   system(install_path.c_str());
470 #endif
471 }
472
473 HRESULT CApplication::Create(HWND hWnd)
474 {
475   g_guiSettings.Initialize();  // Initialize default Settings
476   g_settings.Initialize(); //Initialize default AdvancedSettings
477
478 #ifdef _WIN32
479   CWIN32Util::SystemParams::GetDefaults( m_SSysParam );
480   CWIN32Util::SystemParams::SetCustomParams();
481 #endif
482
483 #ifdef _LINUX
484   tzset();   // Initialize timezone information variables
485 #endif
486
487   // Grab a handle to our thread to be used later in identifying the render thread.
488   m_threadID = CThread::GetCurrentThreadId();
489
490 #ifndef _LINUX
491   //floating point precision to 24 bits (faster performance)
492   _controlfp(_PC_24, _MCW_PC);
493
494   /* install win32 exception translator, win32 exceptions
495    * can now be caught using c++ try catch */
496   win32_exception::install_handler();
497 #endif
498
499   CProfile *profile;
500
501   // only the InitDirectories* for the current platform should return
502   // non-null (if at all i.e. to set a profile)
503   // putting this before the first log entries saves another ifdef for g_stSettings.m_logFolder
504   profile = InitDirectoriesLinux();
505   if (!profile)
506     profile = InitDirectoriesOSX();
507   if (!profile)
508     profile = InitDirectoriesWin32();
509   if (profile)
510   {
511     profile->setName("Master user");
512     profile->setLockMode(LOCK_MODE_EVERYONE);
513     profile->setLockCode("");
514     profile->setDate("");
515     g_settings.m_vecProfiles.push_back(*profile);
516     delete profile;
517   }
518
519   CLog::Log(LOGNOTICE, "-----------------------------------------------------------------------");
520 #if defined(__APPLE__)
521   CLog::Log(LOGNOTICE, "Starting XBMC, Platform: Mac OS X.  Built on %s (SVN:%s)", __DATE__, SVN_REV);
522 #elif defined(_LINUX)
523   CLog::Log(LOGNOTICE, "Starting XBMC, Platform: GNU/Linux.  Built on %s (SVN:%s)", __DATE__, SVN_REV);
524 #elif defined(_WIN32)
525   CLog::Log(LOGNOTICE, "Starting XBMC, Platform: %s.  Built on %s (SVN:%s, compiler %i)",g_sysinfo.GetKernelVersion().c_str(), __DATE__, SVN_REV, _MSC_VER);
526   CLog::Log(LOGNOTICE, g_cpuInfo.getCPUModel().c_str());
527   CLog::Log(LOGNOTICE, CWIN32Util::GetResInfoString());
528   CLog::Log(LOGNOTICE, "Running with %s rights", (CWIN32Util::IsCurrentUserLocalAdministrator() == TRUE) ? "administrator" : "restricted");
529 #endif
530   CSpecialProtocol::LogPaths();
531
532   char szXBEFileName[1024];
533   CIoSupport::GetXbePath(szXBEFileName);
534   CLog::Log(LOGNOTICE, "The executable running is: %s", szXBEFileName);
535   CLog::Log(LOGNOTICE, "Log File is located: %sxbmc.log", g_stSettings.m_logFolder.c_str());
536   CLog::Log(LOGNOTICE, "-----------------------------------------------------------------------");
537
538   CStdString strExecutablePath;
539   CUtil::GetHomePath(strExecutablePath);
540
541   // if we are running from DVD our UserData location will be TDATA
542   if (CUtil::IsDVD(strExecutablePath))
543   {
544     // TODO: Should we copy over any UserData folder from the DVD?
545     if (!CFile::Exists("special://masterprofile/guisettings.xml")) // first run - cache userdata folder
546     {
547       CFileItemList items;
548       CUtil::GetRecursiveListing("special://xbmc/userdata",items,"");
549       for (int i=0;i<items.Size();++i)
550           CFile::Cache(items[i]->m_strPath,"special://masterprofile/"+CUtil::GetFileName(items[i]->m_strPath));
551     }
552     g_settings.m_vecProfiles[0].setDirectory("special://masterprofile/");
553     g_stSettings.m_logFolder = "special://masterprofile/";
554   }
555
556 #ifdef HAS_XRANDR
557   g_xrandr.LoadCustomModeLinesToAllOutputs();
558 #endif
559
560   // Init our DllLoaders emu env
561   init_emu_environ();
562
563
564 #ifdef HAS_SDL
565   CLog::Log(LOGNOTICE, "Setup SDL");
566
567   /* Clean up on exit, exit on window close and interrupt */
568   atexit(SDL_Quit);
569
570   Uint32 sdlFlags = 0;
571   
572 #ifdef HAS_SDL_OPENGL
573   sdlFlags |= SDL_INIT_VIDEO;
574 #endif
575
576 #ifdef HAS_SDL_AUDIO
577   sdlFlags |= SDL_INIT_AUDIO;
578 #endif
579
580 #ifdef HAS_SDL_JOYSTICK
581   sdlFlags |= SDL_INIT_JOYSTICK;
582 #endif
583
584 #endif // HAS_SDL
585
586 #ifdef _LINUX
587   // for nvidia cards - vsync currently ALWAYS enabled.
588   // the reason is that after screen has been setup changing this env var will make no difference.
589   setenv("__GL_SYNC_TO_VBLANK", "1", 0);
590   setenv("__GL_YIELD", "USLEEP", 0);
591 #endif
592
593 #ifdef HAS_SDL
594   if (SDL_Init(sdlFlags) != 0)
595   {
596     CLog::Log(LOGFATAL, "XBAppEx: Unable to initialize SDL: %s", SDL_GetError());
597     return E_FAIL;
598   }
599 #endif
600
601   // for python scripts that check the OS
602 #ifdef __APPLE__
603   setenv("OS","OS X",true);
604 #elif defined(_LINUX)
605   setenv("OS","Linux",true);
606 #endif
607
608   // Initialize core peripheral port support. Note: If these parameters
609   // are 0 and NULL, respectively, then the default number and types of
610   // controllers will be initialized.
611   if (!g_Windowing.InitWindowSystem())
612   {
613     CLog::Log(LOGFATAL, "CApplication::Create: Unable to init windowing system");
614     return E_FAIL;
615   }
616
617   // Create the Mouse and Keyboard devices
618   g_Mouse.Initialize(&hWnd);
619   g_Keyboard.Initialize();
620 #ifdef HAS_LIRC
621   g_RemoteControl.Initialize();
622 #endif
623 #ifdef HAS_SDL_JOYSTICK
624   g_Joystick.Initialize(hWnd);
625 #endif
626
627   CLog::Log(LOGINFO, "Drives are mapped");
628
629   CLog::Log(LOGNOTICE, "load settings...");
630   g_LoadErrorStr = "Unable to load settings";
631   g_settings.m_iLastUsedProfileIndex = g_settings.m_iLastLoadedProfileIndex;
632   if (g_settings.bUseLoginScreen && g_settings.m_iLastLoadedProfileIndex != 0)
633     g_settings.m_iLastLoadedProfileIndex = 0;
634
635   m_bAllSettingsLoaded = g_settings.Load(m_bXboxMediacenterLoaded, m_bSettingsLoaded);
636   if (!m_bAllSettingsLoaded)
637     FatalErrorHandler(true, true, true);
638
639   update_emu_environ();//apply the GUI settings
640
641 #ifdef __APPLE__
642   // Configure and possible manually start the helper.
643   g_xbmcHelper.Configure();
644 #endif
645
646   if (!g_graphicsContext.IsValidResolution(g_guiSettings.m_LookAndFeelResolution))
647   {
648     // Oh uh - doesn't look good for starting in their wanted screenmode
649     CLog::Log(LOGERROR, "The screen resolution requested is not valid, resetting to a valid mode");
650     g_guiSettings.m_LookAndFeelResolution = RES_DESKTOP;
651   }
652   
653   bool bFullScreen = g_guiSettings.m_LookAndFeelResolution == RES_DESKTOP;
654   if (!g_Windowing.CreateNewWindow("XBMC", bFullScreen, g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution], OnEvent))
655   {
656     CLog::Log(LOGFATAL, "CApplication::Create: Unable to create window");
657     return E_FAIL;
658   }
659   
660   if (!g_Windowing.InitRenderSystem())
661   {    
662     CLog::Log(LOGFATAL, "CApplication::Create: Unable to init rendering system");
663     return E_FAIL;
664   }
665
666   // set GUI res and force the clear of the screen
667   g_graphicsContext.SetVideoResolution(g_guiSettings.m_LookAndFeelResolution);
668
669   // initialize our charset converter
670   g_charsetConverter.reset();
671
672   // Load the langinfo to have user charset <-> utf-8 conversion
673   CStdString strLanguage = g_guiSettings.GetString("locale.language");
674   strLanguage[0] = toupper(strLanguage[0]);
675
676   CStdString strLangInfoPath;
677   strLangInfoPath.Format("special://xbmc/language/%s/langinfo.xml", strLanguage.c_str());
678
679   CLog::Log(LOGINFO, "load language info file: %s", strLangInfoPath.c_str());
680   g_langInfo.Load(strLangInfoPath);
681
682   m_splash = new CSplash("special://xbmc/media/Splash.png");
683   m_splash->Show();
684
685   CStdString strLanguagePath;
686   strLanguagePath.Format("special://xbmc/language/%s/strings.xml", strLanguage.c_str());
687
688   CLog::Log(LOGINFO, "load language file:%s", strLanguagePath.c_str());
689   if (!g_localizeStrings.Load(strLanguagePath))
690     FatalErrorHandler(false, false, true);
691
692   CLog::Log(LOGINFO, "load keymapping");
693   if (!CButtonTranslator::GetInstance().Load())
694     FatalErrorHandler(false, false, true);
695
696   // check the skin file for testing purposes
697   CStdString strSkinBase = "special://home/skin/";
698   CStdString strSkinPath = strSkinBase + g_guiSettings.GetString("lookandfeel.skin");
699   if (!CFile::Exists(strSkinPath)) {
700     strSkinBase = "special://xbmc/skin/";
701     strSkinPath = strSkinBase + g_guiSettings.GetString("lookandfeel.skin");
702   }
703   CLog::Log(LOGINFO, "Checking skin version of: %s", g_guiSettings.GetString("lookandfeel.skin").c_str());
704   if (!g_SkinInfo.Check(strSkinPath))
705   {
706     // reset to the default skin (DEFAULT_SKIN)
707     CLog::Log(LOGINFO, "The above skin isn't suitable - checking the version of the default: %s", DEFAULT_SKIN);
708     strSkinPath = strSkinBase + DEFAULT_SKIN;
709     if (!g_SkinInfo.Check(strSkinPath))
710     {
711       g_LoadErrorStr.Format("No suitable skin version found.\nWe require at least version %5.4f \n", g_SkinInfo.GetMinVersion());
712       FatalErrorHandler(false, false, true);
713     }
714   }
715   int iResolution = g_graphicsContext.GetVideoResolution();
716   CLog::Log(LOGINFO, "GUI format %ix%i %s",
717             g_settings.m_ResInfo[iResolution].iWidth,
718             g_settings.m_ResInfo[iResolution].iHeight,
719             g_settings.m_ResInfo[iResolution].strMode.c_str());
720   m_gWindowManager.Initialize();
721
722   g_Mouse.SetEnabled(g_guiSettings.GetBool("lookandfeel.enablemouse"));
723
724   CUtil::InitRandomSeed();
725
726 #ifdef _WIN32
727   CWIN32Util::AddRemovableDrives();
728 #endif
729
730   return Initialize();
731 }
732
733 CProfile* CApplication::InitDirectoriesLinux()
734 {
735 /*
736    The following is the directory mapping for Platform Specific Mode:
737
738    special://xbmc/          => [read-only] system directory (/usr/share/xbmc)
739    special://home/          => [read-write] user's directory that will override special://xbmc/ system-wide
740                                installations like skins, screensavers, etc.
741                                ($HOME/.xbmc)
742                                NOTE: XBMC will look in both special://xbmc/skin and special://xbmc/skin for skins.
743                                      Same applies to screensavers, sounds, etc.
744    special://masterprofile/ => [read-write] userdata of master profile. It will by default be
745                                mapped to special://home/userdata ($HOME/.xbmc/userdata)
746    special://profile/       => [read-write] current profile's userdata directory.
747                                Generally special://masterprofile for the master profile or
748                                special://masterprofile/profiles/<profile_name> for other profiles.
749
750    NOTE: All these root directories are lowercase. Some of the sub-directories
751          might be mixed case.
752 */
753
754 #if defined(_LINUX) && !defined(__APPLE__)
755   CProfile* profile = NULL;
756
757   CStdString userName;
758   if (getenv("USER"))
759     userName = getenv("USER");
760   else
761     userName = "root";
762
763   CStdString userHome;
764   if (getenv("HOME"))
765     userHome = getenv("HOME");
766   else
767     userHome = "/root";
768
769   CStdString strHomePath;
770   CUtil::GetHomePath(strHomePath);
771   setenv("XBMC_HOME", strHomePath.c_str(), 0);
772
773   if (m_bPlatformDirectories)
774   {
775     // map our special drives
776     CSpecialProtocol::SetXBMCPath(strHomePath);
777     CSpecialProtocol::SetHomePath(userHome + "/.xbmc");
778     CSpecialProtocol::SetMasterProfilePath(userHome + "/.xbmc/userdata");
779
780     CStdString strTempPath = CUtil::AddFileToFolder(userHome, ".xbmc/temp");
781     CSpecialProtocol::SetTempPath(strTempPath);
782
783     CUtil::AddSlashAtEnd(strTempPath);
784     g_stSettings.m_logFolder = strTempPath;
785
786     bool bCopySystemPlugins = false;
787     if (!CDirectory::Exists("special://home/plugins") )
788        bCopySystemPlugins = true;
789
790     CDirectory::Create("special://home/");
791     CDirectory::Create("special://temp/");
792     CDirectory::Create("special://home/skin");
793     CDirectory::Create("special://home/keymaps");
794     CDirectory::Create("special://home/visualisations");
795     CDirectory::Create("special://home/screensavers");
796     CDirectory::Create("special://home/sounds");
797     CDirectory::Create("special://home/system");
798     CDirectory::Create("special://home/plugins");
799     CDirectory::Create("special://home/plugins/video");
800     CDirectory::Create("special://home/plugins/music");
801     CDirectory::Create("special://home/plugins/pictures");
802     CDirectory::Create("special://home/plugins/programs");
803     CDirectory::Create("special://home/plugins/weather");
804     CDirectory::Create("special://home/scripts");
805     CDirectory::Create("special://home/scripts/My Scripts");    // FIXME: both scripts should be in 1 directory
806
807     if (!CFile::Exists("special://home/scripts/Common Scripts"))
808     {
809       if (symlink( INSTALL_PATH "/scripts",  _P("special://home/scripts/Common Scripts").c_str() ) != 0)
810         CLog::Log(LOGERROR, "Failed to create common scripts symlink.");
811     }
812
813     CDirectory::Create("special://masterprofile");
814
815     // copy required files
816     //CopyUserDataIfNeeded("special://masterprofile/", "Keymap.xml");  // Eventual FIXME.
817     CopyUserDataIfNeeded("special://masterprofile/", "RssFeeds.xml");
818     CopyUserDataIfNeeded("special://masterprofile/", "Lircmap.xml");
819     CopyUserDataIfNeeded("special://masterprofile/", "LCD.xml");
820     
821     // copy system-wide plugins into userprofile
822     if ( bCopySystemPlugins )
823        CUtil::CopyDirRecursive("special://xbmc/plugins", "special://home/plugins");
824   }
825   else
826   {
827     CUtil::AddSlashAtEnd(strHomePath);
828     g_stSettings.m_logFolder = strHomePath;
829
830     CSpecialProtocol::SetXBMCPath(strHomePath);
831     CSpecialProtocol::SetHomePath(strHomePath);
832     CSpecialProtocol::SetMasterProfilePath(CUtil::AddFileToFolder(strHomePath, "userdata"));
833
834     CStdString strTempPath = CUtil::AddFileToFolder(strHomePath, "temp");
835     CSpecialProtocol::SetTempPath(strTempPath);
836     CDirectory::Create("special://temp/");
837
838     CUtil::AddSlashAtEnd(strTempPath);
839     g_stSettings.m_logFolder = strTempPath;
840   }
841
842   g_settings.m_vecProfiles.clear();
843   g_settings.LoadProfiles( PROFILES_FILE );
844
845   if (g_settings.m_vecProfiles.size()==0)
846   {
847     profile = new CProfile;
848     profile->setDirectory("special://masterprofile/");
849   }
850   return profile;
851 #else
852   return NULL;
853 #endif
854 }
855
856 CProfile* CApplication::InitDirectoriesOSX()
857 {
858 #ifdef __APPLE__
859   CProfile* profile = NULL;
860
861   CStdString userName;
862   if (getenv("USER"))
863     userName = getenv("USER");
864   else
865     userName = "root";
866
867   CStdString userHome;
868   if (getenv("HOME"))
869     userHome = getenv("HOME");
870   else
871     userHome = "/root";
872
873   CStdString strHomePath;
874   CUtil::GetHomePath(strHomePath);
875   setenv("XBMC_HOME", strHomePath.c_str(), 0);
876
877   // OSX always runs with m_bPlatformDirectories == true
878   if (m_bPlatformDirectories)
879   {
880     // map our special drives
881     CSpecialProtocol::SetXBMCPath(strHomePath);
882     CSpecialProtocol::SetHomePath(userHome + "/Library/Application Support/XBMC");
883     CSpecialProtocol::SetMasterProfilePath(userHome + "/Library/Application Support/XBMC/userdata");
884
885 #ifdef __APPLE__
886     CStdString strTempPath = CUtil::AddFileToFolder(userHome, ".xbmc/");
887     CDirectory::Create(strTempPath);
888 #endif
889
890     strTempPath = CUtil::AddFileToFolder(userHome, ".xbmc/temp");
891     CSpecialProtocol::SetTempPath(strTempPath);
892
893 #ifdef __APPLE__
894     strTempPath = userHome + "/Library/Logs";
895 #endif
896     CUtil::AddSlashAtEnd(strTempPath);
897     g_stSettings.m_logFolder = strTempPath;
898
899     bool bCopySystemPlugins = false;
900     if (!CDirectory::Exists("special://home/plugins") )
901        bCopySystemPlugins = true;
902
903     CDirectory::Create("special://home/");
904     CDirectory::Create("special://temp/");
905     CDirectory::Create("special://home/skin");
906     CDirectory::Create("special://home/keymaps");
907     CDirectory::Create("special://home/visualisations");
908     CDirectory::Create("special://home/screensavers");
909     CDirectory::Create("special://home/sounds");
910     CDirectory::Create("special://home/system");
911     CDirectory::Create("special://home/plugins");
912     CDirectory::Create("special://home/plugins/video");
913     CDirectory::Create("special://home/plugins/music");
914     CDirectory::Create("special://home/plugins/pictures");
915     CDirectory::Create("special://home/plugins/programs");
916     CDirectory::Create("special://home/plugins/weather");
917     CDirectory::Create("special://home/scripts");
918     CDirectory::Create("special://home/scripts/My Scripts"); // FIXME: both scripts should be in 1 directory
919 #ifdef __APPLE__
920     strTempPath = strHomePath + "/scripts";
921 #else
922     strTempPath = INSTALL_PATH "/scripts";
923 #endif
924     symlink( strTempPath.c_str(),  _P("special://home/scripts/Common Scripts").c_str() );
925
926     CDirectory::Create("special://masterprofile/");
927
928     // copy required files
929     //CopyUserDataIfNeeded("special://masterprofile/", "Keymap.xml"); // Eventual FIXME.
930     CopyUserDataIfNeeded("special://masterprofile/", "RssFeeds.xml");
931     CopyUserDataIfNeeded("special://masterprofile/", "Lircmap.xml");
932     CopyUserDataIfNeeded("special://masterprofile/", "LCD.xml");
933
934     // copy system-wide plugins into userprofile
935     if ( bCopySystemPlugins )
936        CUtil::CopyDirRecursive("special://xbmc/plugins", "special://home/plugins");
937   }
938   else
939   {
940     CUtil::AddSlashAtEnd(strHomePath);
941     g_stSettings.m_logFolder = strHomePath;
942
943     CSpecialProtocol::SetXBMCPath(strHomePath);
944     CSpecialProtocol::SetHomePath(strHomePath);
945     CSpecialProtocol::SetMasterProfilePath(CUtil::AddFileToFolder(strHomePath, "userdata"));
946
947     CStdString strTempPath = CUtil::AddFileToFolder(strHomePath, "temp");
948     CSpecialProtocol::SetTempPath(strTempPath);
949     CDirectory::Create("special://temp/");
950
951     CUtil::AddSlashAtEnd(strTempPath);
952     g_stSettings.m_logFolder = strTempPath;
953   }
954
955   g_settings.m_vecProfiles.clear();
956   g_settings.LoadProfiles( PROFILES_FILE );
957
958   if (g_settings.m_vecProfiles.size()==0)
959   {
960     profile = new CProfile;
961     profile->setDirectory("special://masterprofile/");
962   }
963   return profile;
964 #else
965   return NULL;
966 #endif
967 }
968
969 CProfile* CApplication::InitDirectoriesWin32()
970 {
971 #ifdef _WIN32
972   CProfile* profile = NULL;
973   CStdString strExecutablePath;
974
975   CUtil::GetHomePath(strExecutablePath);
976   SetEnvironmentVariable("XBMC_HOME", strExecutablePath.c_str());
977   CSpecialProtocol::SetXBMCPath(strExecutablePath);
978
979   if (m_bPlatformDirectories)
980   {
981
982     CStdString strWin32UserFolder = CWIN32Util::GetProfilePath();
983
984     // create user/app data/XBMC
985     CStdString homePath = CUtil::AddFileToFolder(strWin32UserFolder, "XBMC");
986
987     // move log to platform dirs
988     g_stSettings.m_logFolder = homePath;
989     CUtil::AddSlashAtEnd(g_stSettings.m_logFolder);
990
991     // map our special drives
992     CSpecialProtocol::SetXBMCPath(strExecutablePath);
993     CSpecialProtocol::SetHomePath(homePath);
994     CSpecialProtocol::SetMasterProfilePath(CUtil::AddFileToFolder(homePath, "userdata"));
995     SetEnvironmentVariable("XBMC_PROFILE_USERDATA",_P("special://masterprofile").c_str());
996
997     bool bCopySystemPlugins = false;
998     if (!CDirectory::Exists("special://home/plugins") )
999        bCopySystemPlugins = true;
1000
1001     CDirectory::Create("special://home/");
1002     CDirectory::Create("special://home/skin");
1003     CDirectory::Create("special://home/keymaps");
1004     CDirectory::Create("special://home/visualisations");
1005     CDirectory::Create("special://home/screensavers");
1006     CDirectory::Create("special://home/sounds");
1007     CDirectory::Create("special://home/system");
1008     CDirectory::Create("special://home/plugins");
1009     CDirectory::Create("special://home/plugins/video");
1010     CDirectory::Create("special://home/plugins/music");
1011     CDirectory::Create("special://home/plugins/pictures");
1012     CDirectory::Create("special://home/plugins/programs");
1013     CDirectory::Create("special://home/plugins/weather");
1014     CDirectory::Create("special://home/scripts");
1015
1016     CDirectory::Create("special://masterprofile");
1017
1018     // copy required files
1019     //CopyUserDataIfNeeded("special://masterprofile/", "Keymap.xml");  // Eventual FIXME.
1020     CopyUserDataIfNeeded("special://masterprofile/", "RssFeeds.xml");
1021     CopyUserDataIfNeeded("special://masterprofile/", "favourites.xml");
1022     CopyUserDataIfNeeded("special://masterprofile/", "Lircmap.xml");
1023     CopyUserDataIfNeeded("special://masterprofile/", "LCD.xml");
1024
1025     // copy system-wide plugins into userprofile
1026     if ( bCopySystemPlugins )
1027        CUtil::CopyDirRecursive("special://xbmc/plugins", "special://home/plugins");
1028
1029     // create user/app data/XBMC/cache
1030     CSpecialProtocol::SetTempPath(CUtil::AddFileToFolder(homePath,"cache"));
1031     CDirectory::Create("special://temp");
1032   }
1033   else
1034   {
1035     g_stSettings.m_logFolder = strExecutablePath;
1036     CUtil::AddSlashAtEnd(g_stSettings.m_logFolder);
1037     CStdString strTempPath = CUtil::AddFileToFolder(strExecutablePath, "cache");
1038     CSpecialProtocol::SetTempPath(strTempPath);
1039     CDirectory::Create("special://temp/");
1040
1041     CSpecialProtocol::SetHomePath(strExecutablePath);
1042     CSpecialProtocol::SetMasterProfilePath(CUtil::AddFileToFolder(strExecutablePath,"userdata"));
1043     SetEnvironmentVariable("XBMC_PROFILE_USERDATA",_P("special://masterprofile/").c_str());
1044   }
1045
1046   g_settings.m_vecProfiles.clear();
1047   g_settings.LoadProfiles(PROFILES_FILE);
1048
1049   if (g_settings.m_vecProfiles.size()==0)
1050   {
1051     profile = new CProfile;
1052     profile->setDirectory("special://masterprofile/");
1053   }
1054
1055   // Expand the DLL search path with our directories
1056   CWIN32Util::ExtendDllPath();
1057
1058   return profile;
1059 #else
1060   return NULL;
1061 #endif
1062 }
1063
1064 HRESULT CApplication::Initialize()
1065 {
1066 #ifdef HAS_DVD_DRIVE
1067   // turn off cdio logging
1068   cdio_loglevel_default = CDIO_LOG_ERROR;
1069 #endif
1070
1071   CLog::Log(LOGINFO, "creating subdirectories");
1072
1073   CLog::Log(LOGINFO, "userdata folder: %s", g_settings.GetProfileUserDataFolder().c_str());
1074   CLog::Log(LOGINFO, "recording folder:%s", g_guiSettings.GetString("mymusic.recordingpath",false).c_str());
1075   CLog::Log(LOGINFO, "screenshots folder:%s", g_guiSettings.GetString("pictures.screenshotpath",false).c_str());
1076
1077   // UserData folder layout:
1078   // UserData/
1079   //   Database/
1080   //     CDDb/
1081   //   Thumbnails/
1082   //     Music/
1083   //       temp/
1084   //     0 .. F/
1085
1086   CDirectory::Create(g_settings.GetUserDataFolder());
1087   CDirectory::Create(g_settings.GetProfileUserDataFolder());
1088   g_settings.CreateProfileFolders();
1089
1090   CDirectory::Create(g_settings.GetProfilesThumbFolder());
1091
1092   CDirectory::Create("special://temp/temp"); // temp directory for python and dllGetTempPathA
1093
1094 #ifdef _LINUX // TODO: Win32 has no special://home/ mapping by default, so we
1095               //       must create these here. Ideally this should be using special://home/ and
1096               //       be platform agnostic (i.e. unify the InitDirectories*() functions)
1097   if (!m_bPlatformDirectories)
1098 #endif
1099   {
1100     CDirectory::Create("special://xbmc/scripts");
1101     CDirectory::Create("special://xbmc/plugins");
1102     CDirectory::Create("special://xbmc/plugins/music");
1103     CDirectory::Create("special://xbmc/plugins/video");
1104     CDirectory::Create("special://xbmc/plugins/pictures");
1105     CDirectory::Create("special://xbmc/plugins/programs");
1106     CDirectory::Create("special://xbmc/plugins/weather");
1107     CDirectory::Create("special://xbmc/language");
1108     CDirectory::Create("special://xbmc/visualisations");
1109     CDirectory::Create("special://xbmc/sounds");
1110     CDirectory::Create(CUtil::AddFileToFolder(g_settings.GetUserDataFolder(),"visualisations"));
1111   }
1112
1113   // initialize network
1114   if (!m_bXboxMediacenterLoaded)
1115   {
1116     CLog::Log(LOGINFO, "using default network settings");
1117     g_guiSettings.SetString("network.ipaddress", "192.168.0.100");
1118     g_guiSettings.SetString("network.subnet", "255.255.255.0");
1119     g_guiSettings.SetString("network.gateway", "192.168.0.1");
1120     g_guiSettings.SetString("network.dns", "192.168.0.1");
1121     g_guiSettings.SetBool("servers.ftpserver", true);
1122     g_guiSettings.SetBool("servers.webserver", false);
1123     g_guiSettings.SetBool("locale.timeserver", false);
1124   }
1125
1126   StartServices();
1127
1128   // Init DPMS, before creating the corresponding setting control.
1129   m_dpms = new DPMSSupport();
1130   g_guiSettings.GetSetting("screensaver.sep_powersaving")->SetVisible(
1131       m_dpms->IsSupported());
1132   g_guiSettings.GetSetting("screensaver.powersavingtime")->SetVisible(
1133       m_dpms->IsSupported());
1134
1135   m_gWindowManager.Add(new CGUIWindowHome);                     // window id = 0
1136
1137   CLog::Log(LOGNOTICE, "load default skin:[%s]", g_guiSettings.GetString("lookandfeel.skin").c_str());
1138   LoadSkin(g_guiSettings.GetString("lookandfeel.skin"));
1139
1140   m_gWindowManager.Add(new CGUIWindowPrograms);                 // window id = 1
1141   m_gWindowManager.Add(new CGUIWindowPictures);                 // window id = 2
1142   m_gWindowManager.Add(new CGUIWindowFileManager);      // window id = 3
1143   m_gWindowManager.Add(new CGUIWindowVideoFiles);          // window id = 6
1144   m_gWindowManager.Add(new CGUIWindowSettings);                 // window id = 4
1145   m_gWindowManager.Add(new CGUIWindowSystemInfo);               // window id = 7
1146 #ifdef HAS_GL  
1147   m_gWindowManager.Add(new CGUIWindowTestPatternGL);      // window id = 8
1148 #endif
1149 #ifdef HAS_DX
1150   m_gWindowManager.Add(new CGUIWindowTestPatternDX);      // window id = 8
1151 #endif
1152   m_gWindowManager.Add(new CGUIWindowSettingsScreenCalibration); // window id = 11
1153   m_gWindowManager.Add(new CGUIWindowSettingsCategory);         // window id = 12 slideshow:window id 2007
1154   m_gWindowManager.Add(new CGUIWindowScripts);                  // window id = 20
1155   m_gWindowManager.Add(new CGUIWindowVideoNav);                 // window id = 36
1156   m_gWindowManager.Add(new CGUIWindowVideoPlaylist);            // window id = 28
1157   m_gWindowManager.Add(new CGUIWindowLoginScreen);            // window id = 29
1158   m_gWindowManager.Add(new CGUIWindowSettingsProfile);          // window id = 34
1159   m_gWindowManager.Add(new CGUIDialogYesNo);              // window id = 100
1160   m_gWindowManager.Add(new CGUIDialogProgress);           // window id = 101
1161   m_gWindowManager.Add(new CGUIDialogKeyboard);           // window id = 103
1162   m_gWindowManager.Add(&m_guiDialogVolumeBar);          // window id = 104
1163   m_gWindowManager.Add(&m_guiDialogSeekBar);            // window id = 115
1164   m_gWindowManager.Add(new CGUIDialogSubMenu);            // window id = 105
1165   m_gWindowManager.Add(new CGUIDialogContextMenu);        // window id = 106
1166   m_gWindowManager.Add(&m_guiDialogKaiToast);           // window id = 107
1167   m_gWindowManager.Add(new CGUIDialogNumeric);            // window id = 109
1168   m_gWindowManager.Add(new CGUIDialogGamepad);            // window id = 110
1169   m_gWindowManager.Add(new CGUIDialogButtonMenu);         // window id = 111
1170   m_gWindowManager.Add(new CGUIDialogMusicScan);          // window id = 112
1171   m_gWindowManager.Add(new CGUIDialogPlayerControls);     // window id = 113
1172 #ifdef HAS_KARAOKE
1173   m_gWindowManager.Add(new CGUIDialogKaraokeSongSelectorSmall); // window id 143
1174   m_gWindowManager.Add(new CGUIDialogKaraokeSongSelectorLarge); // window id 144
1175 #endif
1176   m_gWindowManager.Add(new CGUIDialogSlider);             // window id = 145
1177   m_gWindowManager.Add(new CGUIDialogMusicOSD);           // window id = 120
1178   m_gWindowManager.Add(new CGUIDialogVisualisationSettings);     // window id = 121
1179   m_gWindowManager.Add(new CGUIDialogVisualisationPresetList);   // window id = 122
1180   m_gWindowManager.Add(new CGUIDialogVideoSettings);             // window id = 123
1181   m_gWindowManager.Add(new CGUIDialogAudioSubtitleSettings);     // window id = 124
1182   m_gWindowManager.Add(new CGUIDialogVideoBookmarks);      // window id = 125
1183   // Don't add the filebrowser dialog - it's created and added when it's needed
1184   m_gWindowManager.Add(new CGUIDialogNetworkSetup);  // window id = 128
1185   m_gWindowManager.Add(new CGUIDialogMediaSource);   // window id = 129
1186   m_gWindowManager.Add(new CGUIDialogProfileSettings); // window id = 130
1187   m_gWindowManager.Add(new CGUIDialogVideoScan);      // window id = 133
1188   m_gWindowManager.Add(new CGUIDialogFavourites);     // window id = 134
1189   m_gWindowManager.Add(new CGUIDialogSongInfo);       // window id = 135
1190   m_gWindowManager.Add(new CGUIDialogSmartPlaylistEditor);       // window id = 136
1191   m_gWindowManager.Add(new CGUIDialogSmartPlaylistRule);       // window id = 137
1192   m_gWindowManager.Add(new CGUIDialogBusy);      // window id = 138
1193   m_gWindowManager.Add(new CGUIDialogPictureInfo);      // window id = 139
1194   m_gWindowManager.Add(new CGUIDialogPluginSettings);      // window id = 140
1195 #ifdef HAS_LINUX_NETWORK
1196   m_gWindowManager.Add(new CGUIDialogAccessPoints);      // window id = 141
1197 #endif
1198
1199   m_gWindowManager.Add(new CGUIDialogLockSettings); // window id = 131
1200
1201   m_gWindowManager.Add(new CGUIDialogContentSettings);        // window id = 132
1202
1203   m_gWindowManager.Add(new CGUIWindowMusicPlayList);          // window id = 500
1204   m_gWindowManager.Add(new CGUIWindowMusicSongs);             // window id = 501
1205   m_gWindowManager.Add(new CGUIWindowMusicNav);               // window id = 502
1206   m_gWindowManager.Add(new CGUIWindowMusicPlaylistEditor);    // window id = 503
1207
1208   m_gWindowManager.Add(new CGUIDialogSelect);             // window id = 2000
1209   m_gWindowManager.Add(new CGUIWindowMusicInfo);                // window id = 2001
1210   m_gWindowManager.Add(new CGUIDialogOK);                 // window id = 2002
1211   m_gWindowManager.Add(new CGUIWindowVideoInfo);                // window id = 2003
1212   m_gWindowManager.Add(new CGUIWindowScriptsInfo);              // window id = 2004
1213   m_gWindowManager.Add(new CGUIWindowFullScreen);         // window id = 2005
1214   m_gWindowManager.Add(new CGUIWindowVisualisation);      // window id = 2006
1215   m_gWindowManager.Add(new CGUIWindowSlideShow);          // window id = 2007
1216   m_gWindowManager.Add(new CGUIDialogFileStacking);       // window id = 2008
1217 #ifdef HAS_KARAOKE
1218   m_gWindowManager.Add(new CGUIWindowKaraokeLyrics);      // window id = 2009
1219 #endif
1220
1221   m_gWindowManager.Add(new CGUIWindowOSD);                // window id = 2901
1222   m_gWindowManager.Add(new CGUIWindowMusicOverlay);       // window id = 2903
1223   m_gWindowManager.Add(new CGUIWindowVideoOverlay);       // window id = 2904
1224   m_gWindowManager.Add(new CGUIWindowScreensaver);        // window id = 2900 Screensaver
1225   m_gWindowManager.Add(new CGUIWindowWeather);            // window id = 2600 WEATHER
1226   m_gWindowManager.Add(new CGUIWindowStartup);            // startup window (id 2999)
1227
1228   /* window id's 3000 - 3100 are reserved for python */
1229
1230   SAFE_DELETE(m_splash);
1231
1232   if (g_guiSettings.GetBool("masterlock.startuplock") &&
1233       g_settings.m_vecProfiles[0].getLockMode() != LOCK_MODE_EVERYONE &&
1234      !g_settings.m_vecProfiles[0].getLockCode().IsEmpty())
1235   {
1236      g_passwordManager.CheckStartUpLock();
1237   }
1238
1239   // check if we should use the login screen
1240   if (g_settings.bUseLoginScreen)
1241   {
1242     m_gWindowManager.ActivateWindow(WINDOW_LOGIN_SCREEN);
1243   }
1244   else
1245   {
1246     RESOLUTION res = RES_INVALID;
1247     CStdString startupPath = g_SkinInfo.GetSkinPath("Startup.xml", &res);
1248     int startWindow = g_guiSettings.GetInt("lookandfeel.startupwindow");
1249     // test for a startup window, and activate that instead of home
1250     if (CFile::Exists(startupPath) && (!g_SkinInfo.OnlyAnimateToHome() || startWindow == WINDOW_HOME))
1251     {
1252       m_gWindowManager.ActivateWindow(WINDOW_STARTUP);
1253     }
1254     else
1255     {
1256       // We need to Popup the WindowHome to initiate the GUIWindowManger for MasterCode popup dialog!
1257       // Then we can start the StartUpWindow! To prevent BlackScreen if the target Window is Protected with MasterCode!
1258       m_gWindowManager.ActivateWindow(WINDOW_HOME);
1259       if (startWindow != WINDOW_HOME)
1260         m_gWindowManager.ActivateWindow(startWindow);
1261     }
1262   }
1263
1264 #ifdef HAS_PYTHON
1265   g_pythonParser.bStartup = true;
1266 #endif
1267   g_sysinfo.Refresh();
1268
1269   CLog::Log(LOGINFO, "removing tempfiles");
1270   CUtil::RemoveTempFiles();
1271
1272   if (!m_bAllSettingsLoaded)
1273   {
1274     CLog::Log(LOGWARNING, "settings not correct, show dialog");
1275     CStdString test;
1276     CUtil::GetHomePath(test);
1277     CGUIDialogOK *dialog = (CGUIDialogOK *)m_gWindowManager.GetWindow(WINDOW_DIALOG_OK);
1278     if (dialog)
1279     {
1280       dialog->SetHeading(279);
1281       dialog->SetLine(0, "Error while loading settings");
1282       dialog->SetLine(1, test);
1283       dialog->SetLine(2, "");;
1284       dialog->DoModal();
1285     }
1286   }
1287
1288   //  Show mute symbol
1289   if (g_stSettings.m_nVolumeLevel == VOLUME_MINIMUM)
1290     Mute();
1291
1292   // if the user shutoff the xbox during music scan
1293   // restore the settings
1294   if (g_stSettings.m_bMyMusicIsScanning)
1295   {
1296     CLog::Log(LOGWARNING,"System rebooted during music scan! ... restoring UseTags and FindRemoteThumbs");
1297     RestoreMusicScanSettings();
1298   }
1299
1300   if (g_guiSettings.GetBool("videolibrary.updateonstartup"))
1301   {
1302     CLog::Log(LOGNOTICE, "Updating video library on startup");
1303     CGUIDialogVideoScan *scanner = (CGUIDialogVideoScan *)m_gWindowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
1304     SScraperInfo info;
1305     VIDEO::SScanSettings settings;
1306     if (scanner && !scanner->IsScanning())
1307       scanner->StartScanning("",info,settings,false);
1308   }
1309
1310 #ifdef HAS_HAL
1311   g_HalManager.Initialize();
1312 #endif
1313
1314   if (g_guiSettings.GetBool("musiclibrary.updateonstartup"))
1315   {
1316     CLog::Log(LOGNOTICE, "Updating music library on startup");
1317     CGUIDialogMusicScan *scanner = (CGUIDialogMusicScan *)m_gWindowManager.GetWindow(WINDOW_DIALOG_MUSIC_SCAN);
1318     if (scanner && !scanner->IsScanning())
1319       scanner->StartScanning("");
1320   }
1321
1322   m_slowTimer.StartZero();
1323
1324 #ifdef __APPLE__
1325   g_xbmcHelper.CaptureAllInput();
1326 #endif
1327
1328   g_powerManager.Initialize();
1329
1330   CLog::Log(LOGNOTICE, "initialize done");
1331
1332   m_bInitializing = false;
1333
1334   // reset our screensaver (starts timers etc.)
1335   ResetScreenSaver();
1336   return S_OK;
1337 }
1338
1339 void CApplication::StartWebServer()
1340 {
1341 #ifdef HAS_WEB_SERVER
1342   if (g_guiSettings.GetBool("servers.webserver") && m_network.IsAvailable())
1343   {
1344     int webPort = atoi(g_guiSettings.GetString("servers.webserverport"));
1345     CLog::Log(LOGNOTICE, "Webserver: Starting...");
1346 #ifdef _LINUX
1347     if (webPort < 1024 && geteuid() != 0)
1348     {
1349         CLog::Log(LOGERROR, "Cannot start Web Server as port is smaller than 1024 and user is not root");
1350         return;
1351     }
1352 #endif
1353     CSectionLoader::Load("LIBHTTP");
1354     if (m_network.GetFirstConnectedInterface())
1355     {
1356        m_pWebServer = new CWebServer();
1357        m_pWebServer->Start(m_network.GetFirstConnectedInterface()->GetCurrentIPAddress().c_str(), webPort, "special://xbmc/web", false);
1358     }
1359     if (m_pWebServer)
1360     {
1361       m_pWebServer->SetUserName(g_guiSettings.GetString("servers.webserverusername").c_str());
1362       m_pWebServer->SetPassword(g_guiSettings.GetString("servers.webserverpassword").c_str());
1363
1364       // publish web frontend and API services
1365       CZeroconf::GetInstance()->PublishService("servers.webserver", "_http._tcp", "XBMC Web Server", webPort);
1366       CZeroconf::GetInstance()->PublishService("servers.webapi", "_xbmc-web._tcp", "XBMC HTTP API", webPort);
1367     }
1368     if (m_pWebServer && m_pXbmcHttp && g_stSettings.m_HttpApiBroadcastLevel>=1)
1369       getApplicationMessenger().HttpApi("broadcastlevel; StartUp;1");
1370   }
1371 #endif
1372 }
1373
1374 void CApplication::StopWebServer()
1375 {
1376 #ifdef HAS_WEB_SERVER
1377   if (m_pWebServer)
1378   {
1379     CLog::Log(LOGNOTICE, "Webserver: Stopping...");
1380     m_pWebServer->Stop();
1381     delete m_pWebServer;
1382     m_pWebServer = NULL;
1383     CSectionLoader::Unload("LIBHTTP");
1384     CLog::Log(LOGNOTICE, "Webserver: Stopped...");
1385     CZeroconf::GetInstance()->RemoveService("servers.webserver");
1386     CZeroconf::GetInstance()->RemoveService("servers.webapi");
1387   }
1388 #endif
1389 }
1390
1391 void CApplication::StartFtpServer()
1392 {
1393 #ifdef HAS_FTP_SERVER
1394   if ( g_guiSettings.GetBool("servers.ftpserver") && m_network.IsAvailable() )
1395   {
1396     CLog::Log(LOGNOTICE, "XBFileZilla: Starting...");
1397     if (!m_pFileZilla)
1398     {
1399       CStdString xmlpath = "special://xbmc/system/";
1400       // if user didn't upgrade properly,
1401       // check whether UserData/FileZilla Server.xml exists
1402       if (CFile::Exists(g_settings.GetUserDataItem("FileZilla Server.xml")))
1403         xmlpath = g_settings.GetUserDataFolder();
1404
1405       // check file size and presence
1406       CFile xml;
1407       if (xml.Open(xmlpath+"FileZilla Server.xml") && xml.GetLength() > 0)
1408       {
1409         m_pFileZilla = new CXBFileZilla(_P(xmlpath));
1410         m_pFileZilla->Start(false);
1411       }
1412       else
1413       {
1414         // 'FileZilla Server.xml' does not exist or is corrupt,
1415         // falling back to ftp emergency recovery mode
1416         CLog::Log(LOGNOTICE, "XBFileZilla: 'FileZilla Server.xml' is missing or is corrupt!");
1417         CLog::Log(LOGNOTICE, "XBFileZilla: Starting ftp emergency recovery mode");
1418         StartFtpEmergencyRecoveryMode();
1419       }
1420       xml.Close();
1421     }
1422   }
1423 #endif
1424 }
1425
1426 void CApplication::StopFtpServer()
1427 {
1428 #ifdef HAS_FTP_SERVER
1429   if (m_pFileZilla)
1430   {
1431     CLog::Log(LOGINFO, "XBFileZilla: Stopping...");
1432
1433     std::vector<SXFConnection> mConnections;
1434     std::vector<SXFConnection>::iterator it;
1435
1436     m_pFileZilla->GetAllConnections(mConnections);
1437
1438     for(it = mConnections.begin();it != mConnections.end();it++)
1439     {
1440       m_pFileZilla->CloseConnection(it->mId);
1441     }
1442
1443     m_pFileZilla->Stop();
1444     delete m_pFileZilla;
1445     m_pFileZilla = NULL;
1446
1447     CLog::Log(LOGINFO, "XBFileZilla: Stopped");
1448   }
1449 #endif
1450 }
1451
1452 void CApplication::StartTimeServer()
1453 {
1454 #ifdef HAS_TIME_SERVER
1455   if (g_guiSettings.GetBool("locale.timeserver") && m_network.IsAvailable() )
1456   {
1457     if( !m_psntpClient )
1458     {
1459       CSectionLoader::Load("SNTP");
1460       CLog::Log(LOGNOTICE, "start timeserver client");
1461
1462       m_psntpClient = new CSNTPClient();
1463       m_psntpClient->Update();
1464     }
1465   }
1466 #endif
1467 }
1468
1469 void CApplication::StopTimeServer()
1470 {
1471 #ifdef HAS_TIME_SERVER
1472   if( m_psntpClient )
1473   {
1474     CLog::Log(LOGNOTICE, "stop time server client");
1475     SAFE_DELETE(m_psntpClient);
1476     CSectionLoader::Unload("SNTP");
1477   }
1478 #endif
1479 }
1480
1481 void CApplication::StartUPnP()
1482 {
1483 #ifdef HAS_UPNP
1484     StartUPnPClient();
1485     StartUPnPServer();
1486     StartUPnPRenderer();
1487 #endif
1488 }
1489
1490 void CApplication::StopUPnP()
1491 {
1492 #ifdef HAS_UPNP
1493   if (CUPnP::IsInstantiated())
1494   {
1495     CLog::Log(LOGNOTICE, "stopping upnp");
1496     CUPnP::ReleaseInstance();
1497   }
1498 #endif
1499 }
1500
1501 void CApplication::StartEventServer()
1502 {
1503 #ifdef HAS_EVENT_SERVER
1504   CEventServer* server = CEventServer::GetInstance();
1505   if (!server)
1506   {
1507     CLog::Log(LOGERROR, "ES: Out of memory");
1508     return;
1509   }
1510   if (g_guiSettings.GetBool("remoteevents.enabled"))
1511   {
1512     CLog::Log(LOGNOTICE, "ES: Starting event server");
1513     server->StartServer();
1514   }
1515 #endif
1516 }
1517
1518 bool CApplication::StopEventServer(bool promptuser)
1519 {
1520 #ifdef HAS_EVENT_SERVER
1521   CEventServer* server = CEventServer::GetInstance();
1522   if (!server)
1523   {
1524     CLog::Log(LOGERROR, "ES: Out of memory");
1525     return false;
1526   }
1527   if (promptuser)
1528   {
1529     if (server->GetNumberOfClients() > 0)
1530     {
1531       bool cancelled = false;
1532       if (!CGUIDialogYesNo::ShowAndGetInput(13140, 13141, 13142, 20022,
1533                                             -1, -1, cancelled, 10000)
1534           || cancelled)
1535       {
1536         CLog::Log(LOGNOTICE, "ES: Not stopping event server");
1537         return false;
1538       }
1539     }
1540     CLog::Log(LOGNOTICE, "ES: Stopping event server with confirmation");
1541   }
1542   else
1543   {
1544     CLog::Log(LOGNOTICE, "ES: Stopping event server");
1545   }
1546   CEventServer::GetInstance()->StopServer();
1547   return true;
1548 #endif
1549 }
1550
1551 void CApplication::RefreshEventServer()
1552 {
1553 #ifdef HAS_EVENT_SERVER
1554   if (g_guiSettings.GetBool("remoteevents.enabled"))
1555   {
1556     CEventServer::GetInstance()->RefreshSettings();
1557   }
1558 #endif
1559 }
1560
1561 void CApplication::StartDbusServer()
1562 {
1563 #ifdef HAS_DBUS_SERVER
1564   CDbusServer* serverDbus = CDbusServer::GetInstance();
1565   if (!serverDbus)
1566   {
1567     CLog::Log(LOGERROR, "DS: Out of memory");
1568     return;
1569   }
1570   CLog::Log(LOGNOTICE, "DS: Starting dbus server");
1571   serverDbus->StartServer( this );
1572 #endif
1573 }
1574
1575 bool CApplication::StopDbusServer(bool bWait)
1576 {
1577 #ifdef HAS_DBUS_SERVER
1578   CDbusServer* serverDbus = CDbusServer::GetInstance();
1579   if (!serverDbus)
1580   {
1581     CLog::Log(LOGERROR, "DS: Out of memory");
1582     return false;
1583   }
1584   CDbusServer::GetInstance()->StopServer(bWait);
1585 #endif
1586   return true;
1587 }
1588
1589 void CApplication::StartUPnPRenderer()
1590 {
1591 #ifdef HAS_UPNP
1592   if (g_guiSettings.GetBool("upnp.renderer"))
1593   {
1594     CLog::Log(LOGNOTICE, "starting upnp renderer");
1595     CUPnP::GetInstance()->StartRenderer();
1596   }
1597 #endif
1598 }
1599
1600 void CApplication::StopUPnPRenderer()
1601 {
1602 #ifdef HAS_UPNP
1603   if (CUPnP::IsInstantiated())
1604   {
1605     CLog::Log(LOGNOTICE, "stopping upnp renderer");
1606     CUPnP::GetInstance()->StopRenderer();
1607   }
1608 #endif
1609 }
1610
1611 void CApplication::StartUPnPClient()
1612 {
1613 #ifdef HAS_UPNP
1614   if (g_guiSettings.GetBool("upnp.client"))
1615   {
1616     CLog::Log(LOGNOTICE, "starting upnp client");
1617     CUPnP::GetInstance()->StartClient();
1618   }
1619 #endif
1620 }
1621
1622 void CApplication::StopUPnPClient()
1623 {
1624 #ifdef HAS_UPNP
1625   if (CUPnP::IsInstantiated())
1626   {
1627     CLog::Log(LOGNOTICE, "stopping upnp client");
1628     CUPnP::GetInstance()->StopClient();
1629   }
1630 #endif
1631 }
1632
1633 void CApplication::StartUPnPServer()
1634 {
1635 #ifdef HAS_UPNP
1636   if (g_guiSettings.GetBool("upnp.server"))
1637   {
1638     CLog::Log(LOGNOTICE, "starting upnp server");
1639     CUPnP::GetInstance()->StartServer();
1640   }
1641 #endif
1642 }
1643
1644 void CApplication::StopUPnPServer()
1645 {
1646 #ifdef HAS_UPNP
1647   if (CUPnP::IsInstantiated())
1648   {
1649     CLog::Log(LOGNOTICE, "stopping upnp server");
1650     CUPnP::GetInstance()->StopServer();
1651   }
1652 #endif
1653 }
1654
1655 void CApplication::StartZeroconf()
1656 {
1657 #ifdef HAS_ZEROCONF
1658   //entry in guisetting only present if HAS_ZEROCONF is set
1659   if(g_guiSettings.GetBool("servers.zeroconf"))
1660   {
1661     CLog::Log(LOGNOTICE, "starting zeroconf publishing");
1662     CZeroconf::GetInstance()->Start();
1663   }
1664 #endif
1665 }
1666
1667 void CApplication::StopZeroconf()
1668 {
1669 #ifdef HAS_ZEROCONF
1670   if(CZeroconf::IsInstantiated())
1671   {
1672     CLog::Log(LOGNOTICE, "stopping zeroconf publishing");
1673     CZeroconf::GetInstance()->Stop();
1674   }
1675 #endif
1676 }
1677
1678 void CApplication::DimLCDOnPlayback(bool dim)
1679 {
1680 #ifdef HAS_LCD
1681   if(g_lcd && dim && (g_guiSettings.GetInt("lcd.disableonplayback") != LED_PLAYBACK_OFF) && (g_guiSettings.GetInt("lcd.type") != LCD_TYPE_NONE))
1682   {
1683     if ( (IsPlayingVideo()) && g_guiSettings.GetInt("lcd.disableonplayback") == LED_PLAYBACK_VIDEO)
1684       g_lcd->SetBackLight(0);
1685     if ( (IsPlayingAudio()) && g_guiSettings.GetInt("lcd.disableonplayback") == LED_PLAYBACK_MUSIC)
1686       g_lcd->SetBackLight(0);
1687     if ( ((IsPlayingVideo() || IsPlayingAudio())) && g_guiSettings.GetInt("lcd.disableonplayback") == LED_PLAYBACK_VIDEO_MUSIC)
1688       g_lcd->SetBackLight(0);
1689   }
1690   else if(!dim)
1691 #ifdef _LINUX
1692     g_lcd->SetBackLight(1);
1693 #else
1694     g_lcd->SetBackLight(g_guiSettings.GetInt("lcd.backlight"));
1695 #endif
1696 #endif
1697 }
1698
1699 void CApplication::StartServices()
1700 {
1701 #if !defined(_WIN32) && defined(HAS_DVD_DRIVE)
1702   // Start Thread for DVD Mediatype detection
1703   CLog::Log(LOGNOTICE, "start dvd mediatype detection");
1704   m_DetectDVDType.Create(false, THREAD_MINSTACKSIZE);
1705 #endif
1706
1707   CLog::Log(LOGNOTICE, "initializing playlistplayer");
1708   g_playlistPlayer.SetRepeat(PLAYLIST_MUSIC, g_stSettings.m_bMyMusicPlaylistRepeat ? PLAYLIST::REPEAT_ALL : PLAYLIST::REPEAT_NONE);
1709   g_playlistPlayer.SetShuffle(PLAYLIST_MUSIC, g_stSettings.m_bMyMusicPlaylistShuffle);
1710   g_playlistPlayer.SetRepeat(PLAYLIST_VIDEO, g_stSettings.m_bMyVideoPlaylistRepeat ? PLAYLIST::REPEAT_ALL : PLAYLIST::REPEAT_NONE);
1711   g_playlistPlayer.SetShuffle(PLAYLIST_VIDEO, g_stSettings.m_bMyVideoPlaylistShuffle);
1712   CLog::Log(LOGNOTICE, "DONE initializing playlistplayer");
1713
1714 #ifdef HAS_LCD
1715   CLCDFactory factory;
1716   g_lcd = factory.Create();
1717   if (g_lcd)
1718   {
1719     g_lcd->Initialize();
1720   }
1721 #endif
1722 }
1723
1724 void CApplication::StopServices()
1725 {
1726   m_network.NetworkMessage(CNetwork::SERVICES_DOWN, 0);
1727
1728 #if !defined(_WIN32) && defined(HAS_DVD_DRIVE)
1729   CLog::Log(LOGNOTICE, "stop dvd detect media");
1730   m_DetectDVDType.StopThread();
1731 #endif
1732 }
1733
1734 void CApplication::DelayLoadSkin()
1735 {
1736   m_dwSkinTime = timeGetTime() + 2000;
1737   return ;
1738 }
1739
1740 void CApplication::CancelDelayLoadSkin()
1741 {
1742   m_dwSkinTime = 0;
1743 }
1744
1745 void CApplication::ReloadSkin()
1746 {
1747   CGUIMessage msg(GUI_MSG_LOAD_SKIN, -1, m_gWindowManager.GetActiveWindow());
1748   g_graphicsContext.SendMessage(msg);
1749   // Reload the skin, restoring the previously focused control.  We need this as
1750   // the window unload will reset all control states.
1751   CGUIWindow* pWindow = m_gWindowManager.GetWindow(m_gWindowManager.GetActiveWindow());
1752   unsigned iCtrlID = pWindow->GetFocusedControlID();
1753   g_application.LoadSkin(g_guiSettings.GetString("lookandfeel.skin"));
1754   pWindow = m_gWindowManager.GetWindow(m_gWindowManager.GetActiveWindow());
1755   if (pWindow && pWindow->HasSaveLastControl())
1756   {
1757     CGUIMessage msg3(GUI_MSG_SETFOCUS, m_gWindowManager.GetActiveWindow(), iCtrlID, 0);
1758     pWindow->OnMessage(msg3);
1759   }
1760 }
1761
1762 void CApplication::LoadSkin(const CStdString& strSkin)
1763 {
1764   bool bPreviousPlayingState=false;
1765   bool bPreviousRenderingState=false;
1766   if (g_application.m_pPlayer && g_application.IsPlayingVideo())
1767   {
1768     bPreviousPlayingState = !g_application.m_pPlayer->IsPaused();
1769     if (bPreviousPlayingState)
1770       g_application.m_pPlayer->Pause();
1771 #ifdef HAS_VIDEO_PLAYBACK
1772     if (!g_renderManager.Paused())
1773     {
1774       if (m_gWindowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO)
1775      {
1776         m_gWindowManager.ActivateWindow(WINDOW_HOME);
1777         bPreviousRenderingState = true;
1778       }
1779     }
1780 #endif
1781   }
1782   //stop the busy renderer if it's running before we lock the graphiccontext or we could deadlock.
1783   g_ApplicationRenderer.Stop();
1784   // close the music and video overlays (they're re-opened automatically later)
1785   CSingleLock lock(g_graphicsContext);
1786
1787   m_dwSkinTime = 0;
1788
1789   CStdString strHomePath;
1790   CStdString strSkinPath = g_settings.GetSkinFolder(strSkin);
1791
1792   CLog::Log(LOGINFO, "  load skin from:%s", strSkinPath.c_str());
1793
1794   // save the current window details
1795   int currentWindow = m_gWindowManager.GetActiveWindow();
1796   vector<int> currentModelessWindows;
1797   m_gWindowManager.GetActiveModelessWindows(currentModelessWindows);
1798
1799   CLog::Log(LOGINFO, "  delete old skin...");
1800   UnloadSkin();
1801
1802   // Load in the skin.xml file if it exists
1803   g_SkinInfo.Load(strSkinPath);
1804
1805   CLog::Log(LOGINFO, "  load fonts for skin...");
1806   g_graphicsContext.SetMediaDir(strSkinPath);
1807   g_directoryCache.ClearSubPaths(strSkinPath);
1808   if (g_langInfo.ForceUnicodeFont() && !g_fontManager.IsFontSetUnicode(g_guiSettings.GetString("lookandfeel.font")))
1809   {
1810     CLog::Log(LOGINFO, "    language needs a ttf font, loading first ttf font available");
1811     CStdString strFontSet;
1812     if (g_fontManager.GetFirstFontSetUnicode(strFontSet))
1813     {
1814       CLog::Log(LOGINFO, "    new font is '%s'", strFontSet.c_str());
1815       g_guiSettings.SetString("lookandfeel.font", strFontSet);
1816       g_settings.Save();
1817     }
1818     else
1819       CLog::Log(LOGERROR, "    no ttf font found, but needed for the language %s.", g_guiSettings.GetString("locale.language").c_str());
1820   }
1821   g_colorManager.Load(g_guiSettings.GetString("lookandfeel.skincolors"));
1822
1823   g_fontManager.LoadFonts(g_guiSettings.GetString("lookandfeel.font"));
1824
1825   // load in the skin strings
1826   CStdString skinPath, skinEnglishPath;
1827   CUtil::AddFileToFolder(strSkinPath, "language", skinPath);
1828   CUtil::AddFileToFolder(skinPath, g_guiSettings.GetString("locale.language"), skinPath);
1829   CUtil::AddFileToFolder(skinPath, "strings.xml", skinPath);
1830
1831   CUtil::AddFileToFolder(strSkinPath, "language", skinEnglishPath);
1832   CUtil::AddFileToFolder(skinEnglishPath, "English", skinEnglishPath);
1833   CUtil::AddFileToFolder(skinEnglishPath, "strings.xml", skinEnglishPath);
1834
1835   g_localizeStrings.LoadSkinStrings(skinPath, skinEnglishPath);
1836
1837   LARGE_INTEGER start;
1838   QueryPerformanceCounter(&start);
1839
1840   CLog::Log(LOGINFO, "  load new skin...");
1841   CGUIWindowHome *pHome = (CGUIWindowHome *)m_gWindowManager.GetWindow(WINDOW_HOME);
1842   if (!g_SkinInfo.Check(strSkinPath) || !pHome || !pHome->Load("Home.xml"))
1843   {
1844     // failed to load home.xml
1845     // fallback to default skin
1846     if ( strcmpi(strSkin.c_str(), DEFAULT_SKIN) != 0)
1847     {
1848       CLog::Log(LOGERROR, "failed to load home.xml for skin:%s, fallback to \"%s\" skin", strSkin.c_str(), DEFAULT_SKIN);
1849       g_guiSettings.SetString("lookandfeel.skin", DEFAULT_SKIN);
1850       LoadSkin(g_guiSettings.GetString("lookandfeel.skin"));
1851       return ;
1852     }
1853   }
1854
1855   // Load the user windows
1856   LoadUserWindows(strSkinPath);
1857
1858   LARGE_INTEGER end, freq;
1859   QueryPerformanceCounter(&end);
1860   QueryPerformanceFrequency(&freq);
1861   CLog::Log(LOGDEBUG,"Load Skin XML: %.2fms", 1000.f * (end.QuadPart - start.QuadPart) / freq.QuadPart);
1862
1863   CLog::Log(LOGINFO, "  initialize new skin...");
1864   m_guiPointer.AllocResources(true);
1865   m_guiDialogVolumeBar.AllocResources(true);
1866   m_guiDialogSeekBar.AllocResources(true);
1867   m_guiDialogKaiToast.AllocResources(true);
1868   m_guiDialogMuteBug.AllocResources(true);
1869   m_gWindowManager.AddMsgTarget(this);
1870   m_gWindowManager.AddMsgTarget(&g_playlistPlayer);
1871   m_gWindowManager.AddMsgTarget(&g_infoManager);
1872   m_gWindowManager.SetCallback(*this);
1873   m_gWindowManager.Initialize();
1874   g_audioManager.Initialize(CAudioContext::DEFAULT_DEVICE);
1875   g_audioManager.Load();
1876
1877   CGUIDialogFullScreenInfo* pDialog = NULL;
1878   RESOLUTION res;
1879   CStdString strPath = g_SkinInfo.GetSkinPath("DialogFullScreenInfo.xml", &res);
1880   if (CFile::Exists(strPath))
1881     pDialog = new CGUIDialogFullScreenInfo;
1882
1883   if (pDialog)
1884     m_gWindowManager.Add(pDialog); // window id = 142
1885
1886   CLog::Log(LOGINFO, "  skin loaded...");
1887
1888   // leave the graphics lock
1889   lock.Leave();
1890   g_ApplicationRenderer.Start();
1891
1892   // restore windows
1893   if (currentWindow != WINDOW_INVALID)
1894   {
1895     m_gWindowManager.ActivateWindow(currentWindow);
1896     for (unsigned int i = 0; i < currentModelessWindows.size(); i++)
1897     {
1898       CGUIDialog *dialog = (CGUIDialog *)m_gWindowManager.GetWindow(currentModelessWindows[i]);
1899       if (dialog) dialog->Show();
1900     }
1901   }
1902
1903   if (g_application.m_pPlayer && g_application.IsPlayingVideo())
1904   {
1905     if (bPreviousPlayingState)
1906       g_application.m_pPlayer->Pause();
1907     if (bPreviousRenderingState)
1908       m_gWindowManager.ActivateWindow(WINDOW_FULLSCREEN_VIDEO);
1909   }
1910 }
1911
1912 void CApplication::UnloadSkin()
1913 {
1914   g_ApplicationRenderer.Stop();
1915   g_audioManager.DeInitialize(CAudioContext::DEFAULT_DEVICE);
1916
1917   m_gWindowManager.DeInitialize();
1918
1919   //These windows are not handled by the windowmanager (why not?) so we should unload them manually
1920   CGUIMessage msg(GUI_MSG_WINDOW_DEINIT, 0, 0);
1921   m_guiPointer.OnMessage(msg);
1922   m_guiPointer.ResetControlStates();
1923   m_guiPointer.FreeResources(true);
1924   m_guiDialogMuteBug.OnMessage(msg);
1925   m_guiDialogMuteBug.ResetControlStates();
1926   m_guiDialogMuteBug.FreeResources(true);
1927
1928   // remove the skin-dependent window
1929   m_gWindowManager.Delete(WINDOW_DIALOG_FULLSCREEN_INFO);
1930
1931   g_TextureManager.Cleanup();
1932
1933   g_fontManager.Clear();
1934
1935   g_colorManager.Clear();
1936
1937   g_charsetConverter.reset();
1938
1939   g_infoManager.Clear();
1940 }
1941
1942 bool CApplication::LoadUserWindows(const CStdString& strSkinPath)
1943 {
1944   WIN32_FIND_DATA FindFileData;
1945   WIN32_FIND_DATA NextFindFileData;
1946   HANDLE hFind;
1947   TiXmlDocument xmlDoc;
1948   RESOLUTION resToUse = RES_INVALID;
1949
1950   // Start from wherever home.xml is
1951   g_SkinInfo.GetSkinPath("Home.xml", &resToUse);
1952   std::vector<CStdString> vecSkinPath;
1953   if (resToUse == RES_HDTV_1080i)
1954     vecSkinPath.push_back(CUtil::AddFileToFolder(strSkinPath, g_SkinInfo.GetDirFromRes(RES_HDTV_1080i)));
1955   if (resToUse == RES_HDTV_720p)
1956     vecSkinPath.push_back(CUtil::AddFileToFolder(strSkinPath, g_SkinInfo.GetDirFromRes(RES_HDTV_720p)));
1957   if (resToUse == RES_PAL_16x9 || resToUse == RES_NTSC_16x9 || resToUse == RES_HDTV_480p_16x9 || resToUse == RES_HDTV_720p || resToUse == RES_HDTV_1080i)
1958     vecSkinPath.push_back(CUtil::AddFileToFolder(strSkinPath, g_SkinInfo.GetDirFromRes(g_SkinInfo.GetDefaultWideResolution())));
1959   vecSkinPath.push_back(CUtil::AddFileToFolder(strSkinPath, g_SkinInfo.GetDirFromRes(g_SkinInfo.GetDefaultResolution())));
1960   for (unsigned int i = 0;i < vecSkinPath.size();++i)
1961   {
1962     CStdString strPath = CUtil::AddFileToFolder(vecSkinPath[i], "custom*.xml");
1963     CLog::Log(LOGINFO, "Loading user windows, path %s", vecSkinPath[i].c_str());
1964     hFind = FindFirstFile(_P(strPath).c_str(), &NextFindFileData);
1965
1966     CStdString strFileName;
1967     while (hFind != INVALID_HANDLE_VALUE)
1968     {
1969       FindFileData = NextFindFileData;
1970
1971       if (!FindNextFile(hFind, &NextFindFileData))
1972       {
1973         FindClose(hFind);
1974         hFind = INVALID_HANDLE_VALUE;
1975       }
1976
1977       // skip "up" directories, which come in all queries
1978       if (!strcmp(FindFileData.cFileName, ".") || !strcmp(FindFileData.cFileName, ".."))
1979         continue;
1980
1981       strFileName = CUtil::AddFileToFolder(vecSkinPath[i], FindFileData.cFileName);
1982       CLog::Log(LOGINFO, "Loading skin file: %s", strFileName.c_str());
1983       CStdString strLower(FindFileData.cFileName);
1984       strLower.MakeLower();
1985       strLower = CUtil::AddFileToFolder(vecSkinPath[i], strLower);
1986       if (!xmlDoc.LoadFile(strFileName) && !xmlDoc.LoadFile(strLower))
1987       {
1988         CLog::Log(LOGERROR, "unable to load:%s, Line %d\n%s", strFileName.c_str(), xmlDoc.ErrorRow(), xmlDoc.ErrorDesc());
1989         continue;
1990       }
1991
1992       // Root element should be <window>
1993       TiXmlElement* pRootElement = xmlDoc.RootElement();
1994       CStdString strValue = pRootElement->Value();
1995       if (!strValue.Equals("window"))
1996       {
1997         CLog::Log(LOGERROR, "file :%s doesnt contain <window>", strFileName.c_str());
1998         continue;
1999       }
2000
2001       // Read the <type> element to get the window type to create
2002       // If no type is specified, create a CGUIWindow as default
2003       CGUIWindow* pWindow = NULL;
2004       CStdString strType;
2005       if (pRootElement->Attribute("type"))
2006         strType = pRootElement->Attribute("type");
2007       else
2008       {
2009         const TiXmlNode *pType = pRootElement->FirstChild("type");
2010         if (pType && pType->FirstChild())
2011           strType = pType->FirstChild()->Value();
2012       }
2013       if (strType.Equals("dialog"))
2014         pWindow = new CGUIDialog(0, "");
2015       else if (strType.Equals("submenu"))
2016         pWindow = new CGUIDialogSubMenu();
2017       else if (strType.Equals("buttonmenu"))
2018         pWindow = new CGUIDialogButtonMenu();
2019       else
2020         pWindow = new CGUIStandardWindow();
2021
2022       int id = WINDOW_INVALID;
2023       if (!pRootElement->Attribute("id", &id))
2024       {
2025         const TiXmlNode *pType = pRootElement->FirstChild("id");
2026         if (pType && pType->FirstChild())
2027           id = atol(pType->FirstChild()->Value());
2028       }
2029       // Check to make sure the pointer isn't still null
2030       if (pWindow == NULL || id == WINDOW_INVALID)
2031       {
2032         CLog::Log(LOGERROR, "Out of memory / Failed to create new object in LoadUserWindows");
2033         return false;
2034       }
2035       if (m_gWindowManager.GetWindow(WINDOW_HOME + id))
2036       {
2037         delete pWindow;
2038         continue;
2039       }
2040       // set the window's xml file, and add it to the window manager.
2041       pWindow->SetXMLFile(FindFileData.cFileName);
2042       pWindow->SetID(WINDOW_HOME + id);
2043       m_gWindowManager.AddCustomWindow(pWindow);
2044     }
2045     CloseHandle(hFind);
2046   }
2047   return true;
2048 }
2049
2050 void CApplication::RenderNoPresent()
2051 {
2052   MEASURE_FUNCTION;
2053
2054 // DXMERGE: This might have been important (do we allow the vsync mode to change
2055 //          while not updating the UI setting?
2056 //  int vsync_mode = g_videoConfig.GetVSyncMode();
2057   int vsync_mode = g_guiSettings.GetInt("videoscreen.vsync");
2058   
2059   // dont show GUI when playing full screen video
2060   if (g_graphicsContext.IsFullScreenVideo() && IsPlaying() && !IsPaused())
2061   {
2062     if (vsync_mode == VSYNC_VIDEO)
2063       g_Windowing.SetVSync(true);
2064     if (m_bPresentFrame)
2065       g_renderManager.Present();
2066     else
2067       g_renderManager.RenderUpdate(true, 0, 255);
2068
2069     if (NeedRenderFullScreen())
2070       RenderFullScreen();
2071     RenderMemoryStatus();
2072
2073     ResetScreenSaver();
2074     g_infoManager.ResetCache();
2075     return;
2076   }
2077
2078 // DXMERGE: This may have been important?
2079 //  g_graphicsContext.AcquireCurrentContext();
2080
2081   if (vsync_mode==VSYNC_ALWAYS)
2082     g_Windowing.SetVSync(true);
2083   else if (vsync_mode!=VSYNC_DRIVER)
2084     g_Windowing.SetVSync(false);
2085
2086   g_ApplicationRenderer.Render();
2087
2088 }
2089
2090 void CApplication::DoRender()
2091 {
2092   g_graphicsContext.Lock();
2093
2094   //g_Windowing.BeginRender();
2095
2096   m_gWindowManager.UpdateModelessVisibility();
2097
2098   // draw GUI
2099   g_graphicsContext.Clear();
2100   //SWATHWIDTH of 4 improves fillrates (performance investigator)
2101   m_gWindowManager.Render();
2102
2103
2104   // if we're recording an audio stream then show blinking REC
2105   if (!g_graphicsContext.IsFullScreenVideo())
2106   {
2107     if (m_pPlayer && m_pPlayer->IsRecording() )
2108     {
2109       static int iBlinkRecord = 0;
2110       iBlinkRecord++;
2111       if (iBlinkRecord > 25)
2112       {
2113         CGUIFont* pFont = g_fontManager.GetFont("font13");
2114         CGUITextLayout::DrawText(pFont, 60, 50, 0xffff0000, 0, "REC", 0);
2115       }
2116
2117       if (iBlinkRecord > 50)
2118         iBlinkRecord = 0;
2119     }
2120   }
2121
2122   // Now render any dialogs
2123   m_gWindowManager.RenderDialogs();
2124
2125   // Render the mouse pointer
2126   if (g_Mouse.IsActive())
2127   {
2128     m_guiPointer.Render();
2129   }
2130
2131   {
2132     // reset image scaling and effect states
2133     g_graphicsContext.SetRenderingResolution(g_graphicsContext.GetVideoResolution(), 0, 0, false);
2134
2135     // If we have the remote codes enabled, then show them
2136     if (g_advancedSettings.m_displayRemoteCodes)
2137     {
2138       // TODO ?
2139     }
2140
2141     RenderMemoryStatus();
2142   }
2143
2144   RenderScreenSaver();
2145
2146   //g_Windowing.EndRender();
2147   g_TextureManager.FreeUnusedTextures();
2148
2149   g_graphicsContext.Unlock();
2150
2151   // reset our info cache - we do this at the end of Render so that it is
2152   // fresh for the next process(), or after a windowclose animation (where process()
2153   // isn't called)
2154   g_infoManager.ResetCache();
2155 }
2156
2157 static int screenSaverFadeAmount = 0;
2158
2159 void CApplication::RenderScreenSaver()
2160 {
2161   bool draw = false;
2162   float amount = 0.0f;
2163   if (m_screenSaverMode == "Dim")
2164     amount = 1.0f - g_guiSettings.GetInt("screensaver.dimlevel")*0.01f;
2165   else if (m_screenSaverMode == "Black")
2166     amount = 1.0f; // fully fade
2167   // special case for dim screensaver
2168   if (amount > 0.f)
2169   {
2170     if (m_bScreenSave)
2171     {
2172       draw = true;
2173       if (screenSaverFadeAmount < 100)
2174       {
2175         screenSaverFadeAmount = std::min(100, screenSaverFadeAmount + 2);  // around a second to fade
2176       }
2177     }
2178     else
2179     {
2180       if (screenSaverFadeAmount > 0)
2181       {
2182         draw = true;
2183         screenSaverFadeAmount = std::max(0, screenSaverFadeAmount - 4);  // around a half second to unfade
2184       }
2185     }
2186   }
2187   if (draw)
2188   {
2189     color_t color = ((color_t)(screenSaverFadeAmount * amount * 2.55f) & 0xff) << 24;
2190     CGUITexture::DrawQuad(CRect(0, 0, (float)g_graphicsContext.GetWidth(), (float)g_graphicsContext.GetHeight()), color);
2191   }
2192 }
2193
2194 bool CApplication::WaitFrame(DWORD timeout)
2195 {
2196   bool done = false;
2197 #ifdef HAS_SDL
2198   // Wait for all other frames to be presented
2199   SDL_mutexP(m_frameMutex);
2200   while(m_frameCount > 0)
2201   {
2202     int result = SDL_CondWaitTimeout(m_frameCond, m_frameMutex, timeout);
2203     if(result == SDL_MUTEX_TIMEDOUT)
2204       break;
2205     if(result < 0)
2206       CLog::Log(LOGWARNING, "CApplication::WaitFrame - error from conditional wait");
2207   }  
2208   done = m_frameCount == 0;
2209   SDL_mutexV(m_frameMutex);
2210 #endif
2211   return done;
2212 }
2213
2214 void CApplication::NewFrame()
2215 {
2216 #ifdef HAS_SDL
2217   // We just posted another frame. Keep track and notify.
2218   SDL_mutexP(m_frameMutex);
2219   m_frameCount++;
2220   SDL_mutexV(m_frameMutex);
2221
2222   SDL_CondBroadcast(m_frameCond);
2223 #endif
2224 }
2225
2226 void CApplication::Render()
2227 {
2228   if (!m_AppActive && !m_bStop && (!IsPlayingVideo() || IsPaused()))
2229   {
2230     Sleep(1);
2231     ResetScreenSaver();
2232     return;
2233   }
2234
2235   MEASURE_FUNCTION;
2236
2237   { // frame rate limiter (really bad, but it does the trick :p)
2238     static unsigned int lastFrameTime = 0;
2239     unsigned int currentTime = timeGetTime();
2240     int nDelayTime = 0;
2241     // Less fps in DPMS or Black screensaver
2242     bool lowfps = (m_dpmsIsActive
2243                    || (m_bScreenSave && (m_screenSaverMode == "Black")
2244                        && (screenSaverFadeAmount >= 100)));
2245     // Whether externalplayer is playing and we're unfocused
2246     bool extPlayerActive = m_eCurrentPlayer >= EPC_EXTPLAYER && IsPlaying() && !m_AppFocused;
2247     unsigned int singleFrameTime = 10; // default limit 100 fps
2248
2249     m_bPresentFrame = false;
2250     if (!extPlayerActive && g_graphicsContext.IsFullScreenVideo() && !IsPaused())
2251     {
2252 #ifdef HAS_SDL
2253       SDL_mutexP(m_frameMutex);
2254
2255       // If we have frames or if we get notified of one, consume it.
2256       while(m_frameCount == 0)
2257       {
2258         int result = SDL_CondWaitTimeout(m_frameCond, m_frameMutex, 100);
2259         if(result == SDL_MUTEX_TIMEDOUT)
2260           break;
2261         if(result < 0)
2262           CLog::Log(LOGWARNING, "CApplication::Render - error from conditional wait");
2263       }
2264
2265       m_bPresentFrame = m_frameCount > 0;
2266       SDL_mutexV(m_frameMutex);
2267 #else
2268       m_bPresentFrame = true;
2269 #endif
2270     }
2271     else
2272     {
2273       // engage the frame limiter as needed
2274       bool limitFrames = lowfps || extPlayerActive;
2275       // DXMERGE - we checked for g_videoConfig.GetVSyncMode() before this
2276       //           perhaps allowing it to be set differently than the UI option??
2277       if (g_guiSettings.GetInt("videoscreen.vsync") == VSYNC_DISABLED ||
2278           g_guiSettings.GetInt("videoscreen.vsync") == VSYNC_VIDEO)
2279         limitFrames = true; // not using vsync.
2280       else if ((g_infoManager.GetFPS() > g_graphicsContext.GetFPS() + 10) && g_infoManager.GetFPS() > 1000/singleFrameTime)
2281         limitFrames = true; // using vsync, but it isn't working.
2282
2283       if (limitFrames)
2284       {
2285         if (extPlayerActive)
2286         {
2287           ResetScreenSaver();  // Prevent screensaver dimming the screen
2288           singleFrameTime = 1000;  // 1 fps, high wakeup latency but v.low CPU usage
2289         }
2290         else if (lowfps)
2291           singleFrameTime = 200;  // 5 fps, <=200 ms latency to wake up
2292
2293         if (lastFrameTime + singleFrameTime > currentTime)
2294           nDelayTime = lastFrameTime + singleFrameTime - currentTime;
2295         Sleep(nDelayTime);
2296       }
2297     }
2298
2299     lastFrameTime = timeGetTime();
2300   }
2301   g_graphicsContext.Lock();
2302
2303   // check if we need font reloading
2304   if(g_fontManager.FontsNeedReloading())
2305     g_fontManager.ReloadTTFFonts();
2306
2307   if(!g_Windowing.BeginRender())
2308     return;
2309
2310   RenderNoPresent();
2311   g_Windowing.EndRender();
2312   g_graphicsContext.Flip();
2313   g_infoManager.UpdateFPS();
2314   g_renderManager.UpdateResolution();
2315   g_graphicsContext.Unlock();
2316   
2317 #ifdef HAS_SDL
2318   SDL_mutexP(m_frameMutex);
2319   if(m_frameCount > 0)
2320     m_frameCount--;
2321   SDL_mutexV(m_frameMutex);
2322   SDL_CondBroadcast(m_frameCond);
2323 #endif
2324 }
2325
2326 void CApplication::RenderMemoryStatus()
2327 {
2328   MEASURE_FUNCTION;
2329
2330   g_cpuInfo.getUsedPercentage(); // must call it to recalculate pct values
2331
2332   if (LOG_LEVEL_DEBUG_FREEMEM <= g_advancedSettings.m_logLevel)
2333   {
2334     // reset the window scaling and fade status
2335     RESOLUTION res = g_graphicsContext.GetVideoResolution();
2336     g_graphicsContext.SetRenderingResolution(res, 0, 0, false);
2337
2338     CStdString info;
2339     MEMORYSTATUS stat;
2340     GlobalMemoryStatus(&stat);
2341     CStdString profiling = CGUIControlProfiler::IsRunning() ? " (profiling)" : "";
2342 #ifdef __APPLE__
2343     double dCPU = m_resourceCounter.GetCPUUsage();
2344     info.Format("FreeMem %ju/%ju MB, FPS %2.1f, CPU-Total %d%%. CPU-XBMC %4.2f%%%s", stat.dwAvailPhys/(1024*1024), stat.dwTotalPhys/(1024*1024),
2345               g_infoManager.GetFPS(), g_cpuInfo.getUsedPercentage(), dCPU, profiling.c_str());
2346 #elif !defined(_LINUX)
2347     CStdString strCores = g_cpuInfo.GetCoresUsageString();
2348     info.Format("FreeMem %d/%d Kb, FPS %2.1f, %s%s", stat.dwAvailPhys/1024, stat.dwTotalPhys/1024, g_infoManager.GetFPS(), strCores.c_str(), profiling.c_str());
2349 #else
2350     double dCPU = m_resourceCounter.GetCPUUsage();
2351     CStdString strCores = g_cpuInfo.GetCoresUsageString();
2352     info.Format("FreeMem %d/%d Kb, FPS %2.1f, %s. CPU-XBMC %4.2f%%%s", stat.dwAvailPhys/1024, stat.dwTotalPhys/1024,
2353               g_infoManager.GetFPS(), strCores.c_str(), dCPU, profiling.c_str());
2354 #endif
2355
2356     static int yShift = 20;
2357     static int xShift = 40;
2358     static unsigned int lastShift = time(NULL);
2359     time_t now = time(NULL);
2360     if (now - lastShift > 10)
2361     {
2362       yShift *= -1;
2363       if (now % 5 == 0)
2364         xShift *= -1;
2365       lastShift = now;
2366     }
2367
2368     float x = xShift + 0.04f * g_graphicsContext.GetWidth() + g_settings.m_ResInfo[res].Overscan.left;
2369     float y = yShift + 0.04f * g_graphicsContext.GetHeight() + g_settings.m_ResInfo[res].Overscan.top;
2370
2371     CGUITextLayout::DrawOutlineText(g_fontManager.GetFont("font13"), x, y, 0xffffffff, 0xff000000, 2, info);
2372   }
2373 }
2374 // OnKey() translates the key into a CAction which is sent on to our Window Manager.
2375 // The window manager will return true if the event is processed, false otherwise.
2376 // If not already processed, this routine handles global keypresses.  It returns
2377 // true if the key has been processed, false otherwise.
2378
2379 bool CApplication::OnKey(CKey& key)
2380 {
2381   // Turn the mouse off, as we've just got a keypress from controller or remote
2382   g_Mouse.SetActive(false);
2383   CAction action;
2384
2385   // get the current active window
2386   int iWin = m_gWindowManager.GetActiveWindow() & WINDOW_ID_MASK;
2387
2388   // this will be checked for certain keycodes that need
2389   // special handling if the screensaver is active
2390   CButtonTranslator::GetInstance().GetAction(iWin, key, action);
2391
2392   // a key has been pressed.
2393   // Reset the screensaver timer
2394   // but not for the analog thumbsticks/triggers
2395   if (!key.IsAnalogButton())
2396   {
2397     // reset Idle Timer
2398     m_idleTimer.StartZero();
2399     bool processKey = AlwaysProcess(action);
2400
2401     ResetScreenSaver();
2402
2403     // allow some keys to be processed while the screensaver is active
2404     if (WakeUpScreenSaverAndDPMS() && !processKey)
2405     {
2406       g_Keyboard.Reset();
2407       return true;
2408     }
2409   }
2410
2411   // change this if we have a dialog up
2412   if (m_gWindowManager.HasModalDialog())
2413   {
2414     iWin = m_gWindowManager.GetTopMostModalDialogID() & WINDOW_ID_MASK;
2415   }
2416   if (iWin == WINDOW_DIALOG_FULLSCREEN_INFO)
2417   { // fullscreen info dialog - special case
2418     CButtonTranslator::GetInstance().GetAction(iWin, key, action);
2419
2420     g_Keyboard.Reset();
2421
2422     if (OnAction(action))
2423       return true;
2424
2425     // fallthrough to the main window
2426     iWin = WINDOW_FULLSCREEN_VIDEO;
2427   }
2428   if (iWin == WINDOW_FULLSCREEN_VIDEO)
2429   {
2430     // current active window is full screen video.
2431     if (g_application.m_pPlayer && g_application.m_pPlayer->IsInMenu())
2432     {
2433       // if player is in some sort of menu, (ie DVDMENU) map buttons differently
2434       CButtonTranslator::GetInstance().GetAction(WINDOW_VIDEO_MENU, key, action);
2435     }
2436     else
2437     {
2438       // no then use the fullscreen window section of keymap.xml to map key->action
2439       CButtonTranslator::GetInstance().GetAction(iWin, key, action);
2440     }
2441   }
2442   else
2443   {
2444     // current active window isnt the fullscreen window
2445     // just use corresponding section from keymap.xml
2446     // to map key->action
2447
2448     // first determine if we should use keyboard input directly
2449     bool useKeyboard = key.FromKeyboard() && (iWin == WINDOW_DIALOG_KEYBOARD || iWin == WINDOW_DIALOG_NUMERIC);
2450     CGUIWindow *window = m_gWindowManager.GetWindow(iWin);
2451     if (window)
2452     {
2453       CGUIControl *control = window->GetFocusedControl();
2454       if (control)
2455       {
2456         if (control->GetControlType() == CGUIControl::GUICONTROL_EDIT ||
2457             (control->IsContainer() && g_Keyboard.GetShift()))
2458           useKeyboard = true;
2459       }
2460     }
2461     if (useKeyboard)
2462     {
2463       if (key.GetFromHttpApi())
2464       {
2465         if (key.GetButtonCode() != KEY_INVALID)
2466           action.id = key.GetButtonCode();
2467         action.unicode = key.GetUnicode();
2468       }
2469       else
2470       { // see if we've got an ascii key
2471         if (g_Keyboard.GetUnicode())
2472         {
2473           action.id = g_Keyboard.GetAscii() | KEY_ASCII; // Only for backwards compatibility
2474           action.unicode = g_Keyboard.GetUnicode();
2475         }
2476         else
2477         {
2478           action.id = g_Keyboard.GetVKey() | KEY_VKEY;
2479           action.unicode = 0;
2480         }
2481       }
2482
2483       g_Keyboard.Reset();
2484
2485       if (OnAction(action))
2486         return true;
2487       // failed to handle the keyboard action, drop down through to standard action
2488     }
2489     if (key.GetFromHttpApi())
2490     {
2491       if (key.GetButtonCode() != KEY_INVALID)
2492       {
2493         action.id = key.GetButtonCode();
2494         CButtonTranslator::GetInstance().GetAction(iWin, key, action);
2495       }
2496     }
2497     else
2498       CButtonTranslator::GetInstance().GetAction(iWin, key, action);
2499   }
2500   if (!key.IsAnalogButton())
2501     CLog::Log(LOGDEBUG, "%s: %i pressed, action is %i", __FUNCTION__, (int) key.GetButtonCode(), action.id);
2502
2503   //  Play a sound based on the action
2504   g_audioManager.PlayActionSound(action);
2505
2506   g_Keyboard.Reset();
2507
2508   return OnAction(action);
2509 }
2510
2511 bool CApplication::OnAction(CAction &action)
2512 {
2513 #ifdef HAS_WEB_SERVER
2514   // Let's tell the outside world about this action
2515   if (m_pXbmcHttp && g_stSettings.m_HttpApiBroadcastLevel>=2)
2516   {
2517     CStdString tmp;
2518     tmp.Format("%i",action.id);
2519     getApplicationMessenger().HttpApi("broadcastlevel; OnAction:"+tmp+";2");
2520   }
2521 #endif
2522
2523   // special case for switching between GUI & fullscreen mode.
2524   if (action.id == ACTION_SHOW_GUI)
2525   { // Switch to fullscreen mode if we can
2526     if (SwitchToFullScreen())
2527     {
2528       m_navigationTimer.StartZero();
2529       return true;
2530     }
2531   }
2532
2533   if (action.id == ACTION_TOGGLE_FULLSCREEN)
2534   {
2535     g_graphicsContext.ToggleFullScreenRoot();
2536     return true;
2537   }
2538
2539   // in normal case
2540   // just pass the action to the current window and let it handle it
2541   if (m_gWindowManager.OnAction(action))
2542   {
2543     m_navigationTimer.StartZero();
2544     return true;
2545   }
2546
2547   // handle extra global presses
2548
2549   // screenshot : take a screenshot :)
2550   if (action.id == ACTION_TAKE_SCREENSHOT)
2551   {
2552     CUtil::TakeScreenshot();
2553     return true;
2554   }
2555   // built in functions : execute the built-in
2556   if (action.id == ACTION_BUILT_IN_FUNCTION)
2557   {
2558     CUtil::ExecBuiltIn(action.strAction);
2559     m_navigationTimer.StartZero();
2560     return true;
2561   }
2562
2563   // reload keymaps
2564   if (action.id == ACTION_RELOAD_KEYMAPS)
2565   {
2566     CButtonTranslator::GetInstance().Clear();
2567     CButtonTranslator::GetInstance().Load();
2568   }
2569
2570   // show info : Shows the current video or song information
2571   if (action.id == ACTION_SHOW_INFO)
2572   {
2573     g_infoManager.ToggleShowInfo();
2574     return true;
2575   }
2576
2577   // codec info : Shows the current song, video or picture codec information
2578   if (action.id == ACTION_SHOW_CODEC)
2579   {
2580     g_infoManager.ToggleShowCodec();
2581     return true;
2582   }
2583
2584   if ((action.id == ACTION_INCREASE_RATING || action.id == ACTION_DECREASE_RATING) && IsPlayingAudio())
2585   {
2586     const CMusicInfoTag *tag = g_infoManager.GetCurrentSongTag();
2587     if (tag)
2588     {
2589       *m_itemCurrentFile->GetMusicInfoTag() = *tag;
2590       char rating = tag->GetRating();
2591       bool needsUpdate(false);
2592       if (rating > '0' && action.id == ACTION_DECREASE_RATING)
2593       {
2594         m_itemCurrentFile->GetMusicInfoTag()->SetRating(rating - 1);
2595         needsUpdate = true;
2596       }
2597       else if (rating < '5' && action.id == ACTION_INCREASE_RATING)
2598       {
2599         m_itemCurrentFile->GetMusicInfoTag()->SetRating(rating + 1);
2600         needsUpdate = true;
2601       }
2602       if (needsUpdate)
2603       {
2604         CMusicDatabase db;
2605         if (db.Open())      // OpenForWrite() ?
2606         {
2607           db.SetSongRating(m_itemCurrentFile->m_strPath, m_itemCurrentFile->GetMusicInfoTag()->GetRating());
2608           db.Close();
2609         }
2610         // send a message to all windows to tell them to update the fileitem (eg playlistplayer, media windows)
2611         CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, m_itemCurrentFile);
2612         g_graphicsContext.SendMessage(msg);
2613       }
2614     }
2615     return true;
2616   }
2617
2618   // stop : stops playing current audio song
2619   if (action.id == ACTION_STOP)
2620   {
2621     StopPlaying();
2622     return true;
2623   }
2624
2625   // previous : play previous song from playlist
2626   if (action.id == ACTION_PREV_ITEM)
2627   {
2628     // first check whether we're within 3 seconds of the start of the track
2629     // if not, we just revert to the start of the track
2630     if (m_pPlayer && m_pPlayer->CanSeek() && GetTime() > 3)
2631     {
2632       SeekTime(0);
2633       SetPlaySpeed(1);
2634     }
2635     else
2636     {
2637       g_playlistPlayer.PlayPrevious();
2638     }
2639     return true;
2640   }
2641
2642   // next : play next song from playlist
2643   if (action.id == ACTION_NEXT_ITEM)
2644   {
2645     if (IsPlaying() && m_pPlayer->SkipNext())
2646       return true;
2647
2648     g_playlistPlayer.PlayNext();
2649
2650     return true;
2651   }
2652
2653   if ( IsPlaying())
2654   {
2655     // OSD toggling
2656     if (action.id == ACTION_SHOW_OSD)
2657     {
2658       if (IsPlayingVideo() && IsPlayingFullScreenVideo())
2659       {
2660         CGUIWindowOSD *pOSD = (CGUIWindowOSD *)m_gWindowManager.GetWindow(WINDOW_OSD);
2661         if (pOSD)
2662         {
2663           if (pOSD->IsDialogRunning())
2664             pOSD->Close();
2665           else
2666             pOSD->DoModal();
2667           return true;
2668         }
2669       }
2670     }
2671
2672     // pause : pauses current audio song
2673     if (action.id == ACTION_PAUSE && m_iPlaySpeed == 1)
2674     {
2675       m_pPlayer->Pause();
2676 #ifdef HAS_KARAOKE
2677       m_pKaraokeMgr->SetPaused( m_pPlayer->IsPaused() );
2678 #endif
2679       if (!m_pPlayer->IsPaused())
2680       { // unpaused - set the playspeed back to normal
2681         SetPlaySpeed(1);
2682       }
2683       if (!g_guiSettings.GetBool("lookandfeel.soundsduringplayback"))
2684         g_audioManager.Enable(m_pPlayer->IsPaused());
2685       return true;
2686     }
2687     if (!m_pPlayer->IsPaused())
2688     {
2689       // if we do a FF/RW in my music then map PLAY action togo back to normal speed
2690       // if we are playing at normal speed, then allow play to pause
2691       if (action.id == ACTION_PLAYER_PLAY || action.id == ACTION_PAUSE)
2692       {
2693         if (m_iPlaySpeed != 1)
2694         {
2695           SetPlaySpeed(1);
2696         }
2697         else
2698         {
2699           m_pPlayer->Pause();
2700         }
2701         return true;
2702       }
2703       if (action.id == ACTION_PLAYER_FORWARD || action.id == ACTION_PLAYER_REWIND)
2704       {
2705         int iPlaySpeed = m_iPlaySpeed;
2706         if (action.id == ACTION_PLAYER_REWIND && iPlaySpeed == 1) // Enables Rewinding
2707           iPlaySpeed *= -2;
2708         else if (action.id == ACTION_PLAYER_REWIND && iPlaySpeed > 1) //goes down a notch if you're FFing
2709           iPlaySpeed /= 2;
2710         else if (action.id == ACTION_PLAYER_FORWARD && iPlaySpeed < 1) //goes up a notch if you're RWing
2711           iPlaySpeed /= 2;
2712         else
2713           iPlaySpeed *= 2;
2714
2715         if (action.id == ACTION_PLAYER_FORWARD && iPlaySpeed == -1) //sets iSpeed back to 1 if -1 (didn't plan for a -1)
2716           iPlaySpeed = 1;
2717         if (iPlaySpeed > 32 || iPlaySpeed < -32)
2718           iPlaySpeed = 1;
2719
2720         SetPlaySpeed(iPlaySpeed);
2721         return true;
2722       }
2723       else if ((action.amount1 || GetPlaySpeed() != 1) && (action.id == ACTION_ANALOG_REWIND || action.id == ACTION_ANALOG_FORWARD))
2724       {
2725         // calculate the speed based on the amount the button is held down
2726         int iPower = (int)(action.amount1 * MAX_FFWD_SPEED + 0.5f);
2727         // returns 0 -> MAX_FFWD_SPEED
2728         int iSpeed = 1 << iPower;
2729         if (iSpeed != 1 && action.id == ACTION_ANALOG_REWIND)
2730           iSpeed = -iSpeed;
2731         g_application.SetPlaySpeed(iSpeed);
2732         if (iSpeed == 1)
2733           CLog::Log(LOGDEBUG,"Resetting playspeed");
2734         return true;
2735       }
2736     }
2737     // allow play to unpause
2738     else
2739     {
2740       if (action.id == ACTION_PLAYER_PLAY)
2741       {
2742         // unpause, and set the playspeed back to normal
2743         m_pPlayer->Pause();
2744         if (!g_guiSettings.GetBool("lookandfeel.soundsduringplayback"))
2745           g_audioManager.Enable(m_pPlayer->IsPaused());
2746
2747         g_application.SetPlaySpeed(1);
2748         return true;
2749       }
2750     }
2751   }
2752   if (action.id == ACTION_MUTE)
2753   {
2754     Mute();
2755     return true;
2756   }
2757
2758   if (action.id == ACTION_TOGGLE_DIGITAL_ANALOG)
2759   {
2760     if(g_guiSettings.GetInt("audiooutput.mode")==AUDIO_DIGITAL)
2761       g_guiSettings.SetInt("audiooutput.mode", AUDIO_ANALOG);
2762     else
2763       g_guiSettings.SetInt("audiooutput.mode", AUDIO_DIGITAL);
2764     g_application.Restart();
2765     if (m_gWindowManager.GetActiveWindow() == WINDOW_SETTINGS_SYSTEM)
2766     {
2767       CGUIMessage msg(GUI_MSG_WINDOW_INIT, 0,0,WINDOW_INVALID,m_gWindowManager.GetActiveWindow());
2768       m_gWindowManager.SendMessage(msg);
2769     }
2770     return true;
2771   }
2772
2773   // Check for global volume control
2774   if (action.amount1 && (action.id == ACTION_VOLUME_UP || action.id == ACTION_VOLUME_DOWN))
2775   {
2776     if (!m_pPlayer || !m_pPlayer->IsPassthrough())
2777     {
2778       // increase or decrease the volume
2779       int volume = g_stSettings.m_nVolumeLevel + g_stSettings.m_dynamicRangeCompressionLevel;
2780
2781       // calculate speed so that a full press will equal 1 second from min to max
2782       float speed = float(VOLUME_MAXIMUM - VOLUME_MINIMUM);
2783       if( action.repeat )
2784         speed *= action.repeat;
2785       else
2786         speed /= 50; //50 fps
2787       if (g_stSettings.m_bMute)
2788       {
2789         // only unmute if volume is to be increased, otherwise leave muted
2790         if (action.id == ACTION_VOLUME_DOWN)
2791           return true;
2792         Mute();
2793         return true;
2794       }
2795       if (action.id == ACTION_VOLUME_UP)
2796       {
2797         volume += (int)((float)fabs(action.amount1) * action.amount1 * speed);
2798       }
2799       else
2800       {
2801         volume -= (int)((float)fabs(action.amount1) * action.amount1 * speed);
2802       }
2803
2804       SetHardwareVolume(volume);
2805   #ifndef HAS_SDL_AUDIO
2806       g_audioManager.SetVolume(g_stSettings.m_nVolumeLevel);
2807   #else
2808       g_audioManager.SetVolume((int)(128.f * (g_stSettings.m_nVolumeLevel - VOLUME_MINIMUM) / (float)(VOLUME_MAXIMUM - VOLUME_MINIMUM)));
2809   #endif
2810     }
2811     // show visual feedback of volume change...
2812     m_guiDialogVolumeBar.Show();
2813     m_guiDialogVolumeBar.OnAction(action);
2814     return true;
2815   }
2816   // Check for global seek control
2817   if (IsPlaying() && action.amount1 && (action.id == ACTION_ANALOG_SEEK_FORWARD || action.id == ACTION_ANALOG_SEEK_BACK))
2818   {
2819     if (!m_pPlayer->CanSeek()) return false;
2820     m_guiDialogSeekBar.OnAction(action);
2821     return true;
2822   }
2823   if (action.id == ACTION_GUIPROFILE_BEGIN)
2824   {
2825     CGUIControlProfiler::Instance().SetOutputFile(_P("special://home/guiprofiler.xml"));
2826     CGUIControlProfiler::Instance().Start();
2827     return true;
2828   }
2829   return false;
2830 }
2831
2832 void CApplication::UpdateLCD()
2833 {
2834 #ifdef HAS_LCD
2835   static long lTickCount = 0;
2836
2837   if (!g_lcd || g_guiSettings.GetInt("lcd.type") == LCD_TYPE_NONE)
2838     return ;
2839   long lTimeOut = 1000;
2840   if ( m_iPlaySpeed != 1)
2841     lTimeOut = 0;
2842   if ( ((long)GetTickCount() - lTickCount) >= lTimeOut)
2843   {
2844     if (g_application.NavigationIdleTime() < 5)
2845       g_lcd->Render(ILCD::LCD_MODE_NAVIGATION);
2846     else if (IsPlayingVideo())
2847       g_lcd->Render(ILCD::LCD_MODE_VIDEO);
2848     else if (IsPlayingAudio())
2849       g_lcd->Render(ILCD::LCD_MODE_MUSIC);
2850     else if (IsInScreenSaver())
2851       g_lcd->Render(ILCD::LCD_MODE_SCREENSAVER);
2852     else
2853       g_lcd->Render(ILCD::LCD_MODE_GENERAL);
2854
2855     // reset tick count
2856     lTickCount = GetTickCount();
2857   }
2858 #endif
2859 }
2860
2861 void CApplication::FrameMove()
2862 {
2863   MEASURE_FUNCTION;
2864
2865   // currently we calculate the repeat time (ie time from last similar keypress) just global as fps
2866   float frameTime = m_frameTime.GetElapsedSeconds();
2867   m_frameTime.StartZero();
2868   // never set a frametime less than 2 fps to avoid problems when debuggin and on breaks
2869   if( frameTime > 0.5 ) frameTime = 0.5;
2870
2871   // check if there are notifications to display
2872   if (m_guiDialogKaiToast.DoWork())
2873   {
2874     if (!m_guiDialogKaiToast.IsDialogRunning())
2875     {
2876       m_guiDialogKaiToast.Show();
2877     }
2878   }
2879
2880   UpdateLCD();
2881   
2882 #ifdef HAS_LIRC
2883   // Read the input from a remote
2884   g_RemoteControl.Update();
2885 #endif
2886   
2887   // process input actions
2888   CWinEvents::MessagePump();
2889   ProcessHTTPApiButtons();
2890   ProcessRemote(frameTime);
2891   ProcessGamepad(frameTime);
2892   ProcessEventServer(frameTime);
2893 }
2894
2895 bool CApplication::ProcessGamepad(float frameTime)
2896 {
2897 #ifdef HAS_SDL_JOYSTICK
2898   int iWin = m_gWindowManager.GetActiveWindow() & WINDOW_ID_MASK;
2899   if (m_gWindowManager.HasModalDialog())
2900   {
2901     iWin = m_gWindowManager.GetTopMostModalDialogID() & WINDOW_ID_MASK;
2902   }
2903   int bid;
2904   g_Joystick.Update();
2905   if (g_Joystick.GetButton(bid))
2906   {
2907     // reset Idle Timer
2908     m_idleTimer.StartZero();
2909
2910     ResetScreenSaver();
2911     if (WakeUpScreenSaverAndDPMS())
2912     {
2913       g_Joystick.Reset(true);
2914       return true;
2915     }
2916
2917     CAction action;
2918     bool fullrange;
2919     string jname = g_Joystick.GetJoystick();
2920     if (CButtonTranslator::GetInstance().TranslateJoystickString(iWin, jname.c_str(), bid, JACTIVE_BUTTON, action.id, action.strAction, fullrange))
2921     {
2922       action.amount1 = 1.0f;
2923       action.repeat = 0.0f;
2924       g_audioManager.PlayActionSound(action);
2925       g_Joystick.Reset();
2926       g_Mouse.SetActive(false);
2927       return OnAction(action);
2928     }
2929     else
2930     {
2931       g_Joystick.Reset();
2932     }
2933   }
2934   if (g_Joystick.GetAxis(bid))
2935   {