]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/app.cpp
Triued in vain to fix threads segvs with gcc
[wxWidgets.git] / src / gtk / app.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: app.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #ifdef __GNUG__
11 #pragma implementation "app.h"
12 #endif
13
14 #include "wx/app.h"
15 #include "wx/gdicmn.h"
16 #include "wx/utils.h"
17 #include "wx/intl.h"
18 #include "wx/log.h"
19 #include "wx/memory.h"
20 #include "wx/font.h"
21 #include "wx/settings.h"
22 #include "wx/resource.h"
23 #include "wx/module.h"
24 #include "wx/image.h"
25 #include "wx/thread.h"
26
27 #include "unistd.h"
28
29 #include "glib.h"
30 #include "gdk/gdk.h"
31 #include "gtk/gtk.h"
32 #include "wx/gtk/win_gtk.h"
33
34 //-----------------------------------------------------------------------------
35 // global data
36 //-----------------------------------------------------------------------------
37
38 wxApp *wxTheApp = (wxApp *) NULL;
39 wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
40
41 extern wxList wxPendingDelete;
42 extern wxResourceCache *wxTheResourceCache;
43
44 unsigned char g_palette[64*3] =
45 {
46 0x0, 0x0, 0x0,
47 0xff, 0xff, 0xff,
48 0xff, 0x0, 0x0,
49 0xff, 0xff, 0x0,
50 0x0, 0xff, 0x0,
51 0x0, 0x0, 0xff,
52 0x0, 0xff, 0xff,
53 0x99, 0x99, 0x99,
54 0xff, 0x88, 0x0,
55 0x88, 0x0, 0x0,
56 0x0, 0x88, 0x88,
57 0x88, 0x88, 0x0,
58 0xff, 0xcc, 0x97,
59 0xbb, 0xbb, 0xbb,
60 0x9f, 0x6b, 0x42,
61 0x55, 0x55, 0x55,
62 0xdd, 0xdd, 0xdd,
63 0x77, 0x77, 0x77,
64 0x33, 0x33, 0x33,
65 0xcc, 0x0, 0x0,
66 0xff, 0x44, 0x0,
67 0xff, 0xcc, 0x0,
68 0xcc, 0xcc, 0x0,
69 0x60, 0x60, 0x0,
70 0x0, 0x43, 0x0,
71 0x0, 0x7f, 0x0,
72 0x0, 0xcc, 0x0,
73 0x0, 0x44, 0x44,
74 0x0, 0x0, 0x44,
75 0x0, 0x0, 0x88,
76 0xef, 0xb1, 0x7b,
77 0xdf, 0x98, 0x5f,
78 0xbf, 0x87, 0x56,
79 0x7f, 0x57, 0x26,
80 0x5f, 0x39, 0xc,
81 0x3f, 0x1c, 0x0,
82 0x21, 0x0, 0x0,
83 0x0, 0x43, 0x87,
84 0x2d, 0x70, 0xaf,
85 0x5a, 0x9e, 0xd7,
86 0x87, 0xcc, 0xff,
87 0xff, 0xe0, 0xba,
88 0x21, 0x43, 0xf,
89 0x3d, 0x5d, 0x25,
90 0x59, 0x78, 0x3a,
91 0x75, 0x93, 0x4f,
92 0x91, 0xae, 0x64,
93 0xad, 0xc8, 0x7a,
94 0xf0, 0xa8, 0xef,
95 0xd0, 0x88, 0xd0,
96 0xaf, 0x66, 0xaf,
97 0x8e, 0x44, 0x8e,
98 0x6d, 0x22, 0x6d,
99 0x4b, 0x0, 0x4b,
100 0xff, 0xc0, 0xbc,
101 0xff, 0x93, 0x91,
102 0xff, 0x66, 0x67,
103 0xd8, 0xf2, 0xbf,
104 0xff, 0xc9, 0x68,
105 0xff, 0x96, 0x67,
106 0xa5, 0x60, 0xff,
107 0x51, 0xff, 0x99,
108 0x3f, 0xa5, 0x63,
109 0x98, 0x90, 0x67
110 };
111
112 //-----------------------------------------------------------------------------
113 // local functions
114 //-----------------------------------------------------------------------------
115
116 extern void wxFlushResources(void);
117
118 //-----------------------------------------------------------------------------
119 // global functions
120 //-----------------------------------------------------------------------------
121
122 void wxExit(void)
123 {
124 gtk_main_quit();
125 }
126
127 bool wxYield(void)
128 {
129 while (gtk_events_pending() > 0) gtk_main_iteration();
130 return TRUE;
131 }
132
133 //-----------------------------------------------------------------------------
134 // wxApp
135 //-----------------------------------------------------------------------------
136
137 IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
138
139 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
140 EVT_IDLE(wxApp::OnIdle)
141 END_EVENT_TABLE()
142
143 gint wxapp_idle_callback( gpointer WXUNUSED(data) )
144 {
145 if (wxTheApp) while (wxTheApp->ProcessIdle()) {}
146 wxMutexGuiLeave();
147 usleep(10000);
148 wxMutexGuiEnter();
149 return TRUE;
150 }
151
152 wxApp::wxApp()
153 {
154 m_idleTag = 0;
155 m_topWindow = (wxWindow *) NULL;
156 m_exitOnFrameDelete = TRUE;
157 wxTheApp = this;
158 }
159
160 wxApp::~wxApp(void)
161 {
162 gtk_idle_remove( m_idleTag );
163 }
164
165 bool wxApp::OnInit(void)
166 {
167 return TRUE;
168 }
169
170 bool wxApp::OnInitGui(void)
171 {
172 m_idleTag = gtk_idle_add( wxapp_idle_callback, NULL );
173 return TRUE;
174 }
175
176 int wxApp::OnRun(void)
177 {
178 return MainLoop();
179 }
180
181 bool wxApp::ProcessIdle(void)
182 {
183 wxIdleEvent event;
184 event.SetEventObject( this );
185 ProcessEvent( event );
186
187 return event.MoreRequested();
188 }
189
190 void wxApp::OnIdle( wxIdleEvent &event )
191 {
192 static bool inOnIdle = FALSE;
193
194 /* Avoid recursion (via ProcessEvent default case) */
195 if (inOnIdle)
196 return;
197
198 inOnIdle = TRUE;
199
200 /* 'Garbage' collection of windows deleted with Close(). */
201 DeletePendingObjects();
202
203 /* flush the logged messages if any */
204 wxLog *log = wxLog::GetActiveTarget();
205 if (log != NULL && log->HasPendingMessages())
206 log->Flush();
207
208 /* Send OnIdle events to all windows */
209 bool needMore = SendIdleEvents();
210
211 if (needMore)
212 event.RequestMore(TRUE);
213
214 inOnIdle = FALSE;
215 }
216
217 bool wxApp::SendIdleEvents(void)
218 {
219 bool needMore = FALSE;
220
221 wxNode* node = wxTopLevelWindows.First();
222 while (node)
223 {
224 wxWindow* win = (wxWindow*) node->Data();
225 if (SendIdleEvents(win))
226 needMore = TRUE;
227 node = node->Next();
228 }
229 return needMore;
230 }
231
232 bool wxApp::SendIdleEvents( wxWindow* win )
233 {
234 bool needMore = FALSE;
235
236 wxIdleEvent event;
237 event.SetEventObject(win);
238 win->ProcessEvent(event);
239
240 if (event.MoreRequested())
241 needMore = TRUE;
242
243 wxNode* node = win->GetChildren().First();
244 while (node)
245 {
246 wxWindow* win = (wxWindow*) node->Data();
247 if (SendIdleEvents(win))
248 needMore = TRUE;
249
250 node = node->Next();
251 }
252 return needMore ;
253 }
254
255 int wxApp::OnExit(void)
256 {
257 return 0;
258 }
259
260 int wxApp::MainLoop(void)
261 {
262 gtk_main();
263 return 0;
264 }
265
266 void wxApp::ExitMainLoop(void)
267 {
268 gtk_main_quit();
269 }
270
271 bool wxApp::Initialized(void)
272 {
273 return m_initialized;
274 }
275
276 bool wxApp::Pending(void)
277 {
278 return FALSE;
279 }
280
281 void wxApp::Dispatch(void)
282 {
283 }
284
285 void wxApp::DeletePendingObjects(void)
286 {
287 wxNode *node = wxPendingDelete.First();
288 while (node)
289 {
290 wxObject *obj = (wxObject *)node->Data();
291
292 delete obj;
293
294 if (wxPendingDelete.Member(obj))
295 delete node;
296
297 node = wxPendingDelete.First();
298 }
299 }
300
301 wxWindow *wxApp::GetTopWindow(void)
302 {
303 if (m_topWindow) return m_topWindow;
304 wxNode *node = wxTopLevelWindows.First();
305 if (!node) return (wxWindow *) NULL;
306 return (wxWindow*)node->Data();
307 }
308
309 void wxApp::SetTopWindow( wxWindow *win )
310 {
311 m_topWindow = win;
312 }
313
314 void wxApp::CommonInit(void)
315 {
316
317 /*
318 #if wxUSE_RESOURCES
319 (void) wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
320 #endif
321 */
322 wxSystemSettings::Init();
323 wxTheResourceCache = new wxResourceCache(wxKEY_STRING);
324
325 wxTheFontNameDirectory = new wxFontNameDirectory;
326 wxTheFontNameDirectory->Initialize();
327
328 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
329 wxTheColourDatabase->Initialize();
330
331 wxInitializeStockLists();
332 wxInitializeStockObjects();
333
334 wxInitializeResourceSystem();
335
336 wxImage::InitStandardHandlers();
337
338 // g_globalCursor = new wxCursor;
339 }
340
341 void wxApp::CommonCleanUp(void)
342 {
343 wxDELETE(wxTheColourDatabase);
344 wxDELETE(wxTheFontNameDirectory);
345 wxDeleteStockObjects();
346
347 wxFlushResources();
348
349 wxDELETE(wxTheResourceCache);
350
351 wxDeleteStockLists();
352
353 wxCleanUpResourceSystem();
354
355 wxImage::CleanUpHandlers();
356
357 wxSystemSettings::Done();
358 }
359
360 wxLog *wxApp::CreateLogTarget()
361 {
362 return new wxLogGui;
363 }
364
365 //-----------------------------------------------------------------------------
366 // wxEntry
367 //-----------------------------------------------------------------------------
368
369 int wxEntry( int argc, char *argv[] )
370 {
371 wxBuffer = new char[BUFSIZ + 512];
372
373 wxClassInfo::InitializeClasses();
374
375
376 if (!wxTheApp)
377 {
378 if (!wxApp::GetInitializerFunction())
379 {
380 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
381 return 0;
382 }
383
384 wxAppInitializerFunction app_ini = wxApp::GetInitializerFunction();
385
386 wxObject *test_app = app_ini();
387
388 wxTheApp = (wxApp*) test_app;
389 }
390
391 if (!wxTheApp)
392 {
393 printf( "wxWindows error: wxTheApp == NULL\n" );
394 return 0;
395 }
396
397 wxTheApp->argc = argc;
398 wxTheApp->argv = argv;
399
400 char name[200];
401 strcpy( name, argv[0] );
402 strcpy( name, wxFileNameFromPath(name) );
403 wxStripExtension( name );
404 wxTheApp->SetAppName( name );
405
406 gtk_set_locale();
407
408 gtk_init( &argc, &argv );
409
410 GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
411
412 for (int i = 0; i < 64; i++)
413 {
414 GdkColor col;
415 col.red = g_palette[i*3 + 0] << 8;
416 col.green = g_palette[i*3 + 1] << 8;
417 col.blue = g_palette[i*3 + 2] << 8;
418 col.pixel = 0;
419
420 gdk_color_alloc( cmap, &col );
421 }
422
423 gtk_widget_push_colormap( cmap );
424
425 gtk_widget_set_default_colormap( cmap );
426
427 wxApp::CommonInit();
428
429 wxModule::RegisterModules();
430 if (!wxModule::InitializeModules()) return FALSE;
431
432 wxTheApp->OnInitGui();
433
434 // Here frames insert themselves automatically
435 // into wxTopLevelWindows by getting created
436 // in OnInit().
437
438 if (!wxTheApp->OnInit()) return 0;
439
440 wxTheApp->m_initialized = (wxTopLevelWindows.Number() > 0);
441
442 int retValue = 0;
443
444 if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
445
446 wxTheApp->DeletePendingObjects();
447
448 wxTheApp->OnExit();
449
450 wxModule::CleanUpModules();
451
452 wxApp::CommonCleanUp();
453
454 delete wxTheApp;
455 wxTheApp = (wxApp*) NULL;
456
457 wxClassInfo::CleanUpClasses();
458
459 delete[] wxBuffer;
460
461 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
462
463 if (wxDebugContext::CountObjectsLeft() > 0)
464 {
465 wxLogDebug("There were memory leaks.\n");
466 wxDebugContext::Dump();
467 wxDebugContext::PrintStatistics();
468 }
469
470 #endif
471
472 wxLog *oldLog = wxLog::SetActiveTarget( NULL );
473 if (oldLog) delete oldLog;
474
475 return retValue;
476 }
477
478 //-----------------------------------------------------------------------------
479