Skip to content
This repository

Build Shared Lib #1049

Merged
merged 14 commits into from almost 2 years ago

5 participants

Cory Fields jmarshallnz davilla Sascha Montellese Memphiz
Cory Fields
Owner
theuni commented June 05, 2012

This is a continuation of #890

This PR is purely foundational. No new behavior is introduced here, except for the ability to build a libxbmc.so in linux/osx, but the lib isn't good for much in its current form.

I'm submitting this now because I have several things up that depend on it. Because it's a nightmare to rebase, it would be a big help to get this part in, and continue contributing to it after that.

There are 2 primary things going on here:

  1. Building as a shared lib. Gives us the ability to do unit testing with all of xbmc's features at our disposal. Also allows for stand-alone programs to use our functionality, eg. scrapers. Eventually we may want to come up with an API that allows for individual services to be started up.

  2. Refactor startup to allow us to run without a window. When combined with #1, this could lead to headless, lightweight xbmc instances. There is still lots of work that remains here. Many functions still rely on a window to exist, so it's quite crash-heavy. As a result, I didn't hook up any way to run this way.

@davilla This likely needs some osx love. For OSX I made an attempt at the link-line, but I'm unfamiliar with the syntax there.

@wiso For win32 I didn't attempt any of the shared lib stuff, only fixed up the startup sequence to match current behavior. I have no way to test, but I think it should be ok.

jmarshallnz
Owner

Looks good to me on the whole. I'll check if win32 builds + runs.

davilla
Collaborator

osx builds/runs with a simple addition of main.cpp, I've made a patch and passed it on to TheUni. IOS/ATV2 builds should be fine, they don't use SDL at all and don't even compile/link in xbmc.cpp.

OSX/IOS sign off.

Cory Fields
Owner
theuni commented June 06, 2012

Thanks. Win32/OSX patches included. Squashed down and ready to go.

Cory Fields theuni merged commit 66520ff into from June 06, 2012
Cory Fields theuni closed this June 06, 2012
Memphiz
Owner

IOS + ATV2 not needed?

Owner

ahh nvm read the comment on the PR - nothing to see here.

Collaborator

we might need a look/see here on ios. forum reports of black screen, sounds like something not setup right.

Sascha Montellese
Collaborator

This causes a problem on win32 (haven't checked linux or osx) with multi-monitor support. The problem is that the GUI settings (specifically "videoscreen.screen") are created before calling CApplication::CreateGUI() which makes the call to InitWindowSystem which in turn calls the code to get the available monitor information on win32. Unfortunately we use g_Windowing.GetNumScreens() when we create the GUI setting "videoscreen.screen" but at that point it isn't properly initialized yet so g_Windowing.GetNumScreens() returns 0. This doesn't cause a problem for the first monitor because it has the index 0 but for any additional monitor with an index > 0 the GUI settings will just set "videoscreen.screen" to the maximum possible value which is 0.

Cory Fields
Owner
theuni commented June 09, 2012

Thanks for the rundown, I'll have a look

Cory Fields
Owner
theuni commented June 09, 2012

From a quick grep, it appears as though that control is disabled and we're just using it to keep the current screen number. I don't see it being used as a ceiling anywhere. As a quick fix, it should be enough to change g_Windowing.GetNumScreens() to INT_MAX. It's a hack, but imo it's pretty hackish as it is now to be storing that kind of thing in a hidden control.

davilla
Collaborator

looks like numscreens also hits osx, there's a forum post regarding it

Sascha Montellese
Collaborator

A hidden control? It's the control that is used in Settings -> System -> Video to switch between the different screens and windowed mode so it's anything but disabled. The ceiling is implemented in the control's internal logic. I can give INT_MAX a try.

@davilla Yeah it hits every platform as long as you have more than one monitor.

Sascha Montellese
Collaborator

ok INT_MAX seems to work but it's a very ugly hack IMO. We should consider that there might be similar effects in other places which just weren't uncovered yet.

Cory Fields
Owner
theuni commented June 12, 2012

Yea, had another look. Not sure what lead me to believe it was hidden. Though I still think that changing it to a big number is "safe", it's certainly no real solution.

I'll push a quck-fix tomorrow changing this to 32 or so so that nightly builds won't stay borked. Will come up with a proper fix and do a PR after that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
24  Makefile.in
@@ -183,13 +183,20 @@ CXXFLAGS=@CXXFLAGS@
183 183
 LDFLAGS=@LDFLAGS@
184 184
 INCLUDES=$(sort @INCLUDES@)
185 185
 
186  
-CLEAN_FILES=xbmc.bin xbmc-xrandr
  186
+CLEAN_FILES=xbmc.bin xbmc-xrandr libxbmc.so
187 187
 
188 188
 DISTCLEAN_FILES=config.h config.log config.status tools/Linux/xbmc.sh \
189 189
         tools/Linux/xbmc-standalone.sh autom4te.cache config.h.in~ \
190 190
         system/libcpluff-@ARCH@.so
191 191
 
192  
-all : Makefile externals xbmc.bin xbmc-xrandr skins
  192
+ifeq (@USE_LIBXBMC@,1)
  193
+FINAL_TARGETS+=libxbmc.so
  194
+else
  195
+FINAL_TARGETS=xbmc.bin skins xbmc-xrandr
  196
+endif
  197
+FINAL_TARGETS+=Makefile externals
  198
+
  199
+all : $(FINAL_TARGETS)
193 200
 	@echo '-----------------------'
194 201
 	@echo 'XBMC built successfully'
195 202
 	@echo '-----------------------'
@@ -335,7 +342,14 @@ OBJSXBMC:=$(filter-out $(DYNOBJSXBMC), $(OBJSXBMC))
335 342
 
336 343
 LIBS += @PYTHON_LDFLAGS@
337 344
 
338  
-xbmc.bin: $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC)
  345
+libxbmc.so: $(OBJSXBMC) $(DYNOBJSXBMC)
  346
+ifeq ($(findstring osx,@ARCH@), osx)
  347
+	$(SILENT_LD) $(CXX) $(LDFLAGS) -bundle -o $@ -Wl,-all_load,-ObjC $(DYNOBJSXBMC) $(OBJSXBMC) $(LIBS)
  348
+else
  349
+	$(SILENT_LD) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $@ -Wl,--whole-archive $(DYNOBJSXBMC) $(OBJSXBMC) -Wl,--no-whole-archive $(LIBS)
  350
+endif
  351
+
  352
+xbmc.bin: $(OBJSXBMC) $(DYNOBJSXBMC)
339 353
 
340 354
 ifeq ($(findstring osx,@ARCH@), osx)
341 355
 	$(SILENT_LD) $(CXX) $(LDFLAGS) -o xbmc.bin -Wl,-all_load,-ObjC $(DYNOBJSXBMC) $(OBJSXBMC) $(LIBS) -rdynamic
@@ -379,8 +393,12 @@ install-binaries: install-scripts
379 393
 ifeq (1,@USE_XRANDR@)
380 394
 	@install xbmc-xrandr $(DESTDIR)$(libdir)/xbmc/xbmc-xrandr
381 395
 endif
  396
+ifeq (@USE_LIBXBMC@,1)
  397
+	@install libxbmc.so $(DESTDIR)$(libdir)/xbmc/libxbmc.so
  398
+else
382 399
 	@echo "You can run XBMC with the command 'xbmc'"
383 400
 endif
  401
+endif
384 402
 
385 403
 install-arch:
386 404
 	@# Arch dependent files
4  XBMC.xcodeproj/project.pbxproj
@@ -949,6 +949,7 @@
949 949
 		F5D8D732102BB3B1004A11AB /* OverlayRendererGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D8D72F102BB3B1004A11AB /* OverlayRendererGL.cpp */; };
