]> git.saurik.com Git - wxWidgets.git/blob - src/stubs/app.cpp
Simplified app initialisation in wxMSW and wxStubs
[wxWidgets.git] / src / stubs / app.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: app.cpp
3 // Purpose: wxApp
4 // Author: AUTHOR
5 // Modified by:
6 // Created: ??/??/98
7 // RCS-ID: $Id$
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "app.h"
14 #endif
15
16 #include "wx/frame.h"
17 #include "wx/app.h"
18 #include "wx/utils.h"
19 #include "wx/gdicmn.h"
20 #include "wx/pen.h"
21 #include "wx/brush.h"
22 #include "wx/cursor.h"
23 #include "wx/icon.h"
24 #include "wx/palette.h"
25 #include "wx/dc.h"
26 #include "wx/dialog.h"
27 #include "wx/msgdlg.h"
28 #include "wx/log.h"
29 #include "wx/module.h"
30 #include "wx/memory.h"
31
32 #if USE_WX_RESOURCES
33 #include "wx/resource.h"
34 #endif
35
36 #if USE_POSTSCRIPT
37 #include "wx/postscrp.h"
38 #endif
39
40 #include <string.h>
41
42 extern char *wxBuffer;
43 extern wxList wxPendingDelete;
44
45 wxApp *wxTheApp = NULL;
46
47 #if !USE_SHARED_LIBRARY
48 IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
49 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
50 EVT_IDLE(wxApp::OnIdle)
51 END_EVENT_TABLE()
52 #endif
53
54 long wxApp::sm_lastMessageTime = 0;
55
56 bool wxApp::Initialize()
57 {
58 #ifdef __WXMSW__
59 wxBuffer = new char[1500];
60 #else
61 wxBuffer = new char[BUFSIZ + 512];
62 #endif
63
64 #if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
65
66 streambuf* sBuf = new wxDebugStreamBuf;
67 ostream* oStr = new ostream(sBuf) ;
68 wxDebugContext::SetStream(oStr, sBuf);
69
70 #endif
71
72 wxClassInfo::InitializeClasses();
73
74 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
75 wxTheColourDatabase->Initialize();
76 wxInitializeStockObjects();
77
78 #if USE_WX_RESOURCES
79 wxInitializeResourceSystem();
80 #endif
81
82 // For PostScript printing
83 #if USE_POSTSCRIPT
84 wxInitializePrintSetupData();
85 wxThePrintPaperDatabase = new wxPrintPaperDatabase;
86 wxThePrintPaperDatabase->CreateDatabase();
87 #endif
88
89 wxBitmap::InitStandardHandlers();
90
91 wxModule::RegisterModules();
92 wxASSERT( wxModule::InitializeModules() == TRUE );
93
94 return TRUE;
95 }
96
97 void wxApp::CleanUp()
98 {
99 wxModule::CleanUpModules();
100
101 #if USE_WX_RESOURCES
102 wxCleanUpResourceSystem();
103 #endif
104
105 wxDeleteStockObjects() ;
106
107 // Destroy all GDI lists, etc.
108
109 delete wxTheBrushList;
110 wxTheBrushList = NULL;
111
112 delete wxThePenList;
113 wxThePenList = NULL;
114
115 delete wxTheFontList;
116 wxTheFontList = NULL;
117
118 delete wxTheBitmapList;
119 wxTheBitmapList = NULL;
120
121 delete wxTheColourDatabase;
122 wxTheColourDatabase = NULL;
123
124 #if USE_POSTSCRIPT
125 wxInitializePrintSetupData(FALSE);
126 delete wxThePrintPaperDatabase;
127 wxThePrintPaperDatabase = NULL;
128 #endif
129
130 wxBitmap::CleanUpHandlers();
131
132 delete[] wxBuffer;
133 wxBuffer = NULL;
134
135 wxClassInfo::CleanUpClasses();
136
137 // do it as the very last thing because everything else can log messages
138 wxLog::DontCreateOnDemand();
139 // do it as the very last thing because everything else can log messages
140 delete wxLog::SetActiveTarget(NULL);
141 }
142
143 int wxEntry( int argc, char *argv[] )
144 {
145 if (!wxApp::Initialize())
146 return FALSE;
147 if (!wxTheApp)
148 {
149 if (!wxApp::GetInitializerFunction())
150 {
151 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
152 return 0;
153 };
154
155 wxTheApp = (wxApp*) (* wxApp::GetInitializerFunction()) ();
156 };
157
158 if (!wxTheApp)
159 {
160 printf( "wxWindows error: wxTheApp == NULL\n" );
161 return 0;
162 };
163
164 wxTheApp->argc = argc;
165 wxTheApp->argv = argv;
166
167 // GUI-specific initialization, such as creating an app context.
168 wxTheApp->OnInitGui();
169
170 // Here frames insert themselves automatically
171 // into wxTopLevelWindows by getting created
172 // in OnInit().
173
174 if (!wxTheApp->OnInit()) return 0;
175
176 int retValue = 0;
177
178 if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
179
180 if (wxTheApp->GetTopWindow())
181 {
182 delete wxTheApp->GetTopWindow();
183 wxTheApp->SetTopWindow(NULL);
184 }
185
186 wxTheApp->DeletePendingObjects();
187
188 wxTheApp->OnExit();
189
190 wxApp::CleanUp();
191
192 delete wxTheApp;
193 wxTheApp = NULL;
194
195 #if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
196 // At this point we want to check if there are any memory
197 // blocks that aren't part of the wxDebugContext itself,
198 // as a special case. Then when dumping we need to ignore
199 // wxDebugContext, too.
200 if (wxDebugContext::CountObjectsLeft() > 0)
201 {
202 wxTrace("There were memory leaks.\n");
203 wxDebugContext::Dump();
204 wxDebugContext::PrintStatistics();
205 }
206 wxDebugContext::SetStream(NULL, NULL);
207 #endif
208
209 return retValue;
210 };
211
212 // Static member initialization
213 wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
214
215 wxApp::wxApp()
216 {
217 m_topWindow = NULL;
218 wxTheApp = this;
219 m_className = "";
220 m_wantDebugOutput = TRUE ;
221 m_appName = "";
222 argc = 0;
223 argv = NULL;
224 #ifdef __WXMSW__
225 m_printMode = wxPRINT_WINDOWS;
226 #else
227 m_printMode = wxPRINT_POSTSCRIPT;
228 #endif
229 m_exitOnFrameDelete = TRUE;
230 m_auto3D = TRUE;
231 }
232
233 bool wxApp::Initialized()
234 {
235 if (GetTopWindow())
236 return TRUE;
237 else
238 return FALSE;
239 }
240
241 int wxApp::MainLoop()
242 {
243 m_keepGoing = TRUE;
244
245 /* TODO: implement your main loop here, calling ProcessIdle in idle time.
246 while (m_keepGoing)
247 {
248 while (!::PeekMessage(&s_currentMsg, 0, 0, 0, PM_NOREMOVE) &&
249 ProcessIdle()) {}
250 if (!DoMessage())
251 m_keepGoing = FALSE;
252 }
253 */
254
255 return 0;
256 }
257
258 // Returns TRUE if more time is needed.
259 bool wxApp::ProcessIdle()
260 {
261 wxIdleEvent event;
262 event.SetEventObject(this);
263 ProcessEvent(event);
264
265 return event.MoreRequested();
266 }
267
268 void wxApp::ExitMainLoop()
269 {
270 m_keepGoing = FALSE;
271 }
272
273 // Is a message/event pending?
274 bool wxApp::Pending()
275 {
276 /* TODO.
277 */
278 return FALSE;
279 }
280
281 // Dispatch a message.
282 void wxApp::Dispatch()
283 {
284 /* TODO.
285 */
286 }
287
288 void wxApp::OnIdle(wxIdleEvent& event)
289 {
290 static bool inOnIdle = FALSE;
291
292 // Avoid recursion (via ProcessEvent default case)
293 if (inOnIdle)
294 return;
295
296 inOnIdle = TRUE;
297
298 // 'Garbage' collection of windows deleted with Close().
299 DeletePendingObjects();
300
301 // flush the logged messages if any
302 wxLog *pLog = wxLog::GetActiveTarget();
303 if ( pLog != NULL && pLog->HasPendingMessages() )
304 pLog->Flush();
305
306 // Send OnIdle events to all windows
307 bool needMore = SendIdleEvents();
308
309 if (needMore)
310 event.RequestMore(TRUE);
311
312 inOnIdle = FALSE;
313 }
314
315 // Send idle event to all top-level windows
316 bool wxApp::SendIdleEvents()
317 {
318 bool needMore = FALSE;
319 wxNode* node = wxTopLevelWindows.First();
320 while (node)
321 {
322 wxWindow* win = (wxWindow*) node->Data();
323 if (SendIdleEvents(win))
324 needMore = TRUE;
325
326 node = node->Next();
327 }
328 return needMore;
329 }
330
331 // Send idle event to window and all subwindows
332 bool wxApp::SendIdleEvents(wxWindow* win)
333 {
334 bool needMore = FALSE;
335
336 wxIdleEvent event;
337 event.SetEventObject(win);
338 win->ProcessEvent(event);
339
340 if (event.MoreRequested())
341 needMore = TRUE;
342
343 wxNode* node = win->GetChildren()->First();
344 while (node)
345 {
346 wxWindow* win = (wxWindow*) node->Data();
347 if (SendIdleEvents(win))
348 needMore = TRUE;
349
350 node = node->Next();
351 }
352 return needMore ;
353 }
354
355 void wxApp::DeletePendingObjects()
356 {
357 wxNode *node = wxPendingDelete.First();
358 while (node)
359 {
360 wxObject *obj = (wxObject *)node->Data();
361
362 delete obj;
363
364 if (wxPendingDelete.Member(obj))
365 delete node;
366
367 // Deleting one object may have deleted other pending
368 // objects, so start from beginning of list again.
369 node = wxPendingDelete.First();
370 }
371 }
372
373 wxLog* wxApp::CreateLogTarget()
374 {
375 return new wxLogGui;
376 }
377
378 wxWindow* wxApp::GetTopWindow() const
379 {
380 if (m_topWindow)
381 return m_topWindow;
382 else if (wxTopLevelWindows.Number() > 0)
383 return (wxWindow*) wxTopLevelWindows.First()->Data();
384 else
385 return NULL;
386 }
387
388 void wxExit()
389 {
390 wxApp::CleanUp();
391 /*
392 * TODO: Exit in some platform-specific way. Not recommended that the app calls this:
393 * only for emergencies.
394 */
395 }
396
397 // Yield to other processes
398 bool wxYield()
399 {
400 /*
401 * TODO
402 */
403 return TRUE;
404 }
405