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