950 950
 		F5D8D733102BB3B1004A11AB /* OverlayRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D8D731102BB3B1004A11AB /* OverlayRenderer.cpp */; };
951 951
 		F5D8EF5B103912A4004A11AB /* DVDSubtitleParserVplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D8EF59103912A4004A11AB /* DVDSubtitleParserVplayer.cpp */; };
  952
+		F5DA82D915803129003EE43C /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5DA82D815803129003EE43C /* main.cpp */; };
952 953
 		F5DC87E2110A287400EE1B15 /* RingBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5DC87E1110A287400EE1B15 /* RingBuffer.cpp */; };
953 954
 		F5DC8801110A46C700EE1B15 /* ModplugCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5DC8800110A46C700EE1B15 /* ModplugCodec.cpp */; };
954 955
 		F5DC888B110A654000EE1B15 /* libapetag.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F5DC888A110A654000EE1B15 /* libapetag.a */; };
@@ -3011,6 +3012,7 @@
3011 3012
 		F5D8D731102BB3B1004A11AB /* OverlayRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OverlayRenderer.cpp; sourceTree = "<group>"; };
3012 3013
 		F5D8EF59103912A4004A11AB /* DVDSubtitleParserVplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDSubtitleParserVplayer.cpp; sourceTree = "<group>"; };
3013 3014
 		F5D8EF5A103912A4004A11AB /* DVDSubtitleParserVplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDSubtitleParserVplayer.h; sourceTree = "<group>"; };
  3015
+		F5DA82D815803129003EE43C /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
3014 3016
 		F5DC87E0110A287400EE1B15 /* RingBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RingBuffer.h; sourceTree = "<group>"; };
3015 3017
 		F5DC87E1110A287400EE1B15 /* RingBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RingBuffer.cpp; sourceTree = "<group>"; };
3016 3018
 		F5DC87FF110A46C700EE1B15 /* ModplugCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModplugCodec.h; sourceTree = "<group>"; };
@@ -4345,6 +4347,7 @@
4345 4347
 				E38E184F0D25F9FA00618676 /* IProgressCallback.h */,
4346 4348
 				E38E18580D25F9FA00618676 /* LangInfo.cpp */,
4347 4349
 				E38E18590D25F9FA00618676 /* LangInfo.h */,
  4350
+				F5DA82D815803129003EE43C /* main.cpp */,
4348 4351
 				880DBE4B0DC223FF00E26B71 /* MediaSource.cpp */,
4349 4352
 				880DBE4C0DC223FF00E26B71 /* MediaSource.h */,
4350 4353
 				E38E1DC10D25F9FD00618676 /* NfoFile.cpp */,
@@ -7297,6 +7300,7 @@
7297 7300
 				7C6EB330155BD1D40080368A /* ImageFile.cpp in Sources */,
7298 7301
 				7C6EB6FA155F32C30080368A /* HTTPImageHandler.cpp in Sources */,
7299 7302
 				18E7CACB1578C26D001D4554 /* CDDARipJob.cpp in Sources */,
  7303
+				F5DA82D915803129003EE43C /* main.cpp in Sources */,
7300 7304
 			);
7301 7305
 			runOnlyForDeploymentPostprocessing = 0;
7302 7306
 		};
10  configure.in
@@ -147,6 +147,11 @@ dashes="------------------------"
147 147
 final_message="\n  XBMC Configuration:"
148 148
 final_message="\n$dashes$final_message\n$dashes"
149 149
 
  150
+AC_ARG_ENABLE([shared-lib],
  151
+  [AS_HELP_STRING([--enable-shared-lib],
  152
+  [build libxbmc. helpful for tests (default is no)])],
  153
+  [build_shared_lib=$enableval],
  154
+  [build_shared_lib=no])
150 155
 
