wxBase/GUI separation: 1st step, wxMSW should build, all the rest is broken
[wxWidgets.git] / src / common / init.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/init.cpp
3 // Purpose: initialisation for the library
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 04.10.99
7 // RCS-ID: $Id$
8 // Copyright: (c) Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif //__BORLANDC__
25
26 #ifndef WX_PRECOMP
27 #include "wx/app.h"
28 #include "wx/debug.h"
29 #include "wx/filefn.h"
30 #include "wx/log.h"
31 #endif
32
33 #include "wx/module.h"
34
35 // ----------------------------------------------------------------------------
36 // private classes
37 // ----------------------------------------------------------------------------
38
39 // we need a dummy app object if the user doesn't want to create a real one
40 class wxDummyConsoleApp : public wxApp
41 {
42 public:
43 virtual int OnRun() { wxFAIL_MSG( _T("unreachable code") ); return 0; }
44 };
45
46 // ----------------------------------------------------------------------------
47 // private functions
48 // ----------------------------------------------------------------------------
49
50 static bool DoInit();
51 static void DoCleanUp();
52
53 // ----------------------------------------------------------------------------
54 // private vars
55 // ----------------------------------------------------------------------------
56
57 static size_t gs_nInitCount = 0;
58
59 // ============================================================================
60 // implementation
61 // ============================================================================
62
63 // ----------------------------------------------------------------------------
64 // wxBase-specific functions
65 // ----------------------------------------------------------------------------
66
67 bool WXDLLEXPORT wxInitialize()
68 {
69 if ( gs_nInitCount )
70 {
71 // already initialized
72 return TRUE;
73 }
74
75 wxASSERT_MSG( !wxTheApp,
76 wxT("either call wxInitialize or create app, not both!") );
77
78 if ( !DoInit() )
79 {
80 return FALSE;
81 }
82
83 wxTheApp = new wxDummyConsoleApp;
84
85 if ( !wxTheApp )
86 {
87 return FALSE;
88 }
89
90 gs_nInitCount++;
91
92 return TRUE;
93 }
94
95 void WXDLLEXPORT wxUninitialize()
96 {
97 if ( !--gs_nInitCount )
98 {
99 DoCleanUp();
100 }
101 }
102
103 int wxEntry(int argc, char **argv)
104 {
105 // library initialization
106 if ( !DoInit() )
107 {
108 return -1;
109 }
110
111 // create the app
112 if ( !wxTheApp )
113 {
114 wxCHECK_MSG( wxApp::GetInitializerFunction(), -1,
115 wxT("No application object: use IMPLEMENT_APP macro.") );
116
117 wxAppInitializerFunction fnCreate = wxApp::GetInitializerFunction();
118
119 wxTheApp = (wxApp *)fnCreate();
120 }
121
122 wxCHECK_MSG( wxTheApp, -1, wxT("wxWindows error: no application object") );
123
124 // app preinitialization
125 wxTheApp->argc = argc;
126
127 #if wxUSE_UNICODE
128 wxTheApp->argv = new wxChar*[argc+1];
129 for ( int mb_argc = 0; mb_argc < argc; mb_argc++ )
130 {
131 wxTheApp->argv[mb_argc] = wxStrdup(wxConvLocal.cMB2WX(argv[mb_argc]));
132 }
133 wxTheApp->argv[mb_argc] = (wxChar *)NULL;
134 #else
135 wxTheApp->argv = argv;
136 #endif
137
138 wxString name = wxFileNameFromPath(wxTheApp->argv[0]);
139 wxStripExtension(name);
140 wxTheApp->SetAppName(name);
141
142 int retValue = 0;
143
144 // app initialization
145 if ( !wxTheApp->OnInit() )
146 retValue = -1;
147
148 // app execution
149 if ( retValue == 0 )
150 {
151 retValue = wxTheApp->OnRun();
152
153 // app clean up
154 wxTheApp->OnExit();
155 }
156
157 // library clean up
158 DoCleanUp();
159
160 return retValue;
161 }
162
163 // ----------------------------------------------------------------------------
164 // private functions
165 // ----------------------------------------------------------------------------
166
167 static bool DoInit()
168 {
169 wxClassInfo::InitializeClasses();
170
171 wxModule::RegisterModules();
172 if ( !wxModule::InitializeModules() )
173 {
174 return FALSE;
175 }
176
177 return TRUE;
178 }
179
180 static void DoCleanUp()
181 {
182 #if wxUSE_LOG
183 // flush the logged messages if any
184 wxLog *log = wxLog::GetActiveTarget();
185 if (log != NULL && log->HasPendingMessages())
186 log->Flush();
187
188 // continuing to use user defined log target is unsafe from now on because
189 // some resources may be already unavailable, so replace it by something
190 // more safe
191 wxLog::DontCreateOnDemand();
192 delete wxLog::SetActiveTarget(new wxLogStderr);
193 #endif // wxUSE_LOG
194
195 wxModule::CleanUpModules();
196
197 wxClassInfo::CleanUpClasses();
198
199 // TODO: this should really be done in ~wxApp
200 #if wxUSE_UNICODE
201 for ( int mb_argc = 0; mb_argc < wxTheApp->argc; mb_argc++ )
202 {
203 free(wxTheApp->argv[mb_argc]);
204 }
205 #endif // wxUSE_UNICODE
206
207 // delete the application object
208 delete wxTheApp;
209 wxTheApp = (wxApp *)NULL;
210
211 #if wxUSE_LOG
212 // and now delete the last logger as well
213 delete wxLog::SetActiveTarget(NULL);
214 #endif // wxUSE_LOG
215 }
216