Skip to content
This repository

adding a server/headless mode to xbmc #890

Closed
wants to merge 1 commit into from

10 participants

vajonam jmarshallnz Sascha Montellese Andres Mejia Cory Fields blades David Robins Piethein Strengholt Bas Rieter xbmcfanboy
vajonam
  • re-based with pull instead of merge
  • cleaned up indenting

this allows a headless xbmc, that can be used to keep the DB upto date, when content is added automatically using an internet pvr like sickbeard or couchpotato

jmarshallnz
Owner

Please squash down the commits and take care of any cosmetics (there's a double bracket (indent?) in 379884e.

Am I right that this is essentially a rebase of #542 ?

vajonam

cleaned up rebased and squashed commits.

jmarshall yes that is right this a rebase of #542

Sascha Montellese
Collaborator

First of all there's a lot of bad indentation in these changes. We use 2 spaces (not tabs) per indentation level. Furthermore you should squash the last two commits into the first. And you don't really need to put the URL to a github repo into the commit message as the commit would show up under your name anyway.

On topic I have to say I don't really like this because it's very hacky. After installing XBMC you first need to start it as usual (without the new --server command line option) to be able to configure it. So you'll need to install XBMC onto a machine which actually has a graphics card, an attached monitor etc. Once configured you can either remove the attached monitor etc or you can copy the XBMC installation onto a headless server and then run XBMC with --server there. The only other way I can see is to manually adjust guisettings.xml, which is even more hacky (and you can easily mess up the settings).

IMO that's so far from user-friendly that I can't even see it anymore.

Sascha Montellese Montellese referenced this pull request April 21, 2012
Closed

xbmc server code #542

Andres Mejia
Collaborator

I presume a dedicated XBMC server wouldn't need various configuration settings anyway. Ideally, a server instance of XBMC should be able to run with default settings and without the need of any config file. A local admin can then adjust settings via a config file, say /etc/xbmc/*.

vajonam

I did already squash the code down. into a commit, am not sure why that isn't showing up as one commit. I have also fixed all the indents. again not sure why git hub isn't showing the squashed

regarding the actual code, I agree with most of the comments, except that you don't need a graphics card to install this package, I have tested this on a system without a card. But that being said the current dependencies on an ubuntu include a number of sdl packages.

The main point of this server is to be always available on the network so internet pvrs can notify it of changes and keep the db upto date. or to run periodic updates to keep db upto date for a multi seat install.

there is a lot of hackery in here I agree. What is the suggested approach to keep this moving forward?

Sascha Montellese
Collaborator

@vajonam When I look at the rebased version of e.g. Application.cpp on github I still see a lot of bad indentation. Maybe your editor/IDE hides them from you?
And my comment with the graphics card wasn't meant as "you need a graphics card to install XBMC". I meant that you need to install it on a computer which has a monitor attached (and therefore needs an (internal or external) graphics card), because you need a monitor to view xbmc's GUI to change the settings/set up sources.

@amejia1 Well first of all you need to setup video sources etc because otherwise xbmc won't be of much use to you. This is something everyone must do. Then (at least) I always need to change the settings of the default scraper because they don't match my preferences. You'll also need to setup the corresponding services (upnp, webserver, json-rpc, airplay etc) if you want to be able to access your library from somewhere else. All the other settings that I normally change are GUI related so they won't be needed but at least setting up the sources is absolutely necessary (and probably adjusting the scrapers as well).
Sure this could be done in an extra configuration file but xbmc already has a ton of configuration files so not sure if adding another one is a good call. And it still means that the user needs to manually change a text file. While this is certainly no problem for the more advanced user (and linux user) I am pretty sure that if this hits an official build, everyone will want to try out the new "server mode" and then they end up frustrated because they don't know how to set it up or it's too difficult for them.

vajonam

@Montellese, I use vi and set the tabstop and shiftinden and expandtab and then did a retab and ensured the indents a re okay. If you are mean the if-defs those indents aren't consistent in Application.cpp to being with, I have made them have no indents as per spec in the sections I touched.

@Montellese,@amejia1 assuming that mysql / shared database is used. there is no need for a sources or gui to adjust the scrapers. they can all be done from another headed machine. since all the scraper information is stored in the database anyway. Any additional sources and so on can also be configued from the headed machine again which gets added to the db. the scrapers and scanners all use this rather than the sources.xml anyway!

the only config this server needs its to point to the same mysql database, if it will make this less easy to stumble upon I can change it that the server mode can be set only by editing the advancedsettings.xml this will remove the -s or --server switch. Which would mean for now this would be just for advanced users who are familiar with using the advanced settings file.

as i see it this is what I see as the minimum requirements

  1. atleast 1 XMBC running in full GUI/Headed mode this will be used to configure.
  2. use of MySQL for a shared database
  3. ability to edit / create advancedsettings.xml for the server/headless under the userdata folder

I think this makes sense because. to use MySQL the user modified and edited an advancedsettings.xml anyway even in the headed GUI XBMC instance.

xbmc/Application.cpp
... ...
@@ -625,62 +628,67 @@ bool CApplication::Create()
625 628
   }
626 629
 
627 630
 #ifdef HAS_XRANDR
628  
-  g_xrandr.LoadCustomModeLinesToAllOutputs();
  631
+  if (!g_application.IsServerMode())
  632