151 156
 AC_ARG_ENABLE([debug],
152 157
   [AS_HELP_STRING([--enable-debug],
@@ -561,6 +566,11 @@ case $host in
561 566
 esac
562 567
 AC_SUBST([ARCH])
563 568
 
  569
+if test "$build_shared_lib" = "yes"; then
  570
+  final_message="$final_message\n Shared lib\tYes"
  571
+  AC_SUBST(USE_LIBXBMC,1)
  572
+fi
  573
+
564 574
 # platform debug flags
565 575
 if test "$use_debug" = "yes"; then
566 576
   final_message="$final_message\n  Debugging:\tYes"
453  xbmc/Application.cpp
@@ -552,11 +552,9 @@ void CApplication::Preflight()
552 552
 
553 553
 bool CApplication::Create()
554 554
 {
  555
+  Preflight();
555 556
   g_settings.Initialize(); //Initialize default AdvancedSettings
556 557
 
557  
-  m_bSystemScreenSaverEnable = g_Windowing.IsSystemScreenSaverEnabled();
558  
-  g_Windowing.EnableSystemScreenSaver(false);
559  
-
560 558
 #ifdef _LINUX
561 559
   tzset();   // Initialize timezone information variables
562 560
 #endif
@@ -595,6 +593,9 @@ bool CApplication::Create()
595 593
     return false;
596 594
   }
597 595
 
  596
+  // Init our DllLoaders emu env
  597
+  init_emu_environ();
  598
+
598 599
   g_settings.LoadProfiles(PROFILES_FILE);
599 600
 
600 601
   CLog::Log(LOGNOTICE, "-----------------------------------------------------------------------");
@@ -642,54 +643,6 @@ bool CApplication::Create()
642 643
   g_xrandr.LoadCustomModeLinesToAllOutputs();
643 644
 #endif
644 645
 
645  
-  // Init our DllLoaders emu env
646  
-  init_emu_environ();
647  
-
648  
-
649  
-#ifdef HAS_SDL
650  
-  CLog::Log(LOGNOTICE, "Setup SDL");
651  
-
652  
-  /* Clean up on exit, exit on window close and interrupt */
653  
-  atexit(SDL_Quit);
654  
-
655  
-  uint32_t sdlFlags = 0;
656  
-
657  
-#if defined(HAS_SDL_OPENGL) || (HAS_GLES == 2)
658  
-  sdlFlags |= SDL_INIT_VIDEO;
659  
-#endif
660  
-
661  
-#if defined(HAS_SDL_JOYSTICK) && !defined(TARGET_WINDOWS)
662  
-  sdlFlags |= SDL_INIT_JOYSTICK;
663  
-#endif
664  
-
665  
-  //depending on how it's compiled, SDL periodically calls XResetScreenSaver when it's fullscreen
666  
-  //this might bring the monitor out of standby, so we have to disable it explicitly
667  
-  //by passing 0 for overwrite to setsenv, the user can still override this by setting the environment variable
668  
-#if defined(_LINUX) && !defined(TARGET_DARWIN)
669  
-  setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0);
670  
-#endif
671  
-
672  
-#endif // HAS_SDL
673  
-
674  
-#ifdef _LINUX
675  
-  // for nvidia cards - vsync currently ALWAYS enabled.
676  
-  // the reason is that after screen has been setup changing this env var will make no difference.
677  
-  setenv("__GL_SYNC_TO_VBLANK", "1", 0);
678  
-  setenv("__GL_YIELD", "USLEEP", 0);
679  
-#endif
680  
-
681  
-#ifdef HAS_SDL
682  
-  if (SDL_Init(sdlFlags) != 0)
683  
-  {
684  
-    CLog::Log(LOGFATAL, "XBAppEx: Unable to initialize SDL: %s", SDL_GetError());
685  
-    return false;
686  
-  }
687  
-  #if defined(TARGET_DARWIN)
688  
-  // SDL_Init will install a handler for segfaults, restore the default handler.
689  
-  signal(SIGSEGV, SIG_DFL);
690  
-  #endif
691  
-#endif
692  
-
693 646
   // for python scripts that check the OS
694 647
 #if defined(TARGET_DARWIN)
695 648
   setenv("OS","OS X",true);
@@ -699,15 +652,6 @@ bool CApplication::Create()
699 652
   SetEnvironmentVariable("OS","win32");
700 653
 #endif
701 654
 
702  
-  // Initialize core peripheral port support. Note: If these parameters
703  
-  // are 0 and NULL, respectively, then the default number and types of
704  
-  // controllers will be initialized.
705  
-  if (!g_Windowing.InitWindowSystem())
706  
-  {
707  
-    CLog::Log(LOGFATAL, "CApplication::Create: Unable to init windowing system");
708  
-    return false;
709  
-  }
710  
-
711 655
   g_powerManager.Initialize();
712 656
 
713 657
   // Load the AudioEngine before settings as they need to query the engine
@@ -790,6 +734,77 @@ bool CApplication::Create()
790 734
   XBMCHelper::GetInstance().Configure();
791 735
 #endif
792 736
 
  737
+  CUtil::InitRandomSeed();
  738
+
  739
+#ifdef HAS_SDL_JOYSTICK
  740
+  g_Joystick.Initialize();
  741
+#endif
  742
+
  743
+  g_mediaManager.Initialize();
  744
+
  745
+  m_lastFrameTime = XbmcThreads::SystemClockMillis();
  746
+  m_lastRenderTime = m_lastFrameTime;
  747
+  return true;
  748
+}
  749
+
  750
+bool CApplication::CreateGUI()
  751
+{
  752
+#ifdef HAS_SDL
  753
+  CLog::Log(LOGNOTICE, "Setup SDL");
  754
+
  755
+  /* Clean up on exit, exit on window close and interrupt */
  756
+  atexit(SDL_Quit);
  757
+
  758
+  uint32_t sdlFlags = 0;
  759
+
  760
+#if defined(HAS_SDL_OPENGL) || (HAS_GLES == 2)
  761
+  sdlFlags |= SDL_INIT_VIDEO;
  762
+#endif
  763
+
  764
+#if defined(HAS_SDL_JOYSTICK) && !defined(TARGET_WINDOWS)
  765
+  sdlFlags |= SDL_INIT_JOYSTICK;
  766
+#endif
  767
+
  768
+  //depending on how it's compiled, SDL periodically calls XResetScreenSaver when it's fullscreen
  769
+  //this might bring the monitor out of standby, so we have to disable it explicitly
  770
+  //by passing 0 for overwrite to setsenv, the user can still override this by setting the environment variable
  771
+#if defined(_LINUX) && !defined(TARGET_DARWIN)
  772
+  setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0);
  773
+#endif
  774
+
  775
+#endif // HAS_SDL
  776
+
  777
+#ifdef _LINUX
  778
+  // for nvidia cards - vsync currently ALWAYS enabled.
  779
+  // the reason is that after screen has been setup changing this env var will make no difference.
  780
+  setenv("__GL_SYNC_TO_VBLANK", "1", 0);
  781
+  setenv("__GL_YIELD", "USLEEP", 0);
  782
+#endif
  783
+
  784
+  m_bSystemScreenSaverEnable = g_Windowing.IsSystemScreenSaverEnabled();
  785
+  g_Windowing.EnableSystemScreenSaver(false);
  786
+
  787
+#ifdef HAS_SDL
  788
+  if (SDL_Init(sdlFlags) != 0)
  789
+  {
  790
+    CLog::Log(LOGFATAL, "XBAppEx: Unable to initialize SDL: %s", SDL_GetError());
  791
+    return false;
  792
+  }
  793
+  #if defined(TARGET_DARWIN)
  794
+  // SDL_Init will install a handler for segfaults, restore the default handler.
  795
+  signal(SIGSEGV, SIG_DFL);
  796
+  #endif
  797
+#endif
  798
+
  799
+  // Initialize core peripheral port support. Note: If these parameters
  800
+  // are 0 and NULL, respectively, then the default number and types of
  801
+  // controllers will be initialized.
  802
+  if (!g_Windowing.InitWindowSystem())
  803
+  {
  804
+    CLog::Log(LOGFATAL, "CApplication::Create: Unable to init windowing system");
  805
+    return false;
  806
+  }
  807
+
793 808
   // update the window resolution
794 809
   g_Windowing.SetWindowResolution(g_guiSettings.GetInt("window.width"), g_guiSettings.GetInt("window.height"));
795 810
 
@@ -802,33 +817,10 @@ bool CApplication::Create()
802 817
     CLog::Log(LOGERROR, "The screen resolution requested is not valid, resetting to a valid mode");
803 818
     g_guiSettings.m_LookAndFeelResolution = RES_DESKTOP;
804 819
   }
805  
-
806  
-#ifdef TARGET_DARWIN_OSX
807  
-  // force initial window creation to be windowed, if fullscreen, it will switch to it below
808  
-  // fixes the white screen of death if starting fullscreen and switching to windowed.
809  
-  bool bFullScreen = false;
810  
-  if (!g_Windowing.CreateNewWindow("XBMC", bFullScreen, g_settings.m_ResInfo[RES_WINDOW], OnEvent))
811  
-  {
812  
-    CLog::Log(LOGFATAL, "CApplication::Create: Unable to create window");
813  
-    return false;
814  
-  }
815  
-#else
816  
-  bool bFullScreen = g_guiSettings.m_LookAndFeelResolution != RES_WINDOW;
817  
-  if (!g_Windowing.CreateNewWindow("XBMC", bFullScreen, g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution], OnEvent))
  820
+  if (!InitWindow())
818 821
   {
819  
-    CLog::Log(LOGFATAL, "CApplication::Create: Unable to create window");
820 822
     return false;
821 823
   }
822  
-#endif
823  
-
824  
-  if (!g_Windowing.InitRenderSystem())
825  
-  {
826  
-    CLog::Log(LOGFATAL, "CApplication::Create: Unable to init rendering system");
827  
-    return false;
828  
-  }
829  
-
830  
-  // set GUI res and force the clear of the screen
831  
-  g_graphicsContext.SetVideoResolution(g_guiSettings.m_LookAndFeelResolution);
832 824
 
833 825
   if (g_advancedSettings.m_splashImage)
834 826
   {
@@ -858,18 +850,43 @@ bool CApplication::Create()
858 850
             g_settings.m_ResInfo[iResolution].strMode.c_str());
859 851
   g_windowManager.Initialize();
860 852
 
861  
-  CUtil::InitRandomSeed();
  853
+  return true;
  854
+}
862 855
 
863  
-#ifdef HAS_SDL_JOYSTICK
864  
-  g_Joystick.Initialize();
  856
+bool CApplication::InitWindow()
  857
+{
  858
+#ifdef TARGET_DARWIN_OSX
  859
+  // force initial window creation to be windowed, if fullscreen, it will switch to it below
  860
+  // fixes the white screen of death if starting fullscreen and switching to windowed.
  861
+  bool bFullScreen = false;
  862
+  if (!g_Windowing.CreateNewWindow("XBMC", bFullScreen, g_settings.m_ResInfo[RES_WINDOW], OnEvent))
  863
+  {
  864
+    CLog::Log(LOGFATAL, "CApplication::Create: Unable to create window");
  865
+    return false;
  866
+  }
  867
+#else
  868
+  bool bFullScreen = g_guiSettings.m_LookAndFeelResolution != RES_WINDOW;
  869
+  if (!g_Windowing.CreateNewWindow("XBMC", bFullScreen, g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution], OnEvent))
  870
+  {
  871
+    CLog::Log(LOGFATAL, "CApplication::Create: Unable to create window");
  872
+    return false;
  873
+  }
865 874
 #endif
866 875
 
