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