+    {
1
Sascha Montellese Collaborator
Montellese added a note April 22, 2012

bad indentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xbmc/Application.cpp
((9 lines not shown))
629 635
 #endif
630 636
 
631 637
   // Init our DllLoaders emu env
632 638
   init_emu_environ();
633 639
 
  640
+  if (!g_application.IsServerMode())
  641
+    { 
1
Sascha Montellese Collaborator
Montellese added a note April 22, 2012

bad indentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xbmc/Application.cpp
((7 lines not shown))
696 705
   {
697  
-    CLog::Log(LOGFATAL, "CApplication::Create: Unable to init windowing system");
698  
-    return false;
  706
+   if (!g_Windowing.InitWindowSystem())
  707
+    {
1
Sascha Montellese Collaborator
Montellese added a note April 22, 2012

bad indentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xbmc/Application.cpp
((30 lines not shown))
763 782
 #if defined(__APPLE__) && !defined(__arm__)
764 783
   // Configure and possible manually start the helper.
765 784
   XBMCHelper::GetInstance().Configure();
766 785
 #endif
  786
+  if (!g_application.IsServerMode())
  787
+   {
1
Sascha Montellese Collaborator
Montellese added a note April 22, 2012

bad indentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Sascha Montellese
Collaborator

Just to show you what I mean I picked out a few places with bad indentation. I didn't bother to mark them all because they are pretty obvious when looking at the diff off this PR here on github.

vajonam

@Montellese thats for pointing those out, stopped seeing them after seeing the patch for so long.. but doesn't look like this PR is going too far based on the discussion thus far?

Sascha Montellese
Collaborator

@vajonam I know that feeling when you have seen some code for too long ;-)

What I stated above is just my personal opinion. Considering that I neither have multiple XBMC installations nor use MySQL I'm not really your target audience anyway.

Cory Fields
Owner

I'm really not sure that this is the way to go here. Compare to #214

With a headless xbmc, you don't get much. But by using xbmc as a lib and being able to create a server around it, you could add lots of functionality that we would never want in mainline.

vajonam

interesting, if this is path that we want to take, I can offer to code something but will need some help / direction I am just bit of hacker when it comes to XBMC i am afraid, enough to be dangerous!

what will be needed to achieve the following?

  • a server that listens exposing the http-api or jsonrpc api
  • updates a mysql db by running the scan and updating content.

wont this almost duplicate a lot of code that is already written in xbmc?

Cory Fields
Owner

well, the idea would be to start breaking breaking stuff out of Application.cpp and into a "services" class.

So then you would have an application that includes xbmc's "services" header, starts those services, then does whatever else it needs to do. So there would be no duplication, it would be running the same code as the desktop binary.

I'm not opposed to the headless idea, but it does seem to conflict with the notion of having a libxbmc for similar functionality. So I just want to be sure we think it through before going either route.

Cory Fields
Owner

I've pushed a branch that's updated for master. I'll get it cleaned up and working this week.

https://github.com/theuni/xbmc/tree/shared-lib

blades

@theuni going down the lib route is definitely the preferred long-term solution to this. however, that's a long-term solution as opposed to something available right now, and on top of that there wasn't much interest in making that happen right at this moment in time. the original pull request i created was a quick hack to get something available with the bare minimum of changes such that we could have a working server mode available here and now that wasn't going to need a massive re-architecting of the mainline codebase. i fully agree that it's not the ideal solution, but it works, and it's available now with only a few minor changes to the mainline codebase that don't impact anything else.

ultimately, so long as there's a server mode, that's the important thing. people have been begging for this for a very, very long time, and i saw a simple and quick way of getting it working. personally, i don't particularly care how it's done, just that it is done. this was within my abilities; shared libraries and building an entirely new server application to use them isn't.

Cory Fields
Owner

Well it's not an issue of getting it done, clearly the headless approach works. The issue is that once it goes in we have to support it. And indeed a server-mode is a big deal. Think of all the new-functionality requests we'll get and have to add to xbmc, for a short-term solution.

But rather than stalling for the future's sake, I'm working on getting something done up that resembles the current functionality here, but done in a lib-way.

Cory Fields
Owner

Additionally, looking closer at the changes here...

Most of the things that are special-cased for server mode should instead just not be compiled in. For ex, X, SDL, peripherals, etc.. Otherwise we still end up with tons of deps.. unsuitable for installing in places where this would be the most helpful.

Cory Fields
Owner

Ok, I've pushed some changes that do this using xbmc as a lib, while keeping the spirit of this PR. See my branch here: https://github.com/theuni/xbmc/tree/shared-lib

At the moment, it basically functions as @vajonam's headless binary would. The difference is that it is actually only a tiny stub application, that calls into libxbmc and blocks there. See here: https://github.com/theuni/xbmc/blob/shared-lib/xbmc/xbmc_headless.cpp for the example.

So it's very uninteresting in its current form. But. If we go this route, we can begin splitting things out into more reasonable chunks. For example, you may want a binary that does nothing more than serves XBMC's webinterface. In that case, a huge chunk of system libs could be removed, leaving you with a clean unit-testable application, or functional server.

The work isn't too bad, it mainly entails pulling Application::Create() and Application::Initialize apart and exposing the bits that start services to xbmc.h. Then, it would be dead-simple to create an application that just starts a few of our services and waits.

I think this also lends itself towards @jimfcarroll's world-domination plans, as iirc he was looking to nuke CApplication altogether.

Cory Fields
Owner

Most credit for the above belongs to @dbrobins btw. I'll be sure to mention that in the commits if we go this way.

David Robins

Thanks. It would be great if the shared lib/headless changes finally made make it in in some form. :)

Piethein Strengholt
Collaborator

Maybe just an idea.. Can't we ask Alasdair Campbell to have a look at this as well? He's Google Summer project is all about XBMC serving content by UPnP / DLNA. Would be nice to see a headless xbmc server serving content to other (xbmc) clients.

blades

@theuni the only downside is that you've now got a separate application: it's not a server-mode within xbmc, but instead an entirely new application using a shared library. to be honest, that's not even remotely a problem, but it's not something that i had the temerity to suggest with my changes :p

my only intention with this was to provide a quick-win that could be in use, and indeed it's been in use for the last few months with a hardcore bunch who were happy to compile it for themselves on the original thread here: http://forum.xbmc.org/showthread.php?tid=114612

now that there's a better solution that does this properly, i'd much rather see this brought up to a usable state instead. yeah, i'm a little gutted that i don't end up actually contributing to the project, but i can console myself with the thought that i've poked and prodded it enough to get an xbmc server onto the radar!

to be honest, it'll be nice not to have to be constantly defending the approach i took with this, too. all i wanted was a quick win to give the dev team space to do it properly while giving those who wanted a server mode something usable to play with.

anyway. what needs to be done from here to get your new branch into a state whereby i can give the thread something to use? how would i go about running your headless version?

Cory Fields
Owner

Wow, what a helpful response. You know we're supposed to be nerds with monstrous egos, right? :p

Here's how this really went. I have been meaning to get the lib concept into shape for quite a while. You guys came along with something that conflicted with it, so I had no choice but to do my part or shut up and let it go a different direction. So in that way, you definitely got things rolling.

All I've done so far is to get things building in a way that facilitates running headless. I created a stub app (xbmc_headless.bin) and verified that it runs the webserver.

The todo's mainly look like this:

  • Verify that the reorg in Application.cpp didn't break anything in the desktop usage of XBMC. @jmarshallnz had some valid concerns. This needs to happen first as we can't pull it in if it's breaking stuff.

  • Verify that server stuff actually works. There are bound to be some things that rely on the GUI being present. I don't know how to find these problems other than just hitting them during use.

  • Begin breaking things out into xbmc.h. Again, the hope is that run_xbmc() could go away, and the headless app could just launch individual services instead.

I could use some help with all of the above. I'd guess that the third probably won't be done until it hits mainline.

To help, just merge my branch, commit with --enable-shared-lib on or off, and start hacking.

I suppose I'll do some github cleanup. Will close this PR as well as the other, and do mine as an RFC. That will make it easier to discuss.

Thanks for the help!

vajonam

@theuni where do you want feedback about bugs? forum or here?

blades

well, i've got an ego somewhere around here if there's one missing :p

i have to admit, i know very, very little about C++. however, there's never a bad time to learn some new skills! i may need a little help to get things moving, though - is there a better way to communicate with you than via here? i'm happy to pass over my email address to you to take this off here, for example...

as to gui reliance, we did find a few bits for database updates (http://forum.xbmc.org/showthread.php?tid=114612&pid=985613#pid985613):

"You have to allow creation of two windows in Application.cpp:

  • g_windowManager.Add(new CGUIDialogMusicScan);
  • g_windowManager.Add(new CGUIDialogVideoScan);"

i also disabled some functionality in the builtins class when running as a server, just to be on the safe side, too.

Bas Rieter

Wow! I really appreciate that this is being picked up and supported by the XBMC team! Nice.

Would it be a good idea to start a central topic on this headless version on the XBMC forums so we can discuss builds, bugs and features there?

I myself an not a very skilled c++ coder. I did however created a tiny service addon that allows a user to schedule Video and Music backups on a daily basis. As soon as this headless server is official it might be a nice addition?

xbmcfanboy

@theuni I would like to help. Can you give more information about "commit with --enable-shared-lib on or off" please.

Cory Fields
Owner

@xbmcfanboy what OS are you running? I meant ./configure with --enable-shared-lib

I will need to discuss with the others, but I'd be ok with merging this in as soon as we could verify that the current functionality works as intended without breaking mainline. It's obviously a popular feature.

@blades: Thanks, I'll have a look at those. I'd much rather remove those dependencies on the gui than work around them, but I'm not sure what work is involved there yet.

@vajonam forum probably makes the most sense.

Cory Fields
Owner
theuni commented May 01, 2012

I've taken a stab at fixing the scan+gui dependency here: #916. That will mean we won't need those hacks for allowing certain windows to be created. As I mentioned above, I'd prefer to fix any of those dependencies rather than just working around them.

Once we get that into mainline (assuming it works!), I'll rebase my lib work and do a new PR. We can begin testing/discussing then.

Cory Fields
Owner
theuni commented June 05, 2012

Closing this in favor of #1049

Cory Fields theuni closed this June 05, 2012
Cory Fields theuni referenced this pull request June 12, 2012
Merged

Build Shared Lib #1049

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Apr 22, 2012
vajonam XBMC Server modifications 029022d
This page is out of date. Refresh to see the latest.
502  xbmc/Application.cpp
@@ -395,6 +395,7 @@ CApplication::CApplication(void)
395 395
   m_bPlatformDirectories = true;
396 396
 
397 397
   m_bStandalone = false;
  398
+  m_bServerMode = false;
398 399
   m_bEnableLegacyRes = false;
399 400
   m_bSystemScreenSaverEnable = false;
400 401
   m_pInertialScrollingHandler = new CInertialScrollingHandler();
@@ -539,8 +540,10 @@ void CApplication::Preflight()
539 540
 bool CApplication::Create()
540 541
 {
541 542
   g_settings.Initialize(); //Initialize default AdvancedSettings
542  
-
543  
-  m_bSystemScreenSaverEnable = g_Windowing.IsSystemScreenSaverEnabled();
  543
+  if (!g_application.IsServerMode())
  544
+  {
  545
+    m_bSystemScreenSaverEnable = g_Windowing.IsSystemScreenSaverEnabled();
  546
+  }
544 547
   g_Windowing.EnableSystemScreenSaver(false);
545 548
 
546 549
 #ifdef _LINUX
@@ -625,62 +628,67 @@ bool CApplication::Create()
625 628
   }
626 629
 
627 630
 #ifdef HAS_XRANDR
628  
-  g_xrandr.LoadCustomModeLinesToAllOutputs();
  631
+  if (!g_application.IsServerMode())
  632
+  {
  633
+    g_xrandr.LoadCustomModeLinesToAllOutputs();
  634
+  }
629 635
 #endif
630 636
 
631 637
   // Init our DllLoaders emu env
632 638
   init_emu_environ();
633 639
 
  640
+  if (!g_application.IsServerMode())
  641
+  { 
634 642
 
635 643
 #ifdef HAS_SDL
636  
-  CLog::Log(LOGNOTICE, "Setup SDL");
  644
+    CLog::Log(LOGNOTICE, "Setup SDL");
637 645
 
638  
-  /* Clean up on exit, exit on window close and interrupt */
639  
-  atexit(SDL_Quit);
  646
+    /* Clean up on exit, exit on window close and interrupt */
  647
+    atexit(SDL_Quit);
640 648
 
641  
-  uint32_t sdlFlags = 0;
  649
+    uint32_t sdlFlags = 0;
642 650
 
643 651
 #if defined(HAS_SDL_OPENGL) || (HAS_GLES == 2)
644  
-  sdlFlags |= SDL_INIT_VIDEO;
  652
+    sdlFlags |= SDL_INIT_VIDEO;
645 653
 #endif
646 654
 
647 655
 #ifdef HAS_SDL_AUDIO
648  
-  sdlFlags |= SDL_INIT_AUDIO;
  656
+    sdlFlags |= SDL_INIT_AUDIO;
649 657
 #endif
650 658
 
651 659
 #ifdef HAS_SDL_JOYSTICK
652  
-  sdlFlags |= SDL_INIT_JOYSTICK;
  660
+    sdlFlags |= SDL_INIT_JOYSTICK;
653 661
 #endif
654 662
 
655  
-  //depending on how it's compiled, SDL periodically calls XResetScreenSaver when it's fullscreen
656  
-  //this might bring the monitor out of standby, so we have to disable it explicitly
657  
-  //by passing 0 for overwrite to setsenv, the user can still override this by setting the environment variable
  663
+    //depending on how it's compiled, SDL periodically calls XResetScreenSaver when it's fullscreen
  664
+    //this might bring the monitor out of standby, so we have to disable it explicitly
  665
+    //by passing 0 for overwrite to setsenv, the user can still override this by setting the environment variable
658 666
 #if defined(_LINUX) && !defined(__APPLE__)
659  
-  setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0);
  667
+    setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0);
660 668
 #endif
661 669
 
662 670
 #endif // HAS_SDL
663 671
 
664 672
 #ifdef _LINUX
665  
-  // for nvidia cards - vsync currently ALWAYS enabled.
666  
-  // the reason is that after screen has been setup changing this env var will make no difference.
667  
-  setenv("__GL_SYNC_TO_VBLANK", "1", 0);
668  
-  setenv("__GL_YIELD", "USLEEP", 0);
  673
+    // for nvidia cards - vsync currently ALWAYS enabled.
  674
+    // the reason is that after screen has been setup changing this env var will make no difference.
  675
+    setenv("__GL_SYNC_TO_VBLANK", "1", 0);
  676
+    setenv("__GL_YIELD", "USLEEP", 0);
669 677
 #endif
670 678
 
671 679
 #ifdef HAS_SDL
672  
-  if (SDL_Init(sdlFlags) != 0)
673  
-  {
674  
-    CLog::Log(LOGFATAL, "XBAppEx: Unable to initialize SDL: %s", SDL_GetError());
675  
-    return false;
676  
-  }
677  
-  #if defined(TARGET_DARWIN)
678  
-  // SDL_Init will install a handler for segfaults, restore the default handler.
679  
-  signal(SIGSEGV, SIG_DFL);
680  
-  #endif
  680
+    if (SDL_Init(sdlFlags) != 0)
  681
+    {
  682
+      CLog::Log(LOGFATAL, "XBAppEx: Unable to initialize SDL: %s", SDL_GetError());
  683
+      return false;
  684
+    }
  685
+#if defined(TARGET_DARWIN)
  686
+    // SDL_Init will install a handler for segfaults, restore the default handler.
  687
+    signal(SIGSEGV, SIG_DFL);
681 688
 #endif
682  
-
683  
-  // for python scripts that check the OS
  689
+#endif
  690
+  }
  691
+// for python scripts that check the OS
684 692
 #ifdef __APPLE__
685 693
   setenv("OS","OS X",true);
686 694
 #elif defined(_LINUX)
@@ -692,12 +700,15 @@ bool CApplication::Create()
692 700
   // Initialize core peripheral port support. Note: If these parameters
693 701
   // are 0 and NULL, respectively, then the default number and types of
694 702
   // controllers will be initialized.
695  
-  if (!g_Windowing.InitWindowSystem())
  703
+  
  704
+  if (!g_application.IsServerMode())
696 705
   {
697  
-    CLog::Log(LOGFATAL, "CApplication::Create: Unable to init windowing system");
698  
-    return false;
  706
+    if (!g_Windowing.InitWindowSystem())
  707
+    {
  708
+      CLog::Log(LOGFATAL, "CApplication::Create: Unable to init windowing system");
  709
+      return false;
  710
+    }
699 711
   }
700  
-
701 712
   g_powerManager.Initialize();
702 713
 
703 714
   CLog::Log(LOGNOTICE, "load settings...");
@@ -709,13 +720,19 @@ bool CApplication::Create()
709 720
 
710 721
   CLog::Log(LOGINFO, "creating subdirectories");
711 722
   CLog::Log(LOGINFO, "userdata folder: %s", g_settings.GetProfileUserDataFolder().c_str());
712  
-  CLog::Log(LOGINFO, "recording folder: %s", g_guiSettings.GetString("audiocds.recordingpath",false).c_str());
713  
-  CLog::Log(LOGINFO, "screenshots folder: %s", g_guiSettings.GetString("debug.screenshotpath",false).c_str());
  723
+  if (!g_application.IsServerMode())
  724
+  {
  725
+    CLog::Log(LOGINFO, "recording folder: %s", g_guiSettings.GetString("audiocds.recordingpath",false).c_str());
  726
+    CLog::Log(LOGINFO, "screenshots folder: %s", g_guiSettings.GetString("debug.screenshotpath",false).c_str());
  727
+  }
714 728
   CDirectory::Create(g_settings.GetUserDataFolder());
715 729
   CDirectory::Create(g_settings.GetProfileUserDataFolder());
716 730
   g_settings.CreateProfileFolders();
717 731
 
718  
-  update_emu_environ();//apply the GUI settings
  732
+  if (!g_application.IsServerMode())
  733
+  {
  734
+    update_emu_environ();//apply the GUI settings
  735
+  }
719 736
 
720 737
   // initialize our charset converter
721 738
   g_charsetConverter.reset();
@@ -745,94 +762,97 @@ bool CApplication::Create()
745 762
     FatalErrorHandler(true, true, true);
746 763
   }
747 764
 
748  
-  g_peripherals.Initialise();
  765
+  if (!g_application.IsServerMode())
  766
+  {
  767
+    g_peripherals.Initialise();
749 768
 
750  
-  // Create the Mouse, Keyboard, Remote, and Joystick devices
751  
-  // Initialize after loading settings to get joystick deadzone setting
752  
-  g_Mouse.Initialize();
753  
-  g_Mouse.SetEnabled(g_guiSettings.GetBool("input.enablemouse"));
  769
+    // Create the Mouse, Keyboard, Remote, and Joystick devices
  770
+    // Initialize after loading settings to get joystick deadzone setting
  771
+    g_Mouse.Initialize();
  772
+    g_Mouse.SetEnabled(g_guiSettings.GetBool("input.enablemouse"));
754 773
 
755  
-  g_Keyboard.Initialize();
  774
+    g_Keyboard.Initialize();
756 775
 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
757  
-  g_RemoteControl.Initialize();
  776
+    g_RemoteControl.Initialize();
758 777
 #endif
759 778
 #ifdef HAS_SDL_JOYSTICK
760  
-  g_Joystick.Initialize();
  779
+    g_Joystick.Initialize();
761 780
 #endif
762  
-
  781
+  } 
763 782
 #if defined(__APPLE__) && !defined(__arm__)
764 783
   // Configure and possible manually start the helper.
765 784
   XBMCHelper::GetInstance().Configure();
766 785
 #endif
  786
+  if (!g_application.IsServerMode())
  787
+  {
  788
+    // update the window resolution
  789
+    g_Windowing.SetWindowResolution(g_guiSettings.GetInt("window.width"), g_guiSettings.GetInt("window.height"));
767 790
 
768  
-  // update the window resolution
769  
-  g_Windowing.SetWindowResolution(g_guiSettings.GetInt("window.width"), g_guiSettings.GetInt("window.height"));
770  
-
771  
-  if (g_advancedSettings.m_startFullScreen && g_guiSettings.m_LookAndFeelResolution == RES_WINDOW)
772  
-    g_guiSettings.m_LookAndFeelResolution = RES_DESKTOP;
  791
+    if (g_advancedSettings.m_startFullScreen && g_guiSettings.m_LookAndFeelResolution == RES_WINDOW)
  792
+      g_guiSettings.m_LookAndFeelResolution = RES_DESKTOP;
773 793
 
774  
-  if (!g_graphicsContext.IsValidResolution(g_guiSettings.m_LookAndFeelResolution))
775  
-  {
776  
-    // Oh uh - doesn't look good for starting in their wanted screenmode
777  
-    CLog::Log(LOGERROR, "The screen resolution requested is not valid, resetting to a valid mode");
778  
-    g_guiSettings.m_LookAndFeelResolution = RES_DESKTOP;
779  
-  }
  794
+    if (!g_graphicsContext.IsValidResolution(g_guiSettings.m_LookAndFeelResolution))
  795
+    {
  796
+      // Oh uh - doesn't look good for starting in their wanted screenmode
  797
+      CLog::Log(LOGERROR, "The screen resolution requested is not valid, resetting to a valid mode");
  798
+      g_guiSettings.m_LookAndFeelResolution = RES_DESKTOP;
  799
+    }
780 800
 
781 801
 #ifdef TARGET_DARWIN_OSX
782  
-  // force initial window creation to be windowed, if fullscreen, it will switch to it below
783  
-  // fixes the white screen of death if starting fullscreen and switching to windowed.
784  
-  bool bFullScreen = false;
785  
-  if (!g_Windowing.CreateNewWindow("XBMC", bFullScreen, g_settings.m_ResInfo[RES_WINDOW], OnEvent))
786  
-  {
787  
-    CLog::Log(LOGFATAL, "CApplication::Create: Unable to create window");
788  
-    return false;
789  
-  }
  802
+    // force initial window creation to be windowed, if fullscreen, it will switch to it below
  803
+    // fixes the white screen of death if starting fullscreen and switching to windowed.
  804
+    bool bFullScreen = false;
  805
+    if (!g_Windowing.CreateNewWindow("XBMC", bFullScreen, g_settings.m_ResInfo[RES_WINDOW], OnEvent))
  806
+    {
  807
+      CLog::Log(LOGFATAL, "CApplication::Create: Unable to create window");
  808
+      return false;
  809
+    }
790 810
 #else
791  
-  bool bFullScreen = g_guiSettings.m_LookAndFeelResolution != RES_WINDOW;
792  
-  if (!g_Windowing.CreateNewWindow("XBMC", bFullScreen, g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution], OnEvent))
793  
-  {
794  
-    CLog::Log(LOGFATAL, "CApplication::Create: Unable to create window");
795  
-    return false;
796  
-  }
  811
+    bool bFullScreen = g_guiSettings.m_LookAndFeelResolution != RES_WINDOW;
  812
+    if (!g_Windowing.CreateNewWindow("XBMC", bFullScreen, g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution], OnEvent))
  813