867  
-  g_mediaManager.Initialize();
868  
-
869  
-  m_lastFrameTime = XbmcThreads::SystemClockMillis();
870  
-  m_lastRenderTime = m_lastFrameTime;
  876
+  if (!g_Windowing.InitRenderSystem())
  877
+  {
  878
+    CLog::Log(LOGFATAL, "CApplication::Create: Unable to init rendering system");
  879
+    return false;
  880
+  }
  881
+  // set GUI res and force the clear of the screen
  882
+  g_graphicsContext.SetVideoResolution(g_guiSettings.m_LookAndFeelResolution);
  883
+  return true;
  884
+}
871 885
 
872  
-  return Initialize();
  886
+bool CApplication::DestroyWindow()
  887
+{
  888
+  g_Windowing.DestroyRenderSystem();
  889
+  return g_Windowing.DestroyWindow();
873 890
 }
874 891
 
875 892
 bool CApplication::InitDirectoriesLinux()
@@ -1150,135 +1167,146 @@ bool CApplication::Initialize()
1150 1167
 
1151 1168
   // Init DPMS, before creating the corresponding setting control.
1152 1169
   m_dpms = new DPMSSupport();
1153  
-  g_guiSettings.GetSetting("powermanagement.displaysoff")->SetVisible(m_dpms->IsSupported());
1154  
-
1155  
-  g_windowManager.Add(new CGUIWindowHome);                     // window id = 0
1156  
-  g_windowManager.Add(new CGUIWindowPrograms);                 // window id = 1
1157  
-  g_windowManager.Add(new CGUIWindowPictures);                 // window id = 2
1158  
-  g_windowManager.Add(new CGUIWindowFileManager);      // window id = 3
1159  
-  g_windowManager.Add(new CGUIWindowSettings);                 // window id = 4
1160  
-  g_windowManager.Add(new CGUIWindowSystemInfo);               // window id = 7
  1170
+  if (g_windowManager.Initialized())
  1171
