]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/app.cpp
no message
[wxWidgets.git] / src / gtk / app.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: app.cpp
3// Purpose:
4// Author: Robert Roebling
32e9da8b 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling, Julian Smart
8bbe427f 7// Licence: wxWindows licence
c801d85f
KB
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"
c801d85f
KB
17#include "wx/intl.h"
18#include "wx/log.h"
46dc76ba 19#include "wx/memory.h"
a3622daa
VZ
20#include "wx/font.h"
21#include "wx/settings.h"
06cfab17 22#if wxUSE_WX_RESOURCES
8d71b555 23#include "wx/resource.h"
f5abe911 24#endif
031b2a7b 25#include "wx/module.h"
4bc67cc5 26#include "wx/image.h"
06cfab17 27#if wxUSE_THREADS
f3855ef0 28#include "wx/thread.h"
ac57418f 29#endif
c801d85f
KB
30#include "unistd.h"
31
83624f79
RR
32#include "glib.h"
33#include "gdk/gdk.h"
34#include "gtk/gtk.h"
35#include "wx/gtk/win_gtk.h"
36
c801d85f
KB
37//-----------------------------------------------------------------------------
38// global data
39//-----------------------------------------------------------------------------
40
c67daf87 41wxApp *wxTheApp = (wxApp *) NULL;
c801d85f
KB
42wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
43
44extern wxList wxPendingDelete;
a3622daa 45extern wxResourceCache *wxTheResourceCache;
c801d85f 46
01111366
RR
47unsigned 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,
e0253070 97 0xf0, 0xa8, 0xef,
01111366
RR
98 0xd0, 0x88, 0xd0,
99 0xaf, 0x66, 0xaf,
100 0x8e, 0x44, 0x8e,
101 0x6d, 0x22, 0x6d,
e0253070 102 0x4b, 0x0, 0x4b,
01111366
RR
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
c801d85f
KB
115//-----------------------------------------------------------------------------
116// local functions
117//-----------------------------------------------------------------------------
118
119extern void wxFlushResources(void);
120
121//-----------------------------------------------------------------------------
122// global functions
123//-----------------------------------------------------------------------------
124
125void wxExit(void)
126{
ec758a20 127 gtk_main_quit();
ff7b1510 128}
c801d85f
KB
129
130bool wxYield(void)
131{
ec758a20
RR
132 while (gtk_events_pending() > 0) gtk_main_iteration();
133 return TRUE;
ff7b1510 134}
c801d85f
KB
135
136//-----------------------------------------------------------------------------
137// wxApp
138//-----------------------------------------------------------------------------
139
140IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
141
53010e52
RR
142BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
143 EVT_IDLE(wxApp::OnIdle)
144END_EVENT_TABLE()
145
c801d85f
KB
146gint wxapp_idle_callback( gpointer WXUNUSED(data) )
147{
ec758a20 148 if (wxTheApp) while (wxTheApp->ProcessIdle()) {}
06cfab17 149#if wxUSE_THREADS
f3855ef0 150 wxMutexGuiLeave();
ac57418f 151#endif
f3855ef0 152 usleep(10000);
06cfab17 153#if wxUSE_THREADS
f3855ef0 154 wxMutexGuiEnter();
ac57418f 155#endif
ec758a20 156 return TRUE;
ff7b1510 157}
c801d85f
KB
158
159wxApp::wxApp()
160{
ec758a20
RR
161 m_idleTag = 0;
162 m_topWindow = (wxWindow *) NULL;
163 m_exitOnFrameDelete = TRUE;
164 wxTheApp = this;
ff7b1510 165}
c801d85f
KB
166
167wxApp::~wxApp(void)
168{
ec758a20 169 gtk_idle_remove( m_idleTag );
ff7b1510 170}
c801d85f 171
bbe0af5b 172bool wxApp::InitVisual()
c801d85f 173{
aae24d21
RR
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 */
bbe0af5b 181
aae24d21 182 GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
bbe0af5b 183
aae24d21
RR
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;
bbe0af5b 191
aae24d21 192 gdk_color_alloc( cmap, &col );
bbe0af5b 193 }
aae24d21
RR
194
195 gtk_widget_set_default_colormap( cmap );
bbe0af5b 196
ec758a20 197 return TRUE;
ff7b1510 198}
c801d85f
KB
199
200bool wxApp::OnInitGui(void)
0cf2cb36 201{
ec758a20 202 m_idleTag = gtk_idle_add( wxapp_idle_callback, NULL );
bbe0af5b
RR
203
204 return TRUE;
205}
206
207bool wxApp::OnInit(void)
208{
ec758a20 209 return TRUE;
ff7b1510 210}
c801d85f 211
0cf2cb36
RD
212int wxApp::OnRun(void)
213{
ec758a20 214 return MainLoop();
ff7b1510 215}
c801d85f 216
53010e52
RR
217bool wxApp::ProcessIdle(void)
218{
ec758a20
RR
219 wxIdleEvent event;
220 event.SetEventObject( this );
221 ProcessEvent( event );
0cf2cb36 222
ec758a20 223 return event.MoreRequested();
ff7b1510 224}
53010e52
RR
225
226void wxApp::OnIdle( wxIdleEvent &event )
c801d85f 227{
ec758a20 228 static bool inOnIdle = FALSE;
53010e52 229
d524867f 230 /* Avoid recursion (via ProcessEvent default case) */
ec758a20
RR
231 if (inOnIdle)
232 return;
53010e52 233
ec758a20 234 inOnIdle = TRUE;
53010e52 235
d524867f 236 /* 'Garbage' collection of windows deleted with Close(). */
ec758a20 237 DeletePendingObjects();
53010e52 238
d524867f
RR
239 /* flush the logged messages if any */
240 wxLog *log = wxLog::GetActiveTarget();
241 if (log != NULL && log->HasPendingMessages())
242 log->Flush();
53010e52 243
d524867f 244 /* Send OnIdle events to all windows */
ec758a20 245 bool needMore = SendIdleEvents();
53010e52 246
ec758a20
RR
247 if (needMore)
248 event.RequestMore(TRUE);
53010e52 249
ec758a20 250 inOnIdle = FALSE;
ff7b1510 251}
53010e52
RR
252
253bool wxApp::SendIdleEvents(void)
254{
255 bool needMore = FALSE;
e0253070 256
ec758a20
RR
257 wxNode* node = wxTopLevelWindows.First();
258 while (node)
259 {
f3855ef0
RR
260 wxWindow* win = (wxWindow*) node->Data();
261 if (SendIdleEvents(win))
53010e52 262 needMore = TRUE;
ec758a20
RR
263 node = node->Next();
264 }
53010e52 265 return needMore;
ff7b1510 266}
53010e52
RR
267
268bool wxApp::SendIdleEvents( wxWindow* win )
269{
270 bool needMore = FALSE;
271
8bbe427f
VZ
272 wxIdleEvent event;
273 event.SetEventObject(win);
274 win->ProcessEvent(event);
53010e52
RR
275
276 if (event.MoreRequested())
277 needMore = TRUE;
278
8bbe427f
VZ
279 wxNode* node = win->GetChildren().First();
280 while (node)
281 {
282 wxWindow* win = (wxWindow*) node->Data();
283 if (SendIdleEvents(win))
53010e52
RR
284 needMore = TRUE;
285
8bbe427f
VZ
286 node = node->Next();
287 }
53010e52 288 return needMore ;
ff7b1510 289}
c801d85f
KB
290
291int wxApp::OnExit(void)
292{
ec758a20 293 return 0;
ff7b1510 294}
c801d85f
KB
295
296int wxApp::MainLoop(void)
297{
ec758a20
RR
298 gtk_main();
299 return 0;
ff7b1510 300}
c801d85f
KB
301
302void wxApp::ExitMainLoop(void)
303{
ec758a20 304 gtk_main_quit();
ff7b1510 305}
c801d85f
KB
306
307bool wxApp::Initialized(void)
308{
ec758a20 309 return m_initialized;
ff7b1510 310}
c801d85f 311
0cf2cb36 312bool wxApp::Pending(void)
c801d85f 313{
ec758a20 314 return FALSE;
ff7b1510 315}
c801d85f 316
0cf2cb36 317void wxApp::Dispatch(void)
c801d85f 318{
ff7b1510 319}
c801d85f
KB
320
321void wxApp::DeletePendingObjects(void)
322{
ec758a20
RR
323 wxNode *node = wxPendingDelete.First();
324 while (node)
325 {
326 wxObject *obj = (wxObject *)node->Data();
0cf2cb36 327
ec758a20 328 delete obj;
c801d85f 329
ec758a20
RR
330 if (wxPendingDelete.Member(obj))
331 delete node;
c801d85f 332
ec758a20
RR
333 node = wxPendingDelete.First();
334 }
ff7b1510 335}
c801d85f
KB
336
337wxWindow *wxApp::GetTopWindow(void)
338{
ec758a20
RR
339 if (m_topWindow) return m_topWindow;
340 wxNode *node = wxTopLevelWindows.First();
341 if (!node) return (wxWindow *) NULL;
342 return (wxWindow*)node->Data();
ff7b1510 343}
c801d85f
KB
344
345void wxApp::SetTopWindow( wxWindow *win )
346{
ec758a20 347 m_topWindow = win;
ff7b1510 348}
c801d85f
KB
349
350void wxApp::CommonInit(void)
351{
a3622daa 352 wxSystemSettings::Init();
f5abe911 353
a3622daa
VZ
354 wxTheFontNameDirectory = new wxFontNameDirectory;
355 wxTheFontNameDirectory->Initialize();
c801d85f
KB
356
357 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
358 wxTheColourDatabase->Initialize();
a3622daa
VZ
359
360 wxInitializeStockLists();
c801d85f
KB
361 wxInitializeStockObjects();
362
06cfab17 363#if wxUSE_WX_RESOURCES
f5abe911
RR
364 wxTheResourceCache = new wxResourceCache(wxKEY_STRING);
365
8d71b555 366 wxInitializeResourceSystem();
f5abe911 367#endif
0cf2cb36 368
fd0eed64 369 wxImage::InitStandardHandlers();
e0253070 370
fd0eed64 371// g_globalCursor = new wxCursor;
ff7b1510 372}
c801d85f
KB
373
374void wxApp::CommonCleanUp(void)
375{
bbe0af5b
RR
376 if (wxTheColourDatabase) delete wxTheColourDatabase;
377 wxTheColourDatabase = (wxColourDatabase*) NULL;
378
379 if (wxTheFontNameDirectory) delete wxTheFontNameDirectory;
380 wxTheFontNameDirectory = (wxFontNameDirectory*) NULL;
381
ec758a20 382 wxDeleteStockObjects();
0cf2cb36 383
06cfab17 384#if wxUSE_WX_RESOURCES
ec758a20 385 wxFlushResources();
a3622daa 386
bbe0af5b
RR
387 if (wxTheResourceCache) delete wxTheResourceCache;
388 wxTheResourceCache = (wxResourceCache*) NULL;
f5abe911
RR
389
390 wxCleanUpResourceSystem();
391#endif
a3622daa 392
ec758a20 393 wxDeleteStockLists();
a3622daa 394
ec758a20 395 wxImage::CleanUpHandlers();
0cf2cb36 396
ec758a20 397 wxSystemSettings::Done();
ff7b1510 398}
0cf2cb36 399
c801d85f
KB
400wxLog *wxApp::CreateLogTarget()
401{
402 return new wxLogGui;
403}
404
405//-----------------------------------------------------------------------------
406// wxEntry
407//-----------------------------------------------------------------------------
408
409int wxEntry( int argc, char *argv[] )
410{
ec758a20 411 wxBuffer = new char[BUFSIZ + 512];
c801d85f 412
ec758a20 413 wxClassInfo::InitializeClasses();
0cf2cb36 414
0cf2cb36 415
ec758a20 416 if (!wxTheApp)
c801d85f 417 {
ec758a20
RR
418 if (!wxApp::GetInitializerFunction())
419 {
420 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
421 return 0;
422 }
0cf2cb36 423
ec758a20 424 wxAppInitializerFunction app_ini = wxApp::GetInitializerFunction();
0cf2cb36 425
ec758a20 426 wxObject *test_app = app_ini();
0cf2cb36 427
ec758a20
RR
428 wxTheApp = (wxApp*) test_app;
429 }
0cf2cb36 430
ec758a20
RR
431 if (!wxTheApp)
432 {
433 printf( "wxWindows error: wxTheApp == NULL\n" );
434 return 0;
435 }
c801d85f 436
ec758a20
RR
437 wxTheApp->argc = argc;
438 wxTheApp->argv = argv;
0cf2cb36 439
ec758a20
RR
440 char name[200];
441 strcpy( name, argv[0] );
442 strcpy( name, wxFileNameFromPath(name) );
443 wxStripExtension( name );
444 wxTheApp->SetAppName( name );
e0253070 445
ec758a20 446 gtk_set_locale();
e0253070 447
ec758a20 448 gtk_init( &argc, &argv );
c801d85f 449
bbe0af5b 450 if (!wxTheApp->InitVisual()) return 0;
e0253070 451
bbe0af5b
RR
452 wxApp::CommonInit();
453
454 if (!wxTheApp->OnInitGui()) return 0;
c801d85f 455
aae24d21
RR
456 wxModule::RegisterModules();
457 if (!wxModule::InitializeModules()) return FALSE;
458
ec758a20
RR
459 // Here frames insert themselves automatically
460 // into wxTopLevelWindows by getting created
461 // in OnInit().
0cf2cb36 462
ec758a20 463 if (!wxTheApp->OnInit()) return 0;
c801d85f 464
ec758a20 465 wxTheApp->m_initialized = (wxTopLevelWindows.Number() > 0);
0cf2cb36 466
ec758a20 467 int retValue = 0;
0cf2cb36 468
ec758a20 469 if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
0cf2cb36 470
ec758a20 471 wxTheApp->DeletePendingObjects();
0cf2cb36 472
ec758a20 473 wxTheApp->OnExit();
0cf2cb36 474
ec758a20 475 wxModule::CleanUpModules();
e0253070 476
ec758a20 477 wxApp::CommonCleanUp();
a3622daa 478
ec758a20
RR
479 delete wxTheApp;
480 wxTheApp = (wxApp*) NULL;
0cf2cb36 481
ec758a20 482 wxClassInfo::CleanUpClasses();
e0253070 483
ec758a20 484 delete[] wxBuffer;
e0253070 485
ea57084d 486#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
e0253070 487
ec758a20
RR
488 if (wxDebugContext::CountObjectsLeft() > 0)
489 {
490 wxLogDebug("There were memory leaks.\n");
491 wxDebugContext::Dump();
492 wxDebugContext::PrintStatistics();
493 }
e0253070 494
46dc76ba 495#endif
0cf2cb36 496
bbe0af5b 497 wxLog *oldLog = wxLog::SetActiveTarget( (wxLog*) NULL );
ec758a20 498 if (oldLog) delete oldLog;
184b5d99 499
ec758a20 500 return retValue;
ff7b1510 501}
1a56f55c 502