+    {
  814
+      CLog::Log(LOGFATAL, "CApplication::Create: Unable to create window");
  815
+      return false;
  816
+    }
797 817
 #endif
798 818
 
799  
-  if (!g_Windowing.InitRenderSystem())
800  
-  {
801  
-    CLog::Log(LOGFATAL, "CApplication::Create: Unable to init rendering system");
802  
-    return false;
803  
-  }
804  
-
805  
-  // set GUI res and force the clear of the screen
806  
-  g_graphicsContext.SetVideoResolution(g_guiSettings.m_LookAndFeelResolution);
807  
-
808  
-  if (g_advancedSettings.m_splashImage)
809  
-  {
810  
-    CStdString strUserSplash = "special://home/media/Splash.png";
811  
-    if (CFile::Exists(strUserSplash))
  819
+    if (!g_Windowing.InitRenderSystem())
812 820
     {
813  
-      CLog::Log(LOGINFO, "load user splash image: %s", CSpecialProtocol::TranslatePath(strUserSplash).c_str());
814  
-      m_splash = new CSplash(strUserSplash);
  821
+      CLog::Log(LOGFATAL, "CApplication::Create: Unable to init rendering system");
  822
+      return false;
815 823
     }
816  
-    else
  824
+
  825
+    // set GUI res and force the clear of the screen
  826
+    g_graphicsContext.SetVideoResolution(g_guiSettings.m_LookAndFeelResolution);
  827
+
  828
+    if (g_advancedSettings.m_splashImage)
817 829
     {
818  
-      CLog::Log(LOGINFO, "load default splash image: %s", CSpecialProtocol::TranslatePath("special://xbmc/media/Splash.png").c_str());
819  
-      m_splash = new CSplash("special://xbmc/media/Splash.png");
820  
-    }
821  
-    m_splash->Show();
822  
-  }
  830