+  {
  1172
+    g_guiSettings.GetSetting("powermanagement.displaysoff")->SetVisible(m_dpms->IsSupported());
  1173
+
  1174
+    g_windowManager.Add(new CGUIWindowHome);                     // window id = 0
  1175
+    g_windowManager.Add(new CGUIWindowPrograms);                 // window id = 1
  1176
+    g_windowManager.Add(new CGUIWindowPictures);                 // window id = 2
  1177
+    g_windowManager.Add(new CGUIWindowFileManager);      // window id = 3
  1178
+    g_windowManager.Add(new CGUIWindowSettings);                 // window id = 4
  1179
+    g_windowManager.Add(new CGUIWindowSystemInfo);               // window id = 7
1161 1180
 #ifdef HAS_GL
1162  
-  g_windowManager.Add(new CGUIWindowTestPatternGL);      // window id = 8
  1181
+    g_windowManager.Add(new CGUIWindowTestPatternGL);      // window id = 8
1163 1182
 #endif
1164 1183
 #ifdef HAS_DX
1165  
-  g_windowManager.Add(new CGUIWindowTestPatternDX);      // window id = 8
1166  
-#endif
1167  
-  g_windowManager.Add(new CGUIDialogTeletext);               // window id =
1168  
-  g_windowManager.Add(new CGUIWindowSettingsScreenCalibration); // window id = 11
1169  
-  g_windowManager.Add(new CGUIWindowSettingsCategory);         // window id = 12 slideshow:window id 2007
1170  
-  g_windowManager.Add(new CGUIWindowVideoNav);                 // window id = 36
1171  
-  g_windowManager.Add(new CGUIWindowVideoPlaylist);            // window id = 28
1172  
-  g_windowManager.Add(new CGUIWindowLoginScreen);            // window id = 29
1173  
-  g_windowManager.Add(new CGUIWindowSettingsProfile);          // window id = 34
1174  
-  g_windowManager.Add(new CGUIWindowAddonBrowser);          // window id = 40
1175  
-  g_windowManager.Add(new CGUIWindowScreensaverDim);            // window id = 97  
1176  
-  g_windowManager.Add(new CGUIWindowDebugInfo);            // window id = 98
1177  
-  g_windowManager.Add(new CGUIWindowPointer);            // window id = 99
1178  
-  g_windowManager.Add(new CGUIDialogYesNo);              // window id = 100
1179  
-  g_windowManager.Add(new CGUIDialogProgress);           // window id = 101
1180  
-  g_windowManager.Add(new CGUIDialogKeyboard);           // window id = 103
1181  
-  g_windowManager.Add(new CGUIDialogVolumeBar);          // window id = 104
1182  
-  g_windowManager.Add(new CGUIDialogSeekBar);            // window id = 115
1183  
-  g_windowManager.Add(new CGUIDialogSubMenu);            // window id = 105
1184  
-  g_windowManager.Add(new CGUIDialogContextMenu);        // window id = 106
1185  
-  g_windowManager.Add(new CGUIDialogKaiToast);           // window id = 107
1186  
-  g_windowManager.Add(new CGUIDialogNumeric);            // window id = 109
1187  
-  g_windowManager.Add(new CGUIDialogGamepad);            // window id = 110
1188  
-  g_windowManager.Add(new CGUIDialogButtonMenu);         // window id = 111
1189  
-  g_windowManager.Add(new CGUIDialogMusicScan);          // window id = 112
1190  
-  g_windowManager.Add(new CGUIDialogMuteBug);            // window id = 113
1191  
-  g_windowManager.Add(new CGUIDialogPlayerControls);     // window id = 114
  1184
+    g_windowManager.Add(new CGUIWindowTestPatternDX);      // window id = 8
  1185
+#endif
  1186
+    g_windowManager.Add(new CGUIDialogTeletext);               // window id =
  1187
+    g_windowManager.Add(new CGUIWindowSettingsScreenCalibration); // window id = 11
  1188
+    g_windowManager.Add(new CGUIWindowSettingsCategory);         // window id = 12 slideshow:window id 2007
  1189
+    g_windowManager.Add(new CGUIWindowVideoNav);                 // window id = 36
  1190
+    g_windowManager.Add(new CGUIWindowVideoPlaylist);            // window id = 28
  1191
+    g_windowManager.Add(new CGUIWindowLoginScreen);            // window id = 29
  1192
+    g_windowManager.Add(new CGUIWindowSettingsProfile);          // window id = 34
  1193
+    g_windowManager.Add(new CGUIWindowAddonBrowser);          // window id = 40
  1194
+    g_windowManager.Add(new CGUIWindowScreensaverDim);            // window id = 97  
  1195
+    g_windowManager.Add(new CGUIWindowDebugInfo);            // window id = 98
  1196
+    g_windowManager.Add(new CGUIWindowPointer);            // window id = 99
  1197
+    g_windowManager.Add(new CGUIDialogYesNo);              // window id = 100
  1198
+    g_windowManager.Add(new CGUIDialogProgress);           // window id = 101
  1199
+    g_windowManager.Add(new CGUIDialogKeyboard);           // window id = 103
  1200
+    g_windowManager.Add(new CGUIDialogVolumeBar);          // window id = 104
  1201
+    g_windowManager.Add(new CGUIDialogSeekBar);            // window id = 115
  1202
+    g_windowManager.Add(new CGUIDialogSubMenu);            // window id = 105
  1203
+    g_windowManager.Add(new CGUIDialogContextMenu);        // window id = 106
  1204
+    g_windowManager.Add(new CGUIDialogKaiToast);           // window id = 107
  1205
+    g_windowManager.Add(new CGUIDialogNumeric);            // window id = 109
  1206
+    g_windowManager.Add(new CGUIDialogGamepad);            // window id = 110
  1207
+    g_windowManager.Add(new CGUIDialogButtonMenu);         // window id = 111
  1208
+    g_windowManager.Add(new CGUIDialogMusicScan);          // window id = 112
  1209
+    g_windowManager.Add(new CGUIDialogMuteBug);            // window id = 113
  1210
+    g_windowManager.Add(new CGUIDialogPlayerControls);     // window id = 114
1192 1211
 #ifdef HAS_KARAOKE
1193  
-  g_windowManager.Add(new CGUIDialogKaraokeSongSelectorSmall); // window id 143
1194  
-  g_windowManager.Add(new CGUIDialogKaraokeSongSelectorLarge); // window id 144
1195  
-#endif
1196  
-  g_windowManager.Add(new CGUIDialogSlider);             // window id = 145
1197  
-  g_windowManager.Add(new CGUIDialogMusicOSD);           // window id = 120
1198  
-  g_windowManager.Add(new CGUIDialogVisualisationPresetList);   // window id = 122
1199  
-  g_windowManager.Add(new CGUIDialogVideoSettings);             // window id = 123
1200  
-  g_windowManager.Add(new CGUIDialogAudioSubtitleSettings);     // window id = 124
1201  
-  g_windowManager.Add(new CGUIDialogVideoBookmarks);      // window id = 125
1202  
-  // Don't add the filebrowser dialog - it's created and added when it's needed
1203  
-  g_windowManager.Add(new CGUIDialogNetworkSetup);  // window id = 128
1204  
-  g_windowManager.Add(new CGUIDialogMediaSource);   // window id = 129
1205  
-  g_windowManager.Add(new CGUIDialogProfileSettings); // window id = 130
1206  
-  g_windowManager.Add(new CGUIDialogVideoScan);      // window id = 133
1207  
-  g_windowManager.Add(new CGUIDialogFavourites);     // window id = 134
1208  
-  g_windowManager.Add(new CGUIDialogSongInfo);       // window id = 135
1209  
-  g_windowManager.Add(new CGUIDialogSmartPlaylistEditor);       // window id = 136
1210  
-  g_windowManager.Add(new CGUIDialogSmartPlaylistRule);       // window id = 137
1211  
-  g_windowManager.Add(new CGUIDialogBusy);      // window id = 138
1212  
-  g_windowManager.Add(new CGUIDialogPictureInfo);      // window id = 139
1213  
-  g_windowManager.Add(new CGUIDialogAddonInfo);
1214  
-  g_windowManager.Add(new CGUIDialogAddonSettings);      // window id = 140
  1212
+    g_windowManager.Add(new CGUIDialogKaraokeSongSelectorSmall); // window id 143
  1213
+    g_windowManager.Add(new CGUIDialogKaraokeSongSelectorLarge); // window id 144
  1214
+#endif
  1215
+    g_windowManager.Add(new CGUIDialogSlider);             // window id = 145
  1216
+    g_windowManager.Add(new CGUIDialogMusicOSD);           // window id = 120
  1217
+    g_windowManager.Add(new CGUIDialogVisualisationPresetList);   // window id = 122
  1218
+    g_windowManager.Add(new CGUIDialogVideoSettings);             // window id = 123
  1219
+    g_windowManager.Add(new CGUIDialogAudioSubtitleSettings);     // window id = 124
  1220
+    g_windowManager.Add(new CGUIDialogVideoBookmarks);      // window id = 125
  1221
+    // Don't add the filebrowser dialog - it's created and added when it's needed
  1222
+    g_windowManager.Add(new CGUIDialogNetworkSetup);  // window id = 128
  1223
+    g_windowManager.Add(new CGUIDialogMediaSource);   // window id = 129
  1224
+    g_windowManager.Add(new CGUIDialogProfileSettings); // window id = 130
  1225
+    g_windowManager.Add(new CGUIDialogVideoScan);      // window id = 133
  1226
+    g_windowManager.Add(new CGUIDialogFavourites);     // window id = 134
  1227
+    g_windowManager.Add(new CGUIDialogSongInfo);       // window id = 135
  1228
+    g_windowManager.Add(new CGUIDialogSmartPlaylistEditor);       // window id = 136
  1229
+    g_windowManager.Add(new CGUIDialogSmartPlaylistRule);       // window id = 137
  1230
+    g_windowManager.Add(new CGUIDialogBusy);      // window id = 138
  1231
+    g_windowManager.Add(new CGUIDialogPictureInfo);      // window id = 139
  1232
+    g_windowManager.Add(new CGUIDialogAddonInfo);
  1233
+    g_windowManager.Add(new CGUIDialogAddonSettings);      // window id = 140
1215 1234
 #ifdef HAS_LINUX_NETWORK
1216  
-  g_windowManager.Add(new CGUIDialogAccessPoints);      // window id = 141
  1235
+    g_windowManager.Add(new CGUIDialogAccessPoints);      // window id = 141
1217 1236
 #endif
1218 1237
 
1219  
-  g_windowManager.Add(new CGUIDialogLockSettings); // window id = 131
  1238
+    g_windowManager.Add(new CGUIDialogLockSettings); // window id = 131
1220 1239
 
1221  
-  g_windowManager.Add(new CGUIDialogContentSettings);        // window id = 132
  1240
+    g_windowManager.Add(new CGUIDialogContentSettings);        // window id = 132
1222 1241
 
1223  
-  g_windowManager.Add(new CGUIDialogPlayEject);
  1242
+    g_windowManager.Add(new CGUIDialogPlayEject);
1224 1243
 
1225  
-  g_windowManager.Add(new CGUIDialogPeripheralManager);
1226  
-  g_windowManager.Add(new CGUIDialogPeripheralSettings);
  1244
+    g_windowManager.Add(new CGUIDialogPeripheralManager);
  1245
+    g_windowManager.Add(new CGUIDialogPeripheralSettings);
1227 1246
 
1228  
-  g_windowManager.Add(new CGUIWindowMusicPlayList);          // window id = 500
1229  
-  g_windowManager.Add(new CGUIWindowMusicSongs);             // window id = 501
1230  
-  g_windowManager.Add(new CGUIWindowMusicNav);               // window id = 502
1231  
-  g_windowManager.Add(new CGUIWindowMusicPlaylistEditor);    // window id = 503
  1247
+    g_windowManager.Add(new CGUIWindowMusicPlayList);          // window id = 500
  1248
+    g_windowManager.Add(new CGUIWindowMusicSongs);             // window id = 501
  1249
+    g_windowManager.Add(new CGUIWindowMusicNav);               // window id = 502
  1250
+    g_windowManager.Add(new CGUIWindowMusicPlaylistEditor);    // window id = 503
1232 1251
 
1233  
-  g_windowManager.Add(new CGUIDialogSelect);             // window id = 2000
1234  
-  g_windowManager.Add(new CGUIDialogMusicInfo);          // window id = 2001
1235  
-  g_windowManager.Add(new CGUIDialogOK);                 // window id = 2002
1236  
-  g_windowManager.Add(new CGUIDialogVideoInfo);          // window id = 2003
1237  
-  g_windowManager.Add(new CGUIDialogTextViewer);
1238  
-  g_windowManager.Add(new CGUIWindowFullScreen);         // window id = 2005
1239  
-  g_windowManager.Add(new CGUIWindowVisualisation);      // window id = 2006
1240  
-  g_windowManager.Add(new CGUIWindowSlideShow);          // window id = 2007
1241  
-  g_windowManager.Add(new CGUIDialogFileStacking);       // window id = 2008
  1252
+    g_windowManager.Add(new CGUIDialogSelect);             // window id = 2000
  1253
+    g_windowManager.Add(new CGUIDialogMusicInfo);          // window id = 2001
  1254
+    g_windowManager.Add(new CGUIDialogOK);                 // window id = 2002
  1255
+    g_windowManager.Add(new CGUIDialogVideoInfo);          // window id = 2003
  1256
+    g_windowManager.Add(new CGUIDialogTextViewer);
  1257
+    g_windowManager.Add(new CGUIWindowFullScreen);         // window id = 2005
  1258
+    g_windowManager.Add(new CGUIWindowVisualisation);      // window id = 2006
  1259
+    g_windowManager.Add(new CGUIWindowSlideShow);          // window id = 2007
  1260
+    g_windowManager.Add(new CGUIDialogFileStacking);       // window id = 2008
1242 1261
 #ifdef HAS_KARAOKE
1243  
-  g_windowManager.Add(new CGUIWindowKaraokeLyrics);      // window id = 2009
  1262
+    g_windowManager.Add(new CGUIWindowKaraokeLyrics);      // window id = 2009
1244 1263
 #endif
1245 1264
 
1246  
-  g_windowManager.Add(new CGUIDialogVideoOSD);           // window id = 2901
1247  
-  g_windowManager.Add(new CGUIDialogMusicOverlay);       // window id = 2903
1248  
-  g_windowManager.Add(new CGUIDialogVideoOverlay);       // window id = 2904
1249  
-  g_windowManager.Add(new CGUIWindowScreensaver);        // window id = 2900 Screensaver
1250  
-  g_windowManager.Add(new CGUIWindowWeather);            // window id = 2600 WEATHER
1251  
-  g_windowManager.Add(new CGUIWindowStartup);            // startup window (id 2999)
  1265
+    g_windowManager.Add(new CGUIDialogVideoOSD);           // window id = 2901
  1266
+    g_windowManager.Add(new CGUIDialogMusicOverlay);       // window id = 2903
  1267
+    g_windowManager.Add(new CGUIDialogVideoOverlay);       // window id = 2904
  1268
+    g_windowManager.Add(new CGUIWindowScreensaver);        // window id = 2900 Screensaver
  1269
+    g_windowManager.Add(new CGUIWindowWeather);            // window id = 2600 WEATHER
  1270
+    g_windowManager.Add(new CGUIWindowStartup);            // startup window (id 2999)
1252 1271
 
1253  
-  /* window id's 3000 - 3100 are reserved for python */
  1272
+    /* window id's 3000 - 3100 are reserved for python */
1254 1273
 
1255  
-  // Make sure we have at least the default skin
1256  
-  if (!LoadSkin(g_guiSettings.GetString("lookandfeel.skin")) && !LoadSkin(DEFAULT_SKIN))
1257  
-  {
1258  
-      CLog::Log(LOGERROR, "Default skin '%s' not found! Terminating..", DEFAULT_SKIN);
1259  
-      FatalErrorHandler(true, true, true);
1260  
-  }
  1274
+    // Make sure we have at least the default skin
  1275
+    if (!LoadSkin(g_guiSettings.GetString("lookandfeel.skin")) && !LoadSkin(DEFAULT_SKIN))
  1276
+    {
  1277
+        CLog::Log(LOGERROR, "Default skin '%s' not found! Terminating..", DEFAULT_SKIN);
  1278
+        FatalErrorHandler(true, true, true);
  1279
+    }
1261 1280
 
1262  
-  if (g_advancedSettings.m_splashImage)
1263  
-    SAFE_DELETE(m_splash);
  1281
+    if (g_advancedSettings.m_splashImage)
  1282
+      SAFE_DELETE(m_splash);
1264 1283
 
1265  
-  if (g_guiSettings.GetBool("masterlock.startuplock") &&
1266  
-      g_settings.GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE &&
1267  
-     !g_settings.GetMasterProfile().getLockCode().IsEmpty())
1268  
-  {
1269  
-     g_passwordManager.CheckStartUpLock();
1270  
-  }
  1284
+    if (g_guiSettings.GetBool("masterlock.startuplock") &&
  1285
+        g_settings.GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE &&
  1286
+       !g_settings.GetMasterProfile().getLockCode().IsEmpty())
  1287
+    {
  1288
+       g_passwordManager.CheckStartUpLock();
  1289
+    }
1271 1290
 
1272  
-  // check if we should use the login screen
1273  
-  if (g_settings.UsingLoginScreen())
1274  
-    g_windowManager.ActivateWindow(WINDOW_LOGIN_SCREEN);
1275  
-  else
  1291
+    // check if we should use the login screen
  1292
+    if (g_settings.UsingLoginScreen())
  1293
+      g_windowManager.ActivateWindow(WINDOW_LOGIN_SCREEN);
  1294
+    else
  1295
+    {
  1296
+#ifdef HAS_JSONRPC
  1297
+      CJSONRPC::Initialize();
  1298
+#endif
  1299
+      ADDON::CAddonMgr::Get().StartServices(false);
  1300
+      g_windowManager.ActivateWindow(g_SkinInfo->GetFirstWindow());
  1301
+    }
  1302
+
  1303
+  }
  1304
