]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/app.cpp
check that wxTheApp != NULL in wxLog::GetActiveTarget
[wxWidgets.git] / src / gtk / app.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: app.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Created: 01/02/97
6 // Id:
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #ifdef __GNUG__
12 #pragma implementation "app.h"
13 #endif
14
15 #include "wx/app.h"
16 #include "wx/gdicmn.h"
17 #include "wx/utils.h"
18 #include "wx/postscrp.h"
19 #include "wx/intl.h"
20 #include "wx/log.h"
21 #include "wx/memory.h"
22
23 #include "unistd.h"
24
25 #ifdef USE_GDK_IMLIB
26 #include "../gdk_imlib/gdk_imlib.h"
27 #endif
28
29 //-----------------------------------------------------------------------------
30 // global data
31 //-----------------------------------------------------------------------------
32
33 wxApp *wxTheApp = NULL;
34 wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
35
36 extern wxList wxPendingDelete;
37
38 //-----------------------------------------------------------------------------
39 // local functions
40 //-----------------------------------------------------------------------------
41
42 extern void wxFlushResources(void);
43
44 //-----------------------------------------------------------------------------
45 // global functions
46 //-----------------------------------------------------------------------------
47
48 void wxExit(void)
49 {
50 gtk_main_quit();
51 };
52
53 bool wxYield(void)
54 {
55 while (gtk_events_pending() > 0) gtk_main_iteration();
56 return TRUE;
57 };
58
59 //-----------------------------------------------------------------------------
60 // wxApp
61 //-----------------------------------------------------------------------------
62
63 IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
64
65 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
66 EVT_IDLE(wxApp::OnIdle)
67 END_EVENT_TABLE()
68
69 gint wxapp_idle_callback( gpointer WXUNUSED(data) )
70 {
71 if (wxTheApp) while (wxTheApp->ProcessIdle()) {};
72 usleep( 10000 );
73 return TRUE;
74 };
75
76 wxApp::wxApp()
77 {
78 m_idleTag = 0;
79 m_topWindow = NULL;
80 m_exitOnFrameDelete = TRUE;
81 };
82
83 wxApp::~wxApp(void)
84 {
85 gtk_idle_remove( m_idleTag );
86 };
87
88 bool wxApp::OnInit(void)
89 {
90 return TRUE;
91 };
92
93 bool wxApp::OnInitGui(void)
94 {
95 m_idleTag = gtk_idle_add( wxapp_idle_callback, NULL );
96 return TRUE;
97 };
98
99 int wxApp::OnRun(void)
100 {
101 return MainLoop();
102 };
103
104 bool wxApp::ProcessIdle(void)
105 {
106 wxIdleEvent event;
107 event.SetEventObject( this );
108 ProcessEvent( event );
109
110 return event.MoreRequested();
111 };
112
113 void wxApp::OnIdle( wxIdleEvent &event )
114 {
115 static bool inOnIdle = FALSE;
116
117 // Avoid recursion (via ProcessEvent default case)
118 if (inOnIdle)
119 return;
120
121 inOnIdle = TRUE;
122
123 // 'Garbage' collection of windows deleted with Close().
124 DeletePendingObjects();
125
126 // flush the logged messages if any
127 wxLog *pLog = wxLog::GetActiveTarget();
128 if ( pLog != NULL && pLog->HasPendingMessages() )
129 pLog->Flush();
130
131 // Send OnIdle events to all windows
132 bool needMore = SendIdleEvents();
133
134 if (needMore)
135 event.RequestMore(TRUE);
136
137 inOnIdle = FALSE;
138 };
139
140 bool wxApp::SendIdleEvents(void)
141 {
142 bool needMore = FALSE;
143 wxNode* node = wxTopLevelWindows.First();
144 while (node)
145 {
146 wxWindow* win = (wxWindow*) node->Data();
147 if (SendIdleEvents(win))
148 needMore = TRUE;
149
150 node = node->Next();
151 }
152 return needMore;
153 };
154
155 bool wxApp::SendIdleEvents( wxWindow* win )
156 {
157 bool needMore = FALSE;
158
159 wxIdleEvent event;
160 event.SetEventObject(win);
161 win->ProcessEvent(event);
162
163 if (event.MoreRequested())
164 needMore = TRUE;
165
166 wxNode* node = win->GetChildren()->First();
167 while (node)
168 {
169 wxWindow* win = (wxWindow*) node->Data();
170 if (SendIdleEvents(win))
171 needMore = TRUE;
172
173 node = node->Next();
174 }
175 return needMore ;
176 };
177
178 int wxApp::OnExit(void)
179 {
180 return 0;
181 };
182
183 int wxApp::MainLoop(void)
184 {
185 gtk_main();
186 return 0;
187 };
188
189 void wxApp::ExitMainLoop(void)
190 {
191 gtk_main_quit();
192 };
193
194 bool wxApp::Initialized(void)
195 {
196 return m_initialized;
197 };
198
199 bool wxApp::Pending(void)
200 {
201 return FALSE;
202 };
203
204 void wxApp::Dispatch(void)
205 {
206 };
207
208 void wxApp::DeletePendingObjects(void)
209 {
210 wxNode *node = wxPendingDelete.First();
211 while (node)
212 {
213 wxObject *obj = (wxObject *)node->Data();
214
215 delete obj;
216
217 if (wxPendingDelete.Member(obj))
218 delete node;
219
220 node = wxPendingDelete.First();
221 };
222 };
223
224 wxWindow *wxApp::GetTopWindow(void)
225 {
226 if (m_topWindow) return m_topWindow;
227 wxNode *node = wxTopLevelWindows.First();
228 if (!node) return NULL;
229 return (wxWindow*)node->Data();
230 };
231
232 void wxApp::SetTopWindow( wxWindow *win )
233 {
234 m_topWindow = win;
235 };
236
237 void wxApp::CommonInit(void)
238 {
239
240 /*
241 #if USE_RESOURCES
242 (void) wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
243 #endif
244 */
245
246 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
247 wxTheColourDatabase->Initialize();
248 wxInitializeStockObjects();
249
250 // For PostScript printing
251 #if USE_POSTSCRIPT
252 wxInitializePrintSetupData();
253 wxThePrintPaperDatabase = new wxPrintPaperDatabase;
254 wxThePrintPaperDatabase->CreateDatabase();
255 #endif
256
257
258 /*
259 wxBitmap::InitStandardHandlers();
260
261 g_globalCursor = new wxCursor;
262 */
263
264 wxInitializeStockObjects();
265 };
266
267 void wxApp::CommonCleanUp(void)
268 {
269 wxDeleteStockObjects();
270
271 wxFlushResources();
272 };
273
274 wxLog *wxApp::CreateLogTarget()
275 {
276 return new wxLogGui;
277 }
278
279 //-----------------------------------------------------------------------------
280 // wxEntry
281 //-----------------------------------------------------------------------------
282
283 int wxEntry( int argc, char *argv[] )
284 {
285 wxBuffer = new char[BUFSIZ + 512];
286
287 wxClassInfo::InitializeClasses();
288
289 #if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
290
291 #if !defined(_WINDLL)
292 streambuf* sBuf = new wxDebugStreamBuf;
293 #else
294 streambuf* sBuf = NULL;
295 #endif
296 ostream* oStr = new ostream(sBuf) ;
297 wxDebugContext::SetStream(oStr, sBuf);
298
299 #endif
300
301 if (!wxTheApp)
302 {
303 if (!wxApp::GetInitializerFunction())
304 {
305 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
306 return 0;
307 };
308
309 wxAppInitializerFunction app_ini = wxApp::GetInitializerFunction();
310
311 wxObject *test_app = app_ini();
312
313 wxTheApp = (wxApp*) test_app;
314
315 // wxTheApp = (wxApp*)( app_ini() );
316 };
317
318 if (!wxTheApp)
319 {
320 printf( "wxWindows error: wxTheApp == NULL\n" );
321 return 0;
322 };
323
324 // printf( "Programmstart.\n" );
325
326 wxTheApp->argc = argc;
327 wxTheApp->argv = argv;
328
329 gtk_init( &argc, &argv );
330
331 #ifdef USE_GDK_IMLIB
332
333 gdk_imlib_init();
334
335 gtk_widget_push_visual(gdk_imlib_get_visual());
336
337 gtk_widget_push_colormap(gdk_imlib_get_colormap());
338
339 #endif
340
341 wxApp::CommonInit();
342
343 wxTheApp->OnInitGui();
344
345 // Here frames insert themselves automatically
346 // into wxTopLevelWindows by getting created
347 // in OnInit().
348
349 if (!wxTheApp->OnInit()) return 0;
350
351 wxTheApp->m_initialized = (wxTopLevelWindows.Number() > 0);
352
353 int retValue = 0;
354
355 if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
356
357 wxTheApp->DeletePendingObjects();
358
359 wxTheApp->OnExit();
360
361 wxApp::CommonCleanUp();
362
363 #if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
364 // At this point we want to check if there are any memory
365 // blocks that aren't part of the wxDebugContext itself,
366 // as a special case. Then when dumping we need to ignore
367 // wxDebugContext, too.
368 if (wxDebugContext::CountObjectsLeft() > 0)
369 {
370 wxTrace("There were memory leaks.\n");
371 wxDebugContext::Dump();
372 wxDebugContext::PrintStatistics();
373 }
374 wxDebugContext::SetStream(NULL, NULL);
375 #endif
376
377 return retValue;
378 };
379
380 //-----------------------------------------------------------------------------
381 // main()
382 //-----------------------------------------------------------------------------
383
384 #if defined(AIX) || defined(AIX4) || defined(____HPUX__)
385
386 // main in IMPLEMENT_WX_MAIN in IMPLEMENT_APP in app.h
387
388 #else
389
390 int main(int argc, char *argv[]) { return wxEntry(argc, argv); }
391
392 #endif
393
394