+      CStdString strUserSplash = "special://home/media/Splash.png";
  831
+      if (CFile::Exists(strUserSplash))
  832
+      {
  833
+        CLog::Log(LOGINFO, "load user splash image: %s", CSpecialProtocol::TranslatePath(strUserSplash).c_str());
  834
+        m_splash = new CSplash(strUserSplash);
  835
+      }
  836
+      else
  837
+      {
  838
+        CLog::Log(LOGINFO, "load default splash image: %s", CSpecialProtocol::TranslatePath("special://xbmc/media/Splash.png").c_str());
  839
+        m_splash = new CSplash("special://xbmc/media/Splash.png");
  840
+      }
  841
+      m_splash->Show();
  842
+    }     
823 843
 
824  
-  // The key mappings may already have been loaded by a peripheral
825  
-  CLog::Log(LOGINFO, "load keymapping");
826  
-  if (!CButtonTranslator::GetInstance().Load())
  844
+    // The key mappings may already have been loaded by a peripheral
  845
+    CLog::Log(LOGINFO, "load keymapping");
  846
+    if (!CButtonTranslator::GetInstance().Load())
827 847
       FatalErrorHandler(false, false, true);
828 848
 
829  
-  int iResolution = g_graphicsContext.GetVideoResolution();
830  
-  CLog::Log(LOGINFO, "GUI format %ix%i %s",
831  
-            g_settings.m_ResInfo[iResolution].iWidth,
832  
-            g_settings.m_ResInfo[iResolution].iHeight,
833  
-            g_settings.m_ResInfo[iResolution].strMode.c_str());
834  
-  g_windowManager.Initialize();
835  
-
  849
+    int iResolution = g_graphicsContext.GetVideoResolution();
  850
+    CLog::Log(LOGINFO, "GUI format %ix%i %s",
  851
+    g_settings.m_ResInfo[iResolution].iWidth,
  852
+    g_settings.m_ResInfo[iResolution].iHeight,
  853
+    g_settings.m_ResInfo[iResolution].strMode.c_str());
  854
+    g_windowManager.Initialize();
  855
+  }
836 856
   CUtil::InitRandomSeed();
837 857
 
838 858
   g_mediaManager.Initialize();
@@ -1120,135 +1140,151 @@ bool CApplication::Initialize()
1120 1140
 
1121 1141
   // Init DPMS, before creating the corresponding setting control.
1122 1142
   m_dpms = new DPMSSupport();
1123  
-  g_guiSettings.GetSetting("powermanagement.displaysoff")->SetVisible(m_dpms->IsSupported());
1124  
-
1125  
-  g_windowManager.Add(new CGUIWindowHome);                     // window id = 0
1126  
-  g_windowManager.Add(new CGUIWindowPrograms);                 // window id = 1
1127  
-  g_windowManager.Add(new CGUIWindowPictures);                 // window id = 2
1128  
-  g_windowManager.Add(new CGUIWindowFileManager);      // window id = 3
1129  
-  g_windowManager.Add(new CGUIWindowSettings);                 // window id = 4
1130  
-  g_windowManager.Add(new CGUIWindowSystemInfo);               // window id = 7
  1143
+  if (!g_application.IsServerMode())
  1144
+  {
  1145
+    g_guiSettings.GetSetting("powermanagement.displaysoff")->SetVisible(m_dpms->IsSupported());
  1146
+
  1147
+    g_windowManager.Add(new CGUIWindowHome);                     // window id = 0
  1148
+    g_windowManager.Add(new CGUIWindowPrograms);                 // window id = 1
  1149
+    g_windowManager.Add(new CGUIWindowPictures);                 // window id = 2
  1150
+    g_windowManager.Add(new CGUIWindowFileManager);      // window id = 3
  1151
+    g_windowManager.Add(new CGUIWindowSettings);                 // window id = 4
  1152
+    g_windowManager.Add(new CGUIWindowSystemInfo);               // window id = 7
1131 1153
 #ifdef HAS_GL
1132  
-  g_windowManager.Add(new CGUIWindowTestPatternGL);      // window id = 8
  1154
+    g_windowManager.Add(new CGUIWindowTestPatternGL);      // window id = 8
1133 1155
 #endif
1134 1156
 #ifdef HAS_DX
1135  
-  g_windowManager.Add(new CGUIWindowTestPatternDX);      // window id = 8
1136  
-#endif
1137  
-  g_windowManager.Add(new CGUIDialogTeletext);               // window id =
1138  
-  g_windowManager.Add(new CGUIWindowSettingsScreenCalibration); // window id = 11
1139  
-  g_windowManager.Add(new CGUIWindowSettingsCategory);         // window id = 12 slideshow:window id 2007
1140  
-  g_windowManager.Add(new CGUIWindowVideoNav);                 // window id = 36
1141  
-  g_windowManager.Add(new CGUIWindowVideoPlaylist);            // window id = 28
1142  
-  g_windowManager.Add(new CGUIWindowLoginScreen);            // window id = 29
1143  
-  g_windowManager.Add(new CGUIWindowSettingsProfile);          // window id = 34
1144  
-  g_windowManager.Add(new CGUIWindowAddonBrowser);          // window id = 40
1145  
-  g_windowManager.Add(new CGUIWindowScreensaverDim);            // window id = 97  
1146  
-  g_windowManager.Add(new CGUIWindowDebugInfo);            // window id = 98
1147  
-  g_windowManager.Add(new CGUIWindowPointer);            // window id = 99
1148  
-  g_windowManager.Add(new CGUIDialogYesNo);              // window id = 100
1149  
-  g_windowManager.Add(new CGUIDialogProgress);           // window id = 101
1150  
-  g_windowManager.Add(new CGUIDialogKeyboard);           // window id = 103
1151  
-  g_windowManager.Add(new CGUIDialogVolumeBar);          // window id = 104
1152  
-  g_windowManager.Add(new CGUIDialogSeekBar);            // window id = 115
1153  
-  g_windowManager.Add(new CGUIDialogSubMenu);            // window id = 105
1154  
-  g_windowManager.Add(new CGUIDialogContextMenu);        // window id = 106
1155  
-  g_windowManager.Add(new CGUIDialogKaiToast);           // window id = 107
1156  
-  g_windowManager.Add(new CGUIDialogNumeric);            // window id = 109
1157  
-  g_windowManager.Add(new CGUIDialogGamepad);            // window id = 110
1158  
-  g_windowManager.Add(new CGUIDialogButtonMenu);         // window id = 111
  1157
+    g_windowManager.Add(new CGUIWindowTestPatternDX);      // window id = 8
  1158
+#endif
  1159
+    g_windowManager.Add(new CGUIDialogTeletext);               // window id =
  1160
+    g_windowManager.Add(new CGUIWindowSettingsScreenCalibration); // window id = 11
  1161
+    g_windowManager.Add(new CGUIWindowSettingsCategory);         // window id = 12 slideshow:window id 2007
  1162
+    g_windowManager.Add(new CGUIWindowVideoNav);                 // window id = 36
  1163
+    g_windowManager.Add(new CGUIWindowVideoPlaylist);            // window id = 28
  1164
+    g_windowManager.Add(new CGUIWindowLoginScreen);            // window id = 29
  1165
+    g_windowManager.Add(new CGUIWindowSettingsProfile);          // window id = 34
  1166
+    g_windowManager.Add(new CGUIWindowAddonBrowser);          // window id = 40
  1167
+    g_windowManager.Add(new CGUIWindowScreensaverDim);            // window id = 97  
  1168
+    g_windowManager.Add(new CGUIWindowDebugInfo);            // window id = 98
  1169
+    g_windowManager.Add(new CGUIWindowPointer);            // window id = 99
  1170
+    g_windowManager.Add(new CGUIDialogYesNo);              // window id = 100
  1171
+    g_windowManager.Add(new CGUIDialogProgress);           // window id = 101
  1172
+    g_windowManager.Add(new CGUIDialogKeyboard);           // window id = 103
  1173
+    g_windowManager.Add(new CGUIDialogVolumeBar);          // window id = 104
  1174
+    g_windowManager.Add(new CGUIDialogSeekBar);            // window id = 115
  1175
+    g_windowManager.Add(new CGUIDialogSubMenu);            // window id = 105
  1176
+    g_windowManager.Add(new CGUIDialogContextMenu);        // window id = 106
  1177
+    g_windowManager.Add(new CGUIDialogKaiToast);           // window id = 107
  1178
+    g_windowManager.Add(new CGUIDialogNumeric);            // window id = 109
  1179
+    g_windowManager.Add(new CGUIDialogGamepad);            // window id = 110
  1180
+    g_windowManager.Add(new CGUIDialogButtonMenu);         // window id = 111
  1181
+  }
1159 1182
   g_windowManager.Add(new CGUIDialogMusicScan);          // window id = 112
