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