]> git.mxchange.org Git - flightgear.git/blob - src/Main/bootstrap.cxx
MapWidget: silence compiler warning
[flightgear.git] / src / Main / bootstrap.cxx
1 // bootstrap.cxx -- bootstrap routines: main()
2 //
3 // Written by Curtis Olson, started May 1997.
4 //
5 // Copyright (C) 1997 - 2002  Curtis L. Olson  - http://www.flightgear.org/~curt
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #ifdef HAVE_WINDOWS_H
29 #include <windows.h>
30 #endif
31
32 #if defined(HAVE_FEENABLEEXCEPT)
33 #ifndef _GNU_SOURCE
34 #define _GNU_SOURCE
35 #endif
36 #include <fenv.h>
37 #elif defined(__linux__) && defined(__i386__)
38 #  include <fpu_control.h>
39 #endif
40
41 #ifndef _WIN32
42 #  include <unistd.h> // for gethostname()
43 #endif
44
45 #include <errno.h>
46 #include <signal.h>
47 #include <stdlib.h>
48 #include <stdio.h>
49
50 #include <simgear/compiler.h>
51 #include <simgear/structure/exception.hxx>
52
53 #include <osg/Texture>
54 #include <osg/BufferObject>
55
56 #include <cstring>
57 #include <iostream>
58 using std::cerr;
59 using std::endl;
60
61 #include <Viewer/fgviewer.hxx>
62 #include "main.hxx"
63 #include <Include/version.h>
64 #include <Main/globals.hxx>
65 #include <Main/fg_props.hxx>
66 #include <GUI/MessageBox.hxx>
67
68 #include "fg_os.hxx"
69
70 #if defined(SG_MAC)
71     #include <GUI/CocoaHelpers.h> // for transformToForegroundApp
72 #endif
73
74 #if defined(HAVE_CRASHRPT)
75         #include <CrashRpt.h>
76
77 bool global_crashRptEnabled = false;
78
79 #endif
80
81 std::string homedir;
82 std::string hostname;
83
84 // forward declaration.
85 void fgExitCleanup();
86
87 static bool fpeAbort = false;
88 static void initFPE();
89
90 #if defined(HAVE_FEENABLEEXCEPT)
91 static void handleFPE(int);
92 static void
93 initFPE ()
94 {
95     if (fpeAbort) {
96         int except = fegetexcept();
97         feenableexcept(except | FE_DIVBYZERO | FE_INVALID);
98     } else {
99         signal(SIGFPE, handleFPE);
100     }
101 }
102
103 static void handleFPE(int)
104 {
105     feclearexcept(FE_ALL_EXCEPT);
106     signal(SIGFPE, handleFPE);
107 }
108 #elif defined(__linux__) && defined(__i386__)
109
110 static void handleFPE(int);
111 static void
112 initFPE ()
113 {
114     fpu_control_t fpe_flags = 0;
115     _FPU_GETCW(fpe_flags);
116 //     fpe_flags &= ~_FPU_MASK_IM;      // invalid operation
117 //     fpe_flags &= ~_FPU_MASK_DM;      // denormalized operand
118 //     fpe_flags &= ~_FPU_MASK_ZM;      // zero-divide
119 //     fpe_flags &= ~_FPU_MASK_OM;      // overflow
120 //     fpe_flags &= ~_FPU_MASK_UM;      // underflow
121 //     fpe_flags &= ~_FPU_MASK_PM;      // precision (inexact result)
122     _FPU_SETCW(fpe_flags);
123     signal(SIGFPE, handleFPE);
124 }
125
126 static void
127 handleFPE (int num)
128 {
129   initFPE();
130   SG_LOG(SG_GENERAL, SG_ALERT, "Floating point interrupt (SIGFPE)");
131 }
132 #else
133 static void initFPE()
134 {
135 }
136 #endif
137
138 #if defined(SG_WINDOWS)
139 int main ( int argc, char **argv );
140 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
141                              LPSTR lpCmdLine, int nCmdShow) {
142
143   main( __argc, __argv );
144 }
145 #endif
146
147 static void fg_terminate() {
148     cerr << endl <<
149             "Uncaught Exception: missing exception handler on some thread"
150             << endl << endl;
151     abort();
152 }
153
154 int _bootstrap_OSInit;
155
156 // Main entry point; catch any exceptions that have made it this far.
157 int main ( int argc, char **argv )
158 {
159 #if defined(SG_WINDOWS)
160   // Don't show blocking "no disk in drive" error messages on Windows 7,
161   // silently return errors to application instead.
162   // See Microsoft MSDN #ms680621: "GUI apps should specify SEM_NOOPENFILEERRORBOX"
163   SetErrorMode(SEM_NOOPENFILEERRORBOX);
164
165   hostname = ::getenv( "COMPUTERNAME" );
166 #else
167   // Unix(alike) systems
168   char _hostname[256];
169   gethostname(_hostname, 256);
170   hostname = _hostname;
171     
172   signal(SIGPIPE, SIG_IGN);
173 #endif
174
175 #if defined(SG_MAC)
176     // required so native messages boxes work prior to osgViewer init
177     // (only needed when not running as a bundled app)
178     transformToForegroundApp();
179 #endif
180     
181 #ifdef PTW32_STATIC_LIB
182     // Initialise static pthread win32 lib
183     pthread_win32_process_attach_np ();
184 #endif
185     _bootstrap_OSInit = 0;
186
187 #if defined(HAVE_CRASHRPT)
188         // Define CrashRpt configuration parameters
189         CR_INSTALL_INFO info;  
190         memset(&info, 0, sizeof(CR_INSTALL_INFO));  
191         info.cb = sizeof(CR_INSTALL_INFO);    
192         info.pszAppName = "FlightGear";
193         info.pszAppVersion = FLIGHTGEAR_VERSION;
194         info.pszEmailSubject = "FlightGear " FLIGHTGEAR_VERSION " crash report";
195         info.pszEmailTo = "fgcrash@goneabitbursar.com";
196         info.pszUrl = "http://fgfs.goneabitbursar.com/crashreporter/crashrpt.php";
197         info.uPriorities[CR_HTTP] = 3; 
198         info.uPriorities[CR_SMTP] = 2;  
199         info.uPriorities[CR_SMAPI] = 1;
200
201         // Install all available exception handlers
202         info.dwFlags |= CR_INST_ALL_POSSIBLE_HANDLERS;
203   
204         // Restart the app on crash 
205         info.dwFlags |= CR_INST_SEND_QUEUED_REPORTS; 
206
207         // automatically install handlers for all threads
208         info.dwFlags |= CR_INST_AUTO_THREAD_HANDLERS;
209
210         // Define the Privacy Policy URL 
211         info.pszPrivacyPolicyURL = "http://flightgear.org/crash-privacypolicy.html"; 
212   
213         // Install crash reporting
214         int nResult = crInstall(&info);    
215         if(nResult!=0) {
216                 char buf[1024];
217                 crGetLastErrorMsg(buf, 1024);
218                 flightgear::modalMessageBox("CrashRpt setup failed", 
219                         "Failed to setup crash-reporting engine, check the installation is not damaged.",
220                         buf);
221         } else {
222                 global_crashRptEnabled = true;
223
224                 crAddProperty("hudson-build-id", HUDSON_BUILD_ID);
225                 char buf[16];
226                 ::snprintf(buf, 16, "%d", HUDSON_BUILD_NUMBER);
227                 crAddProperty("hudson-build-number", buf);
228         }
229 #endif
230
231 #if defined(__FreeBSD__)
232     // Ignore floating-point exceptions on FreeBSD
233     signal(SIGFPE, SIG_IGN); 
234 #else
235     // Maybe Enable floating-point exceptions on Linux
236     for (int i = 0; i < argc; ++i) {
237         if (!strcmp("--enable-fpe", argv[i])) {
238             fpeAbort = true;
239             break;
240         }
241     }
242     initFPE();
243 #endif
244
245     // Enable floating-point exceptions for Windows
246 #if defined( _MSC_VER ) && defined( DEBUG )
247     // Christian, we should document what this does
248     _control87( _EM_INEXACT, _MCW_EM );
249 #endif
250
251     bool fgviewer = false;
252     for (int i = 0; i < argc; ++i) {
253         if (!strcmp("--fgviewer", argv[i])) {
254             fgviewer = true;
255             break;
256         }
257     }
258
259     // FIXME: add other, more specific
260     // exceptions.
261     try {
262         // http://code.google.com/p/flightgear-bugs/issues/detail?id=1231
263         // ensure sglog is inited before atexit() is registered, so logging
264         // is possible inside fgExitCleanup
265         sglog();
266         
267         // similar to above, ensure some static maps inside OSG exist before
268         // we register our at-exit handler, otherwise the statics are gone
269         // when fg_terminate runs, which causes crashes.
270         osg::Texture::getTextureObjectManager(0);
271         osg::GLBufferObjectManager::getGLBufferObjectManager(0);
272         
273         std::set_terminate(fg_terminate);
274         atexit(fgExitCleanup);
275         if (fgviewer)
276             fgviewerMain(argc, argv);
277         else
278             fgMainInit(argc, argv);
279            
280     } catch (const sg_throwable &t) {
281         std::string info;
282         if (std::strlen(t.getOrigin()) != 0)
283             info = std::string("received from ") + t.getOrigin();
284         flightgear::fatalMessageBox("Fatal exception", t.getFormattedMessage(), info);
285
286     } catch (const std::exception &e ) {
287         flightgear::fatalMessageBox("Fatal exception", e.what());
288     } catch (const std::string &s) {
289         flightgear::fatalMessageBox("Fatal exception", s);
290     } catch (const char *s) {
291         cerr << "Fatal error (const char*): " << s << endl;
292
293     } catch (...) {
294         cerr << "Unknown exception in the main loop. Aborting..." << endl;
295         if (errno)
296             perror("Possible cause");
297     }
298
299 #if defined(HAVE_CRASHRPT)
300         crUninstall();
301 #endif
302
303     return 0;
304 }
305
306 // do some clean up on exit.  Specifically we want to delete the sound-manager,
307 // so OpenAL device and context are released cleanly
308 void fgExitCleanup() {
309
310     if (_bootstrap_OSInit != 0) {
311         fgSetMouseCursor(MOUSE_CURSOR_POINTER);
312
313         fgOSCloseWindow();
314     }
315     
316     // on the common exit path globals is already deleted, and NULL,
317     // so this only happens on error paths.
318     delete globals;
319 }
320