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