[release] version bump to 13.0 beta1
[vuplus_xbmc] / xbmc / win32 / XBMC_PC.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "AppParamParser.h"
22 #include "settings/AdvancedSettings.h"
23 #include "utils/CharsetConverter.h"
24 #include "utils/log.h"
25 #include "threads/platform/win/Win32Exception.h"
26 #include "shellapi.h"
27 #include "dbghelp.h"
28 #include "XBDateTime.h"
29 #include "threads/Thread.h"
30 #include "Application.h"
31 #include "XbmcContext.h"
32 #include "GUIInfoManager.h"
33 #include "utils/StringUtils.h"
34 #include "utils/CPUInfo.h"
35
36 #ifndef _DEBUG
37 #define XBMC_TRACK_EXCEPTIONS
38 #endif
39
40 // Minidump creation function
41 LONG WINAPI CreateMiniDump( EXCEPTION_POINTERS* pEp )
42 {
43   win32_exception::write_stacktrace(pEp);
44   win32_exception::write_minidump(pEp);
45   return pEp->ExceptionRecord->ExceptionCode;;
46 }
47
48 //-----------------------------------------------------------------------------
49 // Name: WinMain()
50 // Desc: The application's entry point
51 //-----------------------------------------------------------------------------
52 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT )
53 {
54   // set up some xbmc specific relationships
55   XBMC::Context context;
56
57   //this can't be set from CAdvancedSettings::Initialize() because it will overwrite
58   //the loglevel set with the --debug flag
59 #ifdef _DEBUG
60   g_advancedSettings.m_logLevel     = LOG_LEVEL_DEBUG;
61   g_advancedSettings.m_logLevelHint = LOG_LEVEL_DEBUG;
62 #else
63   g_advancedSettings.m_logLevel     = LOG_LEVEL_NORMAL;
64   g_advancedSettings.m_logLevelHint = LOG_LEVEL_NORMAL;
65 #endif
66   CLog::SetLogLevel(g_advancedSettings.m_logLevel);
67
68   // Initializes CreateMiniDump to handle exceptions.
69   win32_exception::set_version(g_infoManager.GetVersion());
70   SetUnhandledExceptionFilter( CreateMiniDump );
71
72   // check if XBMC is already running
73   CreateMutex(NULL, FALSE, "XBMC Media Center");
74   if(GetLastError() == ERROR_ALREADY_EXISTS)
75   {
76     HWND m_hwnd = FindWindow("XBMC","XBMC");
77     if(m_hwnd != NULL)
78     {
79       // switch to the running instance
80       ShowWindow(m_hwnd,SW_RESTORE);
81       SetForegroundWindow(m_hwnd);
82     }
83     return 0;
84   }
85
86 #ifndef HAS_DX
87   if(CWIN32Util::GetDesktopColorDepth() < 32)
88   {
89     //FIXME: replace it by a SDL window for all ports
90     MessageBox(NULL, "Desktop Color Depth isn't 32Bit", "XBMC: Fatal Error", MB_OK|MB_ICONERROR);
91     return 0;
92   }
93 #endif
94
95   if((g_cpuInfo.GetCPUFeatures() & CPU_FEATURE_SSE2) == 0)
96   {
97     MessageBox(NULL, "No SSE2 support detected", "XBMC: Fatal Error", MB_OK|MB_ICONERROR);
98     return 0;
99   }
100
101   //Initialize COM
102   CoInitializeEx(NULL, COINIT_MULTITHREADED);
103
104   // Handle numeric values using the default/POSIX standard
105   setlocale(LC_NUMERIC, "C");
106
107   // If the command line passed to WinMain, commandLine, is not "" we need
108   // to process the command line arguments.
109   // Note that commandLine does not include the program name and can be
110   // equal to "" if no arguments were supplied. By contrast GetCommandLineW()
111   // does include the program name and is never equal to "".
112   g_advancedSettings.Initialize();
113   if (strlen(commandLine) != 0)
114   {
115     int argc;
116     LPWSTR* argvW = CommandLineToArgvW(GetCommandLineW(), &argc);
117
118     std::vector<std::string> strargvA;
119     strargvA.resize(argc);
120     const char** argv = (const char**) LocalAlloc(LMEM_FIXED, argc*sizeof(char*));
121     for (int i = 0; i < argc; i++)
122     {
123       g_charsetConverter.wToUTF8(argvW[i], strargvA[i]);
124       argv[i] = strargvA[i].c_str();
125     }
126
127     // Parse the arguments
128     CAppParamParser appParamParser;
129     appParamParser.Parse(argv, argc);
130
131     // Clean up the storage we've used
132     LocalFree(argvW);
133     LocalFree(argv);
134   }
135
136   // Initialise Winsock
137   WSADATA wd;
138   WSAStartup(MAKEWORD(2,2), &wd);
139
140   // use 1 ms timer precision - like SDL initialization used to do
141   timeBeginPeriod(1);
142
143 #ifdef XBMC_TRACK_EXCEPTIONS
144   try
145   {
146 #endif
147     // Create and run the app
148     if(!g_application.Create())
149     {
150       MessageBox(NULL, "ERROR: Unable to create application. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
151       return 1;
152     }
153 #ifdef XBMC_TRACK_EXCEPTIONS
154   }
155   catch (const XbmcCommons::UncheckedException &e)
156   {
157     e.LogThrowMessage("CApplication::Create()");
158     MessageBox(NULL, "ERROR: Unable to create application. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
159     return 1;
160   }
161   catch (...)
162   {
163     CLog::Log(LOGERROR, "exception in CApplication::Create()");
164     MessageBox(NULL, "ERROR: Unable to create application. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
165     return 1;
166   }
167 #endif
168
169 #ifndef _DEBUG
170   // we don't want to see the "no disc in drive" windows message box
171   SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
172 #endif
173
174 #ifdef XBMC_TRACK_EXCEPTIONS
175   try
176   {
177 #endif
178     if (!g_application.CreateGUI())
179     {
180       MessageBox(NULL, "ERROR: Unable to create GUI. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
181       return 1;
182     }
183 #ifdef XBMC_TRACK_EXCEPTIONS
184   }
185   catch (const XbmcCommons::UncheckedException &e)
186   {
187     e.LogThrowMessage("CApplication::CreateGUI()");
188     MessageBox(NULL, "ERROR: Unable to create GUI. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
189     return 1;
190   }
191   catch (...)
192   {
193     CLog::Log(LOGERROR, "exception in CApplication::CreateGUI()");
194     MessageBox(NULL, "ERROR: Unable to create GUI. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
195     return 1;
196   }
197 #endif
198
199 #ifdef XBMC_TRACK_EXCEPTIONS
200   try
201   {
202 #endif
203     if (!g_application.Initialize())
204     {
205       MessageBox(NULL, "ERROR: Unable to Initialize. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
206       return 1;
207     }
208 #ifdef XBMC_TRACK_EXCEPTIONS
209   }
210   catch (const XbmcCommons::UncheckedException &e)
211   {
212     e.LogThrowMessage("CApplication::Initialize()");
213     MessageBox(NULL, "ERROR: Unable to Initialize. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
214     return 1;
215   }
216   catch (...)
217   {
218     CLog::Log(LOGERROR, "exception in CApplication::Initialize()");
219     MessageBox(NULL, "ERROR: Unable to Initialize. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
220     return 1;
221   }
222 #endif
223
224   g_application.Run();
225
226   // clear previously set timer resolution
227   timeEndPeriod(1);             
228
229   // the end
230   WSACleanup();
231   CoUninitialize();
232
233   return 0;
234 }