1160  
-  g_windowManager.Add(new CGUIDialogMuteBug);            // window id = 113
1161  
-  g_windowManager.Add(new CGUIDialogPlayerControls);     // window id = 114
  1183
+  if (!g_application.IsServerMode())
  1184
+  { 
  1185
+    g_windowManager.Add(new CGUIDialogMuteBug);            // window id = 113
  1186
+    g_windowManager.Add(new CGUIDialogPlayerControls);     // window id = 114
1162 1187
 #ifdef HAS_KARAOKE
1163  
-  g_windowManager.Add(new CGUIDialogKaraokeSongSelectorSmall); // window id 143
1164  
-  g_windowManager.Add(new CGUIDialogKaraokeSongSelectorLarge); // window id 144
1165  
-#endif
1166  
-  g_windowManager.Add(new CGUIDialogSlider);             // window id = 145
1167  
-  g_windowManager.Add(new CGUIDialogMusicOSD);           // window id = 120
1168  
-  g_windowManager.Add(new CGUIDialogVisualisationPresetList);   // window id = 122
1169  
-  g_windowManager.Add(new CGUIDialogVideoSettings);             // window id = 123
1170  
-  g_windowManager.Add(new CGUIDialogAudioSubtitleSettings);     // window id = 124
1171  
-  g_windowManager.Add(new CGUIDialogVideoBookmarks);      // window id = 125
1172  
-  // Don't add the filebrowser dialog - it's created and added when it's needed
1173  
-  g_windowManager.Add(new CGUIDialogNetworkSetup);  // window id = 128
1174  
-  g_windowManager.Add(new CGUIDialogMediaSource);   // window id = 129
1175  
-  g_windowManager.Add(new CGUIDialogProfileSettings); // window id = 130
  1188
+    g_windowManager.Add(new CGUIDialogKaraokeSongSelectorSmall); // window id 143
  1189
+    g_windowManager.Add(new CGUIDialogKaraokeSongSelectorLarge); // window id 144
  1190
+#endif
  1191
+    g_windowManager.Add(new CGUIDialogSlider);             // window id = 145
  1192
+    g_windowManager.Add(new CGUIDialogMusicOSD);           // window id = 120
  1193
+    g_windowManager.Add(new CGUIDialogVisualisationPresetList);   // window id = 122
  1194
+    g_windowManager.Add(new CGUIDialogVideoSettings);             // window id = 123
  1195
+    g_windowManager.Add(new CGUIDialogAudioSubtitleSettings);     // window id = 124
  1196
+    g_windowManager.Add(new CGUIDialogVideoBookmarks);      // window id = 125
  1197
+    // Don't add the filebrowser dialog - it's created and added when it's needed
  1198
+    g_windowManager.Add(new CGUIDialogNetworkSetup);  // window id = 128
  1199
+    g_windowManager.Add(new CGUIDialogMediaSource);   // window id = 129
  1200
+    g_windowManager.Add(new CGUIDialogProfileSettings); // window id = 130
  1201
+  } 
1176 1202
   g_windowManager.Add(new CGUIDialogVideoScan);      // window id = 133
1177  
-  g_windowManager.Add(new CGUIDialogFavourites);     // window id = 134
1178  
-  g_windowManager.Add(new CGUIDialogSongInfo);       // window id = 135
1179  
-  g_windowManager.Add(new CGUIDialogSmartPlaylistEditor);       // window id = 136
1180  
-  g_windowManager.Add(new CGUIDialogSmartPlaylistRule);       // window id = 137
1181  
-  g_windowManager.Add(new CGUIDialogBusy);      // window id = 138
1182  
-  g_windowManager.Add(new CGUIDialogPictureInfo);      // window id = 139
1183  
-  g_windowManager.Add(new CGUIDialogAddonInfo);
1184  
-  g_windowManager.Add(new CGUIDialogAddonSettings);      // window id = 140
  1203
+  if (!g_application.IsServerMode())
  1204
+  {
  1205
+    g_windowManager.Add(new CGUIDialogFavourites);     // window id = 134
  1206
+    g_windowManager.Add(new CGUIDialogSongInfo);       // window id = 135
  1207
+    g_windowManager.Add(new CGUIDialogSmartPlaylistEditor);       // window id = 136
  1208
+    g_windowManager.Add(new CGUIDialogSmartPlaylistRule);       // window id = 137
  1209
+    g_windowManager.Add(new CGUIDialogBusy);      // window id = 138
  1210
+    g_windowManager.Add(new CGUIDialogPictureInfo);      // window id = 139
  1211
+    g_windowManager.Add(new CGUIDialogAddonInfo);
  1212
+    g_windowManager.Add(new CGUIDialogAddonSettings);      // window id = 140
1185 1213
 #ifdef HAS_LINUX_NETWORK
1186  
-  g_windowManager.Add(new CGUIDialogAccessPoints);      // window id = 141
  1214
+    g_windowManager.Add(new CGUIDialogAccessPoints);      // window id = 141
1187 1215
 #endif
1188 1216
 
1189  
-  g_windowManager.Add(new CGUIDialogLockSettings); // window id = 131
  1217
+    g_windowManager.Add(new CGUIDialogLockSettings); // window id = 131
1190 1218
 
1191  
-  g_windowManager.Add(new CGUIDialogContentSettings);        // window id = 132
  1219
+    g_windowManager.Add(new CGUIDialogContentSettings);        // window id = 132
1192 1220
 
1193  
-  g_windowManager.Add(new CGUIDialogPlayEject);
  1221
+    g_windowManager.Add(new CGUIDialogPlayEject);
1194 1222
 
1195  
-  g_windowManager.Add(new CGUIDialogPeripheralManager);
1196  
-  g_windowManager.Add(new CGUIDialogPeripheralSettings);
  1223
+    g_windowManager.Add(new CGUIDialogPeripheralManager);
  1224
+    g_windowManager.Add(new CGUIDialogPeripheralSettings);
1197 1225
 
1198  
-  g_windowManager.Add(new CGUIWindowMusicPlayList);          // window id = 500
1199  
-  g_windowManager.Add(new CGUIWindowMusicSongs);             // window id = 501
1200  
-  g_windowManager.Add(new CGUIWindowMusicNav);               // window id = 502
1201  
-  g_windowManager.Add(new CGUIWindowMusicPlaylistEditor);    // window id = 503
  1226
+    g_windowManager.Add(new CGUIWindowMusicPlayList);          // window id = 500
  1227
+    g_windowManager.Add(new CGUIWindowMusicSongs);             // window id = 501
  1228
+    g_windowManager.Add(new CGUIWindowMusicNav);               // window id = 502
  1229
+    g_windowManager.Add(new CGUIWindowMusicPlaylistEditor);    // window id = 503
1202 1230
 
1203  
-  g_windowManager.Add(new CGUIDialogSelect);             // window id = 2000
1204  
-  g_windowManager.Add(new CGUIDialogMusicInfo);          // window id = 2001
1205  
-  g_windowManager.Add(new CGUIDialogOK);                 // window id = 2002
1206  
-  g_windowManager.Add(new CGUIDialogVideoInfo);          // window id = 2003
1207  
-  g_windowManager.Add(new CGUIDialogTextViewer);
1208  
-  g_windowManager.Add(new CGUIWindowFullScreen);         // window id = 2005
1209  
-  g_windowManager.Add(new CGUIWindowVisualisation);      // window id = 2006
1210  
-  g_windowManager.Add(new CGUIWindowSlideShow);          // window id = 2007
1211  
-  g_windowManager.Add(new CGUIDialogFileStacking);       // window id = 2008
  1231
+    g_windowManager.Add(new CGUIDialogSelect);             // window id = 2000
  1232
+    g_windowManager.Add(new CGUIDialogMusicInfo);          // window id = 2001
  1233
+    g_windowManager.Add(new CGUIDialogOK);                 // window id = 2002
  1234
+    g_windowManager.Add(new CGUIDialogVideoInfo);          // window id = 2003
  1235
+    g_windowManager.Add(new CGUIDialogTextViewer);
  1236
+    g_windowManager.Add(new CGUIWindowFullScreen);         // window id = 2005
  1237
+    g_windowManager.Add(new CGUIWindowVisualisation);      // window id = 2006
  1238
+    g_windowManager.Add(new CGUIWindowSlideShow);          // window id = 2007
  1239
+    g_windowManager.Add(new CGUIDialogFileStacking);       // window id = 2008
1212 1240
 #ifdef HAS_KARAOKE
1213  
-  g_windowManager.Add(new CGUIWindowKaraokeLyrics);      // window id = 2009
  1241
+    g_windowManager.Add(new CGUIWindowKaraokeLyrics);      // window id = 2009
1214 1242
 #endif
1215 1243
 
1216  
-  g_windowManager.Add(new CGUIDialogVideoOSD);           // window id = 2901
1217  
-  g_windowManager.Add(new CGUIDialogMusicOverlay);       // window id = 2903
1218  
-  g_windowManager.Add(new CGUIDialogVideoOverlay);       // window id = 2904
1219  
-  g_windowManager.Add(new CGUIWindowScreensaver);        // window id = 2900 Screensaver
1220  
-  g_windowManager.Add(new CGUIWindowWeather);            // window id = 2600 WEATHER
1221  
-  g_windowManager.Add(new CGUIWindowStartup);            // startup window (id 2999)
  1244
+    g_windowManager.Add(new CGUIDialogVideoOSD);           // window id = 2901
  1245
+    g_windowManager.Add(new CGUIDialogMusicOverlay);       // window id = 2903
  1246
+    g_windowManager.Add(new CGUIDialogVideoOverlay);       // window id = 2904
  1247
+    g_windowManager.Add(new CGUIWindowScreensaver);        // window id = 2900 Screensaver
  1248
+    g_windowManager.Add(new CGUIWindowWeather);            // window id = 2600 WEATHER
  1249
+    g_windowManager.Add(new CGUIWindowStartup);            // startup window (id 2999)
1222 1250
 
1223  
-  /* window id's 3000 - 3100 are reserved for python */
  1251
+    /* window id's 3000 - 3100 are reserved for python */
1224 1252
 
1225  
-  // Make sure we have at least the default skin
1226  
-  if (!LoadSkin(g_guiSettings.GetString("lookandfeel.skin")) && !LoadSkin(DEFAULT_SKIN))
1227  
-  {
1228  
-      CLog::Log(LOGERROR, "Default skin '%s' not found! Terminating..", DEFAULT_SKIN);
1229  
-      FatalErrorHandler(true, true, true);
1230  
-  }
  1253
+    // Make sure we have at least the default skin
  1254
+    if (!LoadSkin(g_guiSettings.GetString("lookandfeel.skin")) && !LoadSkin(DEFAULT_SKIN))
  1255
+    {
  1256
+        CLog::Log(LOGERROR, "Default skin '%s' not found! Terminating..", DEFAULT_SKIN);
  1257
+        FatalErrorHandler(true, true, true);
  1258
+    }
1231 1259
 
1232  
-  if (g_advancedSettings.m_splashImage)
1233  
-    SAFE_DELETE(m_splash);
  1260
+    if (g_advancedSettings.m_splashImage)
  1261
+      SAFE_DELETE(m_splash);
1234 1262
 
1235  
-  if (g_guiSettings.GetBool("masterlock.startuplock") &&
1236  
-      g_settings.GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE &&
1237  
-     !g_settings.GetMasterProfile().getLockCode().IsEmpty())
1238  
-  {
1239  
-     g_passwordManager.CheckStartUpLock();
  1263
+    if (g_guiSettings.GetBool("masterlock.startuplock") &&
  1264
+        g_settings.GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE &&
  1265
+       !g_settings.GetMasterProfile().getLockCode().IsEmpty())
  1266
+    {
  1267
+      g_passwordManager.CheckStartUpLock();
  1268
+    }
1240 1269
   }
1241  
-
1242 1270
   // check if we should use the login screen
1243 1271
   if (g_settings.UsingLoginScreen())
1244  
-    g_windowManager.ActivateWindow(WINDOW_LOGIN_SCREEN);
  1272
+  {
  1273
+    if (!g_application.IsServerMode())
  1274
+    {
  1275
+      g_windowManager.ActivateWindow(WINDOW_LOGIN_SCREEN);
  1276
+    }
  1277
+  } 
1245 1278
   else
1246 1279
   {
1247 1280
 #ifdef HAS_JSONRPC
1248 1281
     CJSONRPC::Initialize();
1249 1282
 #endif
1250 1283
     ADDON::CAddonMgr::Get().StartServices(false);
1251  
-    g_windowManager.ActivateWindow(g_SkinInfo->GetFirstWindow());
  1284
+    if (!g_application.IsServerMode())
  1285
+    {
  1286
+      g_windowManager.ActivateWindow(g_SkinInfo->GetFirstWindow());
  1287
+    }
1252 1288
   }
1253 1289
 
1254 1290
   g_sysinfo.Refresh();
@@ -1314,8 +1350,8 @@ bool CApplication::StartWebServer()
1314 1350
 #ifdef _LINUX
1315 1351
     if (webPort < 1024 && geteuid() != 0)
1316 1352
     {
1317  
-        CLog::Log(LOGERROR, "Cannot start Web Server as port is smaller than 1024 and user is not root");
1318  
-        return false;
  1353
+      CLog::Log(LOGERROR, "Cannot start Web Server as port is smaller than 1024 and user is not root");
  1354
+      return false;
1319 1355
     }
1320 1356
 #endif
1321 1357
 
@@ -1360,7 +1396,8 @@ void CApplication::StopWebServer()
1360 1396
       CZeroconf::GetInstance()->RemoveService("servers.webserver");
1361 1397
       CZeroconf::GetInstance()->RemoveService("servers.jsonrpc-http");
1362 1398
       CZeroconf::GetInstance()->RemoveService("servers.webapi");
1363  
-    } else
  1399
