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