+  else //No GUI Created
1276 1305
   {
1277 1306
 #ifdef HAS_JSONRPC
1278 1307
     CJSONRPC::Initialize();
1279 1308
 #endif
1280 1309
     ADDON::CAddonMgr::Get().StartServices(false);
1281  
-    g_windowManager.ActivateWindow(g_SkinInfo->GetFirstWindow());
1282 1310
   }
1283 1311
 
1284 1312
   g_sysinfo.Refresh();
@@ -2718,7 +2746,7 @@ void CApplication::UpdateLCD()
2718 2746
 #endif
2719 2747
 }
2720 2748
 
2721  
-void CApplication::FrameMove(bool processEvents)
  2749
+void CApplication::FrameMove(bool processEvents, bool processGUI)
2722 2750
 {
2723 2751
   MEASURE_FUNCTION;
2724 2752
 
@@ -2730,17 +2758,21 @@ void CApplication::FrameMove(bool processEvents)
2730 2758
     // never set a frametime less than 2 fps to avoid problems when debuggin and on breaks
2731 2759
     if( frameTime > 0.5 ) frameTime = 0.5;
2732 2760
 
2733  
-    g_graphicsContext.Lock();
2734  
-    // check if there are notifications to display
2735  
-    CGUIDialogKaiToast *toast = (CGUIDialogKaiToast *)g_windowManager.GetWindow(WINDOW_DIALOG_KAI_TOAST);
2736  
-    if (toast && toast->DoWork())
  2761
+    if (processGUI)
2737 2762
     {
2738  
-      if (!toast->IsDialogRunning())
  2763
+      g_graphicsContext.Lock();
  2764
+      // check if there are notifications to display
  2765
+      CGUIDialogKaiToast *toast = (CGUIDialogKaiToast *)g_windowManager.GetWindow(WINDOW_DIALOG_KAI_TOAST);
  2766
+      if (toast && toast->DoWork())
2739 2767
       {
2740  
-        toast->Show();
  2768
+        if (!toast->IsDialogRunning())
  2769
+        {
  2770
+          toast->Show();
  2771
+        }
2741 2772
       }
  2773
+      g_graphicsContext.Unlock();
  2774
+      CWinEvents::MessagePump();
2742 2775
     }
2743  
-    g_graphicsContext.Unlock();
2744 2776
 
2745 2777
     UpdateLCD();
2746 2778
 
@@ -2750,18 +2782,21 @@ void CApplication::FrameMove(bool processEvents)
2750 2782
 #endif
2751 2783
 
2752 2784
     // process input actions
2753  
-    CWinEvents::MessagePump();
2754 2785
     ProcessHTTPApiButtons();
2755 2786
     ProcessJsonRpcButtons();
2756 2787
     ProcessRemote(frameTime);
2757 2788
     ProcessGamepad(frameTime);
2758 2789
     ProcessEventServer(frameTime);
2759 2790
     ProcessPeripherals(frameTime);
2760  
-    m_pInertialScrollingHandler->ProcessInertialScroll(frameTime);
  2791
+    if (processGUI)
  2792
+      m_pInertialScrollingHandler->ProcessInertialScroll(frameTime);
  2793
+  }
  2794
