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