+    } 
  1400
+    else
1364 1401
       CLog::Log(LOGWARNING, "Webserver: Failed to stop.");
1365 1402
   }
1366 1403
 #endif
@@ -2040,6 +2077,10 @@ void CApplication::Render()
2040 2077
   if (m_bStop)
2041 2078
     return;
2042 2079
 
  2080
+  // do not render if we're in server mode
  2081
+  if (g_application.IsServerMode())
  2082
+    return;
  2083
+
2043 2084
   if (!m_AppActive && !m_bStop && (!IsPlayingVideo() || IsPaused()))
2044 2085
   {
2045 2086
     Sleep(1);
@@ -2171,6 +2212,10 @@ void CApplication::SetStandAlone(bool value)
2171 2212
 {
2172 2213
   g_advancedSettings.m_handleMounting = m_bStandalone = value;
2173 2214
 }
  2215
+void CApplication::SetServerMode(bool value)
  2216
+{
  2217
+  g_advancedSettings.m_serverMode = m_bServerMode = value;
  2218
+}
2174 2219
 
2175 2220
 // OnKey() translates the key into a CAction which is sent on to our Window Manager.
2176 2221
 // The window manager will return true if the event is processed, false otherwise.
@@ -2729,21 +2774,22 @@ void CApplication::FrameMove(bool processEvents)
2729 2774
     m_frameTime.StartZero();
2730 2775
     // never set a frametime less than 2 fps to avoid problems when debuggin and on breaks
2731 2776
     if( frameTime > 0.5 ) frameTime = 0.5;
2732  
-
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())
  2777
+    if (!g_application.IsServerMode())
2737 2778
     {
2738  
-      if (!toast->IsDialogRunning())
  2779
+      g_graphicsContext.Lock();
  2780
+      // check if there are notifications to display
  2781
+      CGUIDialogKaiToast *toast = (CGUIDialogKaiToast *)g_windowManager.GetWindow(WINDOW_DIALOG_KAI_TOAST);
  2782
+      if (toast && toast->DoWork())
2739 2783
       {
2740  
-        toast->Show();
  2784
+        if (!toast->IsDialogRunning())
  2785
+        {
  2786
+          toast->Show();
  2787
+        }
2741 2788
       }
2742  
-    }
2743  
-    g_graphicsContext.Unlock();
2744  
-
2745  
-    UpdateLCD();
  2789
+      g_graphicsContext.Unlock();
2746 2790
 
  2791
+      UpdateLCD();
  2792
+    }
2747 2793
 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
2748 2794
     // Read the input from a remote
2749 2795
     g_RemoteControl.Update();
@@ -2759,9 +2805,12 @@ void CApplication::FrameMove(bool processEvents)
2759 2805
     ProcessPeripherals(frameTime);
2760 2806
     m_pInertialScrollingHandler->ProcessInertialScroll(frameTime);
2761 2807
   }
2762  
-  if (!m_bStop)
2763  
-    g_windowManager.Process(CTimeUtils::GetFrameTime());
2764  
-  g_windowManager.FrameMove();
  2808
+  if (!g_application.IsServerMode())
  2809
+  {
  2810
+    if (!m_bStop)
  2811
+      g_windowManager.Process(CTimeUtils::GetFrameTime());
  2812
+    g_windowManager.FrameMove();
  2813
+  } 
2765 2814
 }
2766 2815
 
2767 2816
 bool CApplication::ProcessGamepad(float frameTime)
@@ -4858,14 +4907,19 @@ bool CApplication::ExecuteXBMCAction(std::string actionStr)
4858 4907
 void CApplication::Process()
4859 4908
 {
4860 4909
   MEASURE_FUNCTION;
  4910
+  if (g_application.IsServerMode())
  4911
+  {
  4912
+    Sleep(1);
  4913
+  }
  4914
+  else 
  4915
+  {
  4916
+    // dispatch the messages generated by python or other threads to the current window
  4917
+    g_windowManager.DispatchThreadMessages();
4861 4918
 
4862  
-  // dispatch the messages generated by python or other threads to the current window
4863  
-  g_windowManager.DispatchThreadMessages();
4864  
-
4865  
-  // process messages which have to be send to the gui
4866  
-  // (this can only be done after g_windowManager.Render())
4867  
-  m_applicationMessenger.ProcessWindowMessages();
4868  
-
  4919
+    // process messages which have to be send to the gui
  4920
+    // (this can only be done after g_windowManager.Render())
  4921
+    m_applicationMessenger.ProcessWindowMessages();
  4922
+  }
4869 4923
 #ifdef HAS_PYTHON
4870 4924
   // process any Python scripts
4871 4925
   g_pythonParser.Process();
9  xbmc/Application.h
@@ -284,6 +284,13 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs
284 284
     return m_bStandalone;
285 285
   }
286 286
 
  287
+  void SetServerMode(bool value);
  288
+
  289
+  bool IsServerMode()
  290
+  {
  291
+    return m_bServerMode;
  292
+  }
  293
+
287 294
   void SetEnableLegacyRes(bool value)