+  if (processGUI)
  2795
+  {
  2796
+    if (!m_bStop)
  2797
+      g_windowManager.Process(CTimeUtils::GetFrameTime());
  2798
+    g_windowManager.FrameMove();
2761 2799
   }
2762  
-  if (!m_bStop)
2763  
-    g_windowManager.Process(CTimeUtils::GetFrameTime());
2764  
-  g_windowManager.FrameMove();
2765 2800
 }
2766 2801
 
2767 2802
 bool CApplication::ProcessGamepad(float frameTime)
5  xbmc/Application.h
@@ -111,13 +111,16 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs
111 111
   CApplication(void);
112 112
   virtual ~CApplication(void);
113 113
   virtual bool Initialize();
114  
-  virtual void FrameMove(bool processEvents);
  114
+  virtual void FrameMove(bool processEvents, bool processGUI = true);
115 115
   virtual void Render();
116 116
   virtual bool RenderNoPresent();
117 117
   virtual void Preflight();
118 118
   virtual bool Create();
119 119
   virtual bool Cleanup();
120 120
 
  121
+  bool CreateGUI();
  122
+  bool InitWindow();
  123
+  bool DestroyWindow();
121 124
   void StartServices();
122 125
   void StopServices();
123 126
   bool StartWebServer();
4  xbmc/Makefile.in
@@ -37,6 +37,10 @@ SRCS=Application.cpp \
37 37
 
38 38
 LIB=xbmc.a
39 39
 
  40
+ifneq (@USE_LIBXBMC@,1)
  41
+SRCS += main.cpp
  42
+endif
  43
+
40 44
 DISTCLEAN_FILES=DllPaths_generated.h
41 45
 
42 46
 include @abs_top_srcdir@/Makefile.include
18  xbmc/XBApplicationEx.cpp
@@ -21,6 +21,7 @@
21 21
 #include "system.h"
22 22
 #include "XBApplicationEx.h"
23 23
 #include "utils/log.h"
  24
+#include "threads/SystemClock.h"
24 25
 #ifdef HAS_PERFORMANCE_SAMPLE
25 26
 #include "utils/PerformanceSample.h"
26 27
 #else
@@ -68,13 +69,16 @@ VOID CXBApplicationEx::Destroy()
68 69
 }
69 70
 
70 71
 /* Function that runs the application */
71  
-INT CXBApplicationEx::Run()
  72
+INT CXBApplicationEx::Run(bool renderGUI)
72 73
 {
73 74
   CLog::Log(LOGNOTICE, "Running the application..." );
74 75
 
75 76
   BYTE processExceptionCount = 0;
76 77
   BYTE frameMoveExceptionCount = 0;
77 78
   BYTE renderExceptionCount = 0;
  79
+  unsigned int lastFrameTime = 0;
  80
+  unsigned int frameTime = 0;
  81
+  const unsigned int noRenderFrameTime = 15;  // Simulates ~66fps
78 82
 
79 83
 #ifndef _DEBUG
80 84
   const BYTE MAX_EXCEPTION_COUNT = 10;
@@ -93,6 +97,7 @@ INT CXBApplicationEx::Run()
93 97
     try
94 98
     {
95 99
 #endif
  100
+      lastFrameTime = XbmcThreads::SystemClockMillis();
96 101
       Process();
97 102
       //reset exception count
98 103
       processExceptionCount = 0;
@@ -117,7 +122,7 @@ INT CXBApplicationEx::Run()
117 122
     try
118 123
     {
119 124
 #endif
120  
-      if (!m_bStop) FrameMove(true);
  125
+      if (!m_bStop) FrameMove(true, renderGUI);
121 126
       //reset exception count
122 127
       frameMoveExceptionCount = 0;
123 128
 
@@ -142,7 +147,14 @@ INT CXBApplicationEx::Run()
142 147
     try
143 148
     {
144 149
 #endif
145  
-      if (!m_bStop) Render();
  150
+      if (renderGUI && !m_bStop) Render();
  151
+      else if (!renderGUI)
  152
+      {
  153
+        frameTime = XbmcThreads::SystemClockMillis() - lastFrameTime;
  154
+        if(frameTime < noRenderFrameTime)
  155
+          Sleep(noRenderFrameTime - frameTime);
  156
+      }
  157
+
146 158
       //reset exception count
147 159
       renderExceptionCount = 0;
148 160
 
2  xbmc/XBApplicationEx.h
@@ -50,7 +50,7 @@ class CXBApplicationEx : public IWindowManagerCallback
50 50
 public:
51 51
   // Functions to create, run, and clean up the application
52 52
   virtual bool Create();
53  
-  INT Run();
  53
+  INT Run(bool renderGUI = true);
54 54
   VOID Destroy();
55 55
 
56 56
 private:
2  xbmc/guilib/IWindowManagerCallback.h
@@ -36,7 +36,7 @@ class IWindowManagerCallback
36 36
   IWindowManagerCallback(void);
37 37
   virtual ~IWindowManagerCallback(void);
38 38
 
39  
-  virtual void FrameMove(bool processEvents) = 0;
  39
+  virtual void FrameMove(bool processEvents, bool processGUI = true) = 0;
40 40
   virtual void Render() = 0;
41 41
   virtual void Process() = 0;
42 42
 };
86  xbmc/main.cpp
... ...
@@ -0,0 +1,86 @@
  1
+/*
  2
+ *      Copyright (C) 2005-2008 Team XBMC
  3
+ *      http://www.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 "system.h"
  23
+#include "settings/AppParamParser.h"
  24
+#include "settings/AdvancedSettings.h"
  25
+#include "FileItem.h"
  26
+#include "Application.h"
  27
+#include "PlayListPlayer.h"
  28
+#include "utils/log.h"
  29
+#include "xbmc.h"
  30
+#ifdef _LINUX
  31
+#include <sys/resource.h>
  32
+#include <signal.h>
  33
+#endif
  34
+#if defined(TARGET_DARWIN_OSX)
  35
+  #include "Util.h"
  36
+  // SDL redefines main as SDL_main 
  37
+  #ifdef HAS_SDL
  38
+    #include <SDL/SDL.h>
  39
+  #endif
  40
+#endif
  41
+#ifdef HAS_LIRC
  42
+#include "input/linux/LIRC.h"
  43
+#endif
  44
+#include "XbmcContext.h"
  45
+
  46
+int main(int argc, char* argv[])
  47
+{
  48
+  // set up some xbmc specific relationships
  49
+  XBMC::Context context;
  50
+
  51
+  bool renderGUI = true;
  52
+  //this can't be set from CAdvancedSettings::Initialize() because it will overwrite
  53
+  //the loglevel set with the --debug flag
  54
+#ifdef _DEBUG
  55
+  g_advancedSettings.m_logLevel     = LOG_LEVEL_DEBUG;
  56
+  g_advancedSettings.m_logLevelHint = LOG_LEVEL_DEBUG;
  57
+#else
  58
+  g_advancedSettings.m_logLevel     = LOG_LEVEL_NORMAL;
  59
+  g_advancedSettings.m_logLevelHint = LOG_LEVEL_NORMAL;
  60
+#endif
  61
+  CLog::SetLogLevel(g_advancedSettings.m_logLevel);
  62
+
  63
+#ifdef _LINUX
  64
+#if defined(DEBUG)
  65
+  struct rlimit rlim;
  66
+  rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
  67
+  if (setrlimit(RLIMIT_CORE, &rlim) == -1)
  68
+    CLog::Log(LOGDEBUG, "Failed to set core size limit (%s)", strerror(errno));
  69
+#endif
  70
+  // Prevent child processes from becoming zombies on exit if not waited upon. See also Util::Command
  71
+  struct sigaction sa;
  72
+  memset(&sa, 0, sizeof(sa));
  73
+
  74
+  sa.sa_flags = SA_NOCLDWAIT;
  75
+  sa.sa_handler = SIG_IGN;
  76
+  sigaction(SIGCHLD, &sa, NULL);
  77
+#endif
  78
+  setlocale(LC_NUMERIC, "C");
  79
+  g_advancedSettings.Initialize();
  80
+
  81
+#ifndef _WIN32
  82
+  CAppParamParser appParamParser;
  83
+  appParamParser.Parse((const char **)argv, argc);
  84
+#endif
  85
+  return XBMC_Run(renderGUI);
  86
+}
2  xbmc/settings/AdvancedSettings.cpp
@@ -41,6 +41,7 @@ using namespace XFILE;
41 41
 
42 42
 CAdvancedSettings::CAdvancedSettings()
43 43
 {
  44
+  m_initialized = false;
44 45
 }
45 46
 
46 47
 void CAdvancedSettings::Initialize()
@@ -296,6 +297,7 @@ void CAdvancedSettings::Initialize()
296 297
   m_logEnableAirtunes = false;
297 298
   m_airTunesPort = 36666;
298 299
   m_airPlayPort = 36667;
  300
+  m_initialized = true;
299 301
 }
300 302
 
301 303
 bool CAdvancedSettings::Load()
2  xbmc/settings/AdvancedSettings.h
@@ -80,6 +80,7 @@ class CAdvancedSettings
80 80
     static CAdvancedSettings* getInstance();
81 81
 
82 82
     void Initialize();
  83
+    bool Initialized() { return m_initialized; };
83 84
     void AddSettingsFile(const CStdString &filename);
84 85
     bool Load();
85 86
     void Clear();
@@ -326,6 +327,7 @@ class CAdvancedSettings
326 327
     void ParseSettingsFile(const CStdString &file);
327 328
 
328 329
     float GetDisplayLatency(float refreshrate);
  330
+    bool m_initialized;
329 331
 };
330 332
 
331 333
 XBMC_GLOBAL(CAdvancedSettings,g_advancedSettings);
18  xbmc/win32/XBMC_PC.cpp
@@ -199,7 +199,23 @@ INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT )
199 199
   SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
200 200
 #endif
201 201
 
202  
-  g_application.Run();
  202
+  if (!g_application.CreateGUI())
  203
+  {
  204
+    CStdString errorMsg;
  205
+    errorMsg.Format("CApplication::CreateGUI() failed - Check log file for display errors");
  206
+    MessageBox(NULL, errorMsg.c_str(), "XBMC: Error", MB_OK|MB_ICONERROR);
  207
+    return 0;
  208
+  }
  209
+
  210
+  if (!g_application.Initialize())
  211
+  {
  212
+    CStdString errorMsg;
  213
+    errorMsg.Format("CApplication::Initialize() failed - Check log file and that it is writable");
  214
+    MessageBox(NULL, errorMsg.c_str(), "XBMC: Error", MB_OK|MB_ICONERROR);
  215
+    return 0;
  216
+  }
  217
+
  218
+  g_application.Run(true);
203 219
   
204 220
   // put everything in CApplication::Cleanup() since this point is never reached
205 221
 
82  xbmc/xbmc.cpp
@@ -19,86 +19,34 @@
19 19
  *
20 20
  */
21 21
 
22  
-
23  
-// XBMC
24  
-//
25  
-// libraries:
26  
-//   - CDRipX   : doesnt support section loading yet
27  
-//   - xbfilezilla : doesnt support section loading yet
28  
-//
29  
-
30  
-#include "system.h"
31  
-#include "settings/AppParamParser.h"
32  
-#include "settings/AdvancedSettings.h"
33  
-#include "FileItem.h"
34 22
 #include "Application.h"
35  
-#include "PlayListPlayer.h"
36  
-#include "utils/log.h"
37  
-#ifdef _LINUX
38  
-#include <sys/resource.h>
39  
-#include <signal.h>
40  
-#endif
41  
-#if defined(TARGET_DARWIN_OSX)
42  
-  #include "Util.h"
43  
-  // SDL redefines main as SDL_main 
44  
-  #ifdef HAS_SDL
45  
-    #include <SDL/SDL.h>
46  
-  #endif
47  
-#endif
48  
-#ifdef HAS_LIRC
49  
-#include "input/linux/LIRC.h"
50  
-#endif
51  
-#include "XbmcContext.h"
52  
-
53  
-int main(int argc, char* argv[])
  23
+#include "settings/AdvancedSettings.h"
  24
+extern "C" int XBMC_Run(bool renderGUI)
54 25
 {
55  
-  // set up some xbmc specific relationships
56  
-  XBMC::Context context;
57  
-
58 26
   int status = -1;
59  
-  //this can't be set from CAdvancedSettings::Initialize() because it will overwrite
60  
-  //the loglevel set with the --debug flag
61  
-#ifdef _DEBUG
62  
-  g_advancedSettings.m_logLevel     = LOG_LEVEL_DEBUG;
63  
-  g_advancedSettings.m_logLevelHint = LOG_LEVEL_DEBUG;
64  
-#else
65  
-  g_advancedSettings.m_logLevel     = LOG_LEVEL_NORMAL;
66  
-  g_advancedSettings.m_logLevelHint = LOG_LEVEL_NORMAL;
67  
-#endif
68  
-  CLog::SetLogLevel(g_advancedSettings.m_logLevel);
69 27
 
70  
-#ifdef _LINUX
71  
-#if defined(DEBUG)
72  
-  struct rlimit rlim;
73  
-  rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
74  
-  if (setrlimit(RLIMIT_CORE, &rlim) == -1)
75  
-    CLog::Log(LOGDEBUG, "Failed to set core size limit (%s)", strerror(errno));
76  
-#endif
77  
-  // Prevent child processes from becoming zombies on exit if not waited upon. See also Util::Command
78  
-  struct sigaction sa;
79  
-  memset(&sa, 0, sizeof(sa));
  28
+  if (!g_advancedSettings.Initialized())
  29
+    g_advancedSettings.Initialize();
80 30
 
81  
-  sa.sa_flags = SA_NOCLDWAIT;
82  
-  sa.sa_handler = SIG_IGN;
83  
-  sigaction(SIGCHLD, &sa, NULL);
84  
-#endif
85  
-  setlocale(LC_NUMERIC, "C");
86  
-  g_advancedSettings.Initialize();
87  
-  
88  
-#ifndef _WIN32
89  
-  CAppParamParser appParamParser;
90  
-  appParamParser.Parse((const char **)argv, argc);
91  
-#endif
92  
-  g_application.Preflight();
93 31
   if (!g_application.Create())
94 32
   {
95 33
     fprintf(stderr, "ERROR: Unable to create application. Exiting\n");
96 34
     return status;
97 35
   }
  36
+  if (renderGUI && !g_application.CreateGUI())
  37
+  {
  38
+    fprintf(stderr, "ERROR: Unable to create GUI. Exiting\n");
  39
+    return status;
  40
+  }
  41
+  if (!g_application.Initialize())
  42
+  {
  43
+    fprintf(stderr, "ERROR: Unable to Initialize. Exiting\n");
  44
+    return status;
  45
+  }
98 46
 
99 47
   try
100 48
   {
101  
-    status = g_application.Run();
  49
+    status = g_application.Run(renderGUI);
102 50
   }
103 51
   catch(...)
104 52
   {
23  xbmc/xbmc.h
... ...
@@ -0,0 +1,23 @@