288 295
   {
289 296
     m_bEnableLegacyRes = value;
@@ -304,6 +311,7 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs
304 311
     return m_bTestMode;
305 312
   }
306 313
 
  314
+
307 315
   bool IsPresentFrame();
308 316
 
309 317
   void Minimize();
@@ -365,6 +373,7 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs
365 373
   unsigned int m_lastRenderTime;
366 374
 
367 375
   bool m_bStandalone;
  376
+  bool m_bServerMode;
368 377
   bool m_bEnableLegacyRes;
369 378
   bool m_bTestMode;
370 379
   bool m_bSystemScreenSaverEnable;
199  xbmc/interfaces/Builtins.cpp
@@ -98,114 +98,115 @@ using namespace MEDIA_DETECT;
98 98
 typedef struct
99 99
 {
100 100
   const char* command;
  101
+  bool availableInServerMode;
101 102
   bool needsParameters;
102 103
   const char* description;
103 104
 } BUILT_IN;
104 105
 
105 106
 const BUILT_IN commands[] = {
106  
-  { "Help",                       false,  "This help message" },
107  
-  { "Reboot",                     false,  "Reboot the xbox (power cycle)" },
108  
-  { "Restart",                    false,  "Restart the xbox (power cycle)" },
109  
-  { "ShutDown",                   false,  "Shutdown the xbox" },
110  
-  { "Powerdown",                  false,  "Powerdown system" },
111  
-  { "Quit",                       false,  "Quit XBMC" },
112  
-  { "Hibernate",                  false,  "Hibernates the system" },
113  
-  { "Suspend",                    false,  "Suspends the system" },
114  
-  { "RestartApp",                 false,  "Restart XBMC" },
115  
-  { "Minimize",                   false,  "Minimize XBMC" },
116  
-  { "Reset",                      false,  "Reset the xbox (warm reboot)" },
117  
-  { "Mastermode",                 false,  "Control master mode" },
118  
-  { "ActivateWindow",             true,   "Activate the specified window" },
119  
-  { "ReplaceWindow",              true,   "Replaces the current window with the new one" },
120  
-  { "TakeScreenshot",             false,  "Takes a Screenshot" },
121  
-  { "RunScript",                  true,   "Run the specified script" },
  107
+  { "Help",                       true, false,  "This help message" },
  108
+  { "Reboot",                     true, false,  "Reboot the xbox (power cycle)" },
  109
+  { "Restart",                    true, false,  "Restart the xbox (power cycle)" },
  110
+  { "ShutDown",                   true, false,  "Shutdown the xbox" },
  111
+  { "Powerdown",                  true, false,  "Powerdown system" },
  112
+  { "Quit",                       true, false,  "Quit XBMC" },
  113
+  { "Hibernate",                  true, false,  "Hibernates the system" },
  114
+  { "Suspend",                    true, false,  "Suspends the system" },
  115
+  { "RestartApp",                 true, false,  "Restart XBMC" },
  116
+  { "Minimize",                   false, false,  "Minimize XBMC" },
  117
+  { "Reset",                      true, false,  "Reset the xbox (warm reboot)" },
  118
+  { "Mastermode",                 true, false,  "Control master mode" },
  119
+  { "ActivateWindow",             false, true,   "Activate the specified window" },
  120
+  { "ReplaceWindow",              false, true,   "Replaces the current window with the new one" },
  121
+  { "TakeScreenshot",             false, false,  "Takes a Screenshot" },
  122
+  { "RunScript",                  true, true,   "Run the specified script" },
122 123
 #if defined(__APPLE__)
123  
-  { "RunAppleScript",             true,   "Run the specified AppleScript command" },
  124
+  { "RunAppleScript",             true, true,   "Run the specified AppleScript command" },
124 125
 #endif
125  
-  { "RunPlugin",                  true,   "Run the specified plugin" },
126  
-  { "RunAddon",                   true,   "Run the specified plugin/script" },
127  
-  { "Extract",                    true,   "Extracts the specified archive" },
128  
-  { "PlayMedia",                  true,   "Play the specified media file (or playlist)" },
129  
-  { "SlideShow",                  true,   "Run a slideshow from the specified directory" },
130  
-  { "RecursiveSlideShow",         true,   "Run a slideshow from the specified directory, including all subdirs" },
131  
-  { "ReloadSkin",                 false,  "Reload XBMC's skin" },
132  
-  { "UnloadSkin",                 false,  "Unload XBMC's skin" },
133  
-  { "RefreshRSS",                 false,  "Reload RSS feeds from RSSFeeds.xml"},
134  
-  { "PlayerControl",              true,   "Control the music or video player" },
135  
-  { "Playlist.PlayOffset",        true,   "Start playing from a particular offset in the playlist" },
136  
-  { "Playlist.Clear",             false,  "Clear the current playlist" },
137  
-  { "EjectTray",                  false,  "Close or open the DVD tray" },
138  
-  { "AlarmClock",                 true,   "Prompt for a length of time and start an alarm clock" },
139  
-  { "CancelAlarm",                true,   "Cancels an alarm" },
140  
-  { "Action",                     true,   "Executes an action for the active window (same as in keymap)" },
141  
-  { "Notification",               true,   "Shows a notification on screen, specify header, then message, and optionally time in milliseconds and a icon." },
142  
-  { "PlayDVD",                    false,  "Plays the inserted CD or DVD media from the DVD-ROM Drive!" },
143  
-  { "RipCD",                      false,  "Rip the currently inserted audio CD"},
144  
-  { "Skin.ToggleSetting",         true,   "Toggles a skin setting on or off" },
145  
-  { "Skin.SetString",             true,   "Prompts and sets skin string" },
146  
-  { "Skin.SetNumeric",            true,   "Prompts and sets numeric input" },
147  
-  { "Skin.SetPath",               true,   "Prompts and sets a skin path" },
148  
-  { "Skin.Theme",                 true,   "Control skin theme" },
149  
-  { "Skin.SetImage",              true,   "Prompts and sets a skin image" },
150  
-  { "Skin.SetLargeImage",         true,   "Prompts and sets a large skin images" },
151  
-  { "Skin.SetFile",               true,   "Prompts and sets a file" },
152  
-  { "Skin.SetAddon",              true,   "Prompts and set an addon" },
153  
-  { "Skin.SetBool",               true,   "Sets a skin setting on" },
154  
-  { "Skin.Reset",                 true,   "Resets a skin setting to default" },
155  
-  { "Skin.ResetSettings",         false,  "Resets all skin settings" },
156  
-  { "Mute",                       false,  "Mute the player" },
157  
-  { "SetVolume",                  true,   "Set the current volume" },
158  
-  { "Dialog.Close",               true,   "Close a dialog" },
159  
-  { "System.LogOff",              false,  "Log off current user" },
160  
-  { "System.Exec",                true,   "Execute shell commands" },
161  
-  { "System.ExecWait",            true,   "Execute shell commands and freezes XBMC until shell is closed" },
162  
-  { "Resolution",                 true,   "Change XBMC's Resolution" },
163  
-  { "SetFocus",                   true,   "Change current focus to a different control id" },
164  
-  { "UpdateLibrary",              true,   "Update the selected library (music or video)" },
165  
-  { "CleanLibrary",               true,   "Clean the video/music library" },
166  
-  { "ExportLibrary",              true,   "Export the video/music library" },
167  
-  { "PageDown",                   true,   "Send a page down event to the pagecontrol with given id" },
168  
-  { "PageUp",                     true,   "Send a page up event to the pagecontrol with given id" },
169  
-  { "LastFM.Love",                false,  "Add the current playing last.fm radio track to the last.fm loved tracks" },
170  
-  { "LastFM.Ban",                 false,  "Ban the current playing last.fm radio track" },
171  
-  { "Container.Refresh",          false,  "Refresh current listing" },
172  
-  { "Container.Update",           false,  "Update current listing. Send Container.Update(path,replace) to reset the path history" },
173  
-  { "Container.NextViewMode",     false,  "Move to the next view type (and refresh the listing)" },
174  
-  { "Container.PreviousViewMode", false,  "Move to the previous view type (and refresh the listing)" },
175  
-  { "Container.SetViewMode",      true,   "Move to the view with the given id" },
176  
-  { "Container.NextSortMethod",   false,  "Change to the next sort method" },
177  
-  { "Container.PreviousSortMethod",false, "Change to the previous sort method" },
178  
-  { "Container.SetSortMethod",    true,   "Change to the specified sort method" },
179  
-  { "Container.SortDirection",    false,  "Toggle the sort direction" },
180  
-  { "Control.Move",               true,   "Tells the specified control to 'move' to another entry specified by offset" },
181  
-  { "Control.SetFocus",           true,   "Change current focus to a different control id" },
182  
-  { "Control.Message",            true,   "Send a given message to a control within a given window" },
183  
-  { "SendClick",                  true,   "Send a click message from the given control to the given window" },
184  
-  { "LoadProfile",                true,   "Load the specified profile (note; if locks are active it won't work)" },
185  
-  { "SetProperty",                true,   "Sets a window property for the current focused window/dialog (key,value)" },
186  
-  { "ClearProperty",              true,   "Clears a window property for the current focused window/dialog (key,value)" },
187  
-  { "PlayWith",                   true,   "Play the selected item with the specified core" },
188  
-  { "WakeOnLan",                  true,   "Sends the wake-up packet to the broadcast address for the specified MAC address" },
189  
-  { "Addon.Default.OpenSettings", true,   "Open a settings dialog for the default addon of the given type" },
190  
-  { "Addon.Default.Set",          true,   "Open a select dialog to allow choosing the default addon of the given type" },
191  
-  { "Addon.OpenSettings",         true,   "Open a settings dialog for the addon of the given id" },
192  
-  { "UpdateAddonRepos",           false,  "Check add-on repositories for updates" },
193  
-  { "UpdateLocalAddons",          false,  "Check for local add-on changes" },
194  
-  { "ToggleDPMS",                 false,  "Toggle DPMS mode manually"},
195  
-  { "Weather.Refresh",            false,  "Force weather data refresh"},
196  
-  { "Weather.LocationNext",       false,  "Switch to next weather location"},
197  
-  { "Weather.LocationPrevious",   false,  "Switch to previous weather location"},
198  
-  { "Weather.LocationSet",        true,   "Switch to given weather location (parameter can be 1-3)"},
  126
+  { "RunPlugin",                  true, true,   "Run the specified plugin" },
  127
+  { "RunAddon",                   true, true,   "Run the specified plugin/script" },
  128
+  { "Extract",                    true, true,   "Extracts the specified archive" },
  129
+  { "PlayMedia",                  false, true,   "Play the specified media file (or playlist)" },
  130
+  { "SlideShow",                  false, true,   "Run a slideshow from the specified directory" },
  131
+  { "RecursiveSlideShow",         false, true,   "Run a slideshow from the specified directory, including all subdirs" },
  132
+  { "ReloadSkin",                 false, false,  "Reload XBMC's skin" },
  133
+  { "UnloadSkin",                 false, false,  "Unload XBMC's skin" },
  134
+  { "RefreshRSS",                 false, false,  "Reload RSS feeds from RSSFeeds.xml"},
  135
+  { "PlayerControl",              false, true,   "Control the music or video player" },
  136
+  { "Playlist.PlayOffset",        false, true,   "Start playing from a particular offset in the playlist" },
  137
+  { "Playlist.Clear",             false, false,  "Clear the current playlist" },
  138
+  { "EjectTray",                  false, false,  "Close or open the DVD tray" },
  139
+  { "AlarmClock",                 true, true,   "Prompt for a length of time and start an alarm clock" },
  140
+  { "CancelAlarm",                true, true,   "Cancels an alarm" },
  141
+  { "Action",                     false, true,   "Executes an action for the active window (same as in keymap)" },
  142
+  { "Notification",               false, true,   "Shows a notification on screen, specify header, then message, and optionally time in milliseconds and a icon." },
  143
+  { "PlayDVD",                    false, false,  "Plays the inserted CD or DVD media from the DVD-ROM Drive!" },
  144
+  { "RipCD",                      false, false,  "Rip the currently inserted audio CD"},
  145
+  { "Skin.ToggleSetting",         false, true,   "Toggles a skin setting on or off" },
  146
+  { "Skin.SetString",             false, true,   "Prompts and sets skin string" },
  147
+  { "Skin.SetNumeric",            false, true,   "Prompts and sets numeric input" },
  148
+  { "Skin.SetPath",               false, true,   "Prompts and sets a skin path" },
  149
+  { "Skin.Theme",                 false, true,   "Control skin theme" },
  150
+  { "Skin.SetImage",              false, true,   "Prompts and sets a skin image" },
  151
+  { "Skin.SetLargeImage",         false, true,   "Prompts and sets a large skin images" },
  152
+  { "Skin.SetFile",               false, true,   "Prompts and sets a file" },
  153
+  { "Skin.SetAddon",              false, true,   "Prompts and set an addon" },
  154
+  { "Skin.SetBool",               false, true,   "Sets a skin setting on" },
  155
+  { "Skin.Reset",                 false, true,   "Resets a skin setting to default" },
  156
+  { "Skin.ResetSettings",         false, false,  "Resets all skin settings" },
  157
+  { "Mute",                       false, false,  "Mute the player" },
  158
+  { "SetVolume",                  false, true,   "Set the current volume" },
  159
+  { "Dialog.Close",               false, true,   "Close a dialog" },
  160
+  { "System.LogOff",              true, false,  "Log off current user" },
  161
+  { "System.Exec",                true, true,   "Execute shell commands" },
  162
+  { "System.ExecWait",            true, true,   "Execute shell commands and freezes XBMC until shell is closed" },
  163
+  { "Resolution",                 false, true,   "Change XBMC's Resolution" },
  164
+  { "SetFocus",                   true, true,   "Change current focus to a different control id" },
  165
+  { "UpdateLibrary",              true, true,   "Update the selected library (music or video)" },
  166
+  { "CleanLibrary",               true, true,   "Clean the video/music library" },
  167
+  { "ExportLibrary",              true, true,   "Export the video/music library" },
  168
+  { "PageDown",                   false, true,   "Send a page down event to the pagecontrol with given id" },
  169
+  { "PageUp",                     false, true,   "Send a page up event to the pagecontrol with given id" },
  170
+  { "LastFM.Love",                false, false,  "Add the current playing last.fm radio track to the last.fm loved tracks" },
  171
+  { "LastFM.Ban",                 false, false,  "Ban the current playing last.fm radio track" },
  172
+  { "Container.Refresh",          false, false,  "Refresh current listing" },
  173
+  { "Container.Update",           false, false,  "Update current listing. Send Container.Update(path,replace) to reset the path history" },
  174
+  { "Container.NextViewMode",     false, false,  "Move to the next view type (and refresh the listing)" },
  175
+  { "Container.PreviousViewMode", false, false,  "Move to the previous view type (and refresh the listing)" },
  176
+  { "Container.SetViewMode",      false, true,   "Move to the view with the given id" },
  177
+  { "Container.NextSortMethod",   false, false,  "Change to the next sort method" },
  178
+  { "Container.PreviousSortMethod",false, false, "Change to the previous sort method" },
  179
+  { "Container.SetSortMethod",    false, true,   "Change to the specified sort method" },
  180
+  { "Container.SortDirection",    false, false,  "Toggle the sort direction" },
  181
+  { "Control.Move",               false, true,   "Tells the specified control to 'move' to another entry specified by offset" },
  182
+  { "Control.SetFocus",           false, true,   "Change current focus to a different control id" },
  183
+  { "Control.Message",            false, true,   "Send a given message to a control within a given window" },
  184
+  { "SendClick",                  false, true,   "Send a click message from the given control to the given window" },
  185
+  { "LoadProfile",                true, true,   "Load the specified profile (note; if locks are active it won't work)" },
  186
+  { "SetProperty",                false, true,   "Sets a window property for the current focused window/dialog (key,value)" },
  187
+  { "ClearProperty",              false, true,   "Clears a window property for the current focused window/dialog (key,value)" },
  188
+  { "PlayWith",                   false, true,   "Play the selected item with the specified core" },
  189
+  { "WakeOnLan",                  true, true,   "Sends the wake-up packet to the broadcast address for the specified MAC address" },
  190
+  { "Addon.Default.OpenSettings", false, true,   "Open a settings dialog for the default addon of the given type" },
  191
+  { "Addon.Default.Set",          false, true,   "Open a select dialog to allow choosing the default addon of the given type" },
  192
+  { "Addon.OpenSettings",         false, true,   "Open a settings dialog for the addon of the given id" },
  193
+  { "UpdateAddonRepos",           true, false,  "Check add-on repositories for updates" },
  194
+  { "UpdateLocalAddons",          true, false,  "Check for local add-on changes" },
  195
+  { "ToggleDPMS",                 false, false,  "Toggle DPMS mode manually"},
  196
+  { "Weather.Refresh",            false, false,  "Force weather data refresh"},
  197
+  { "Weather.LocationNext",       false, false,  "Switch to next weather location"},
  198
+  { "Weather.LocationPrevious",   false, false,  "Switch to previous weather location"},
  199
+  { "Weather.LocationSet",        false, true,   "Switch to given weather location (parameter can be 1-3)"},
199 200
 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
200  
-  { "LIRC.Stop",                  false,  "Removes XBMC as LIRC client" },
201  
-  { "LIRC.Start",                 false,  "Adds XBMC as LIRC client" },
202  
-  { "LIRC.Send",                  true,   "Sends a command to LIRC" },
  201
+  { "LIRC.Stop",                  false, false,  "Removes XBMC as LIRC client" },
  202
+  { "LIRC.Start",                 false, false,  "Adds XBMC as LIRC client" },
  203
+  { "LIRC.Send",                  false, true,   "Sends a command to LIRC" },
203 204
 #endif
204 205
 #ifdef HAS_LCD
205  
-  { "LCD.Suspend",                false,  "Suspends LCDproc" },
206  
-  { "LCD.Resume",                 false,  "Resumes LCDproc" },
  206
+  { "LCD.Suspend",                false, false,  "Suspends LCDproc" },
  207
+  { "LCD.Resume",                 false, false,  "Resumes LCDproc" },
207 208
 #endif
208  
-  { "VideoLibrary.Search",        false,  "Brings up a search dialog which will search the library" },
  209
+  { "VideoLibrary.Search",        false, false,  "Brings up a search dialog which will search the library" },
209 210
 };
210 211
 
211 212
 bool CBuiltins::HasCommand(const CStdString& execString)
@@ -215,7 +216,7 @@ bool CBuiltins::HasCommand(const CStdString& execString)
215 216
   CUtil::SplitExecFunction(execString, function, parameters);
216 217
   for (unsigned int i = 0; i < sizeof(commands)/sizeof(BUILT_IN); i++)
217 218
   {
218  
-    if (function.CompareNoCase(commands[i].command) == 0 && (!commands[i].needsParameters || parameters.size()))
  219
+    if (function.CompareNoCase(commands[i].command) == 0 && (!g_application.IsServerMode() || commands[i].availableInServerMode) && (!commands[i].needsParameters || parameters.size()))
219 220
       return true;
220 221
   }
221 222
   return false;
@@ -456,7 +457,7 @@ int CBuiltins::Execute(const CStdString& execString)