]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/app.cpp
Corrected some .tex problems
[wxWidgets.git] / src / gtk1 / 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"
0d2a2b60 22#include "wx/dialog.h"
06cfab17 23#if wxUSE_WX_RESOURCES
8d71b555 24#include "wx/resource.h"
f5abe911 25#endif
031b2a7b 26#include "wx/module.h"
4bc67cc5 27#include "wx/image.h"
06cfab17 28#if wxUSE_THREADS
f3855ef0 29#include "wx/thread.h"
ac57418f 30#endif
c801d85f
KB
31#include "unistd.h"
32
539dae52
VZ
33// many versions of Unices have this function, but it is not defined in system
34// headers - please add your system here if it is the case for your OS.
35// SunOS < 5.6 (i.e. Solaris < 2.6) and DG-UX are like this.
36#if (defined(__SUN__) && !defined(__SunOs_5_6) && \
37 !defined(__SunOs_5_7) && !defined(__SUNPRO_CC)) || \
38 defined(__osf__)
39 extern "C"
40 {
41 void usleep(unsigned long usec);
42 };
43#endif // Unices without usleep()
24178e4a 44
83624f79
RR
45#include "glib.h"
46#include "gdk/gdk.h"
47#include "gtk/gtk.h"
48#include "wx/gtk/win_gtk.h"
49
69919241
KB
50#include <unistd.h> // usleep() on solaris
51
c801d85f
KB
52//-----------------------------------------------------------------------------
53// global data
54//-----------------------------------------------------------------------------
55
c67daf87 56wxApp *wxTheApp = (wxApp *) NULL;
c801d85f
KB
57wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
58
59extern wxList wxPendingDelete;
a3622daa 60extern wxResourceCache *wxTheResourceCache;
c801d85f 61
01111366
RR
62unsigned char g_palette[64*3] =
63{
64 0x0, 0x0, 0x0,
65 0xff, 0xff, 0xff,
66 0xff, 0x0, 0x0,
67 0xff, 0xff, 0x0,
68 0x0, 0xff, 0x0,
69 0x0, 0x0, 0xff,
70 0x0, 0xff, 0xff,
71 0x99, 0x99, 0x99,
72 0xff, 0x88, 0x0,
73 0x88, 0x0, 0x0,
74 0x0, 0x88, 0x88,
75 0x88, 0x88, 0x0,
76 0xff, 0xcc, 0x97,
77 0xbb, 0xbb, 0xbb,
78 0x9f, 0x6b, 0x42,
79 0x55, 0x55, 0x55,
80 0xdd, 0xdd, 0xdd,
81 0x77, 0x77, 0x77,
82 0x33, 0x33, 0x33,
83 0xcc, 0x0, 0x0,
84 0xff, 0x44, 0x0,
85 0xff, 0xcc, 0x0,
86 0xcc, 0xcc, 0x0,
87 0x60, 0x60, 0x0,
88 0x0, 0x43, 0x0,
89 0x0, 0x7f, 0x0,
90 0x0, 0xcc, 0x0,
91 0x0, 0x44, 0x44,
92 0x0, 0x0, 0x44,
93 0x0, 0x0, 0x88,
94 0xef, 0xb1, 0x7b,
95 0xdf, 0x98, 0x5f,
96 0xbf, 0x87, 0x56,
97 0x7f, 0x57, 0x26,
98 0x5f, 0x39, 0xc,
99 0x3f, 0x1c, 0x0,
100 0x21, 0x0, 0x0,
101 0x0, 0x43, 0x87,
102 0x2d, 0x70, 0xaf,
103 0x5a, 0x9e, 0xd7,
104 0x87, 0xcc, 0xff,
105 0xff, 0xe0, 0xba,
106 0x21, 0x43, 0xf,
107 0x3d, 0x5d, 0x25,
108 0x59, 0x78, 0x3a,
109 0x75, 0x93, 0x4f,
110 0x91, 0xae, 0x64,
111 0xad, 0xc8, 0x7a,
e0253070 112 0xf0, 0xa8, 0xef,
01111366
RR
113 0xd0, 0x88, 0xd0,
114 0xaf, 0x66, 0xaf,
115 0x8e, 0x44, 0x8e,
116 0x6d, 0x22, 0x6d,
e0253070 117 0x4b, 0x0, 0x4b,
01111366
RR
118 0xff, 0xc0, 0xbc,
119 0xff, 0x93, 0x91,
120 0xff, 0x66, 0x67,
121 0xd8, 0xf2, 0xbf,
122 0xff, 0xc9, 0x68,
123 0xff, 0x96, 0x67,
124 0xa5, 0x60, 0xff,
125 0x51, 0xff, 0x99,
126 0x3f, 0xa5, 0x63,
127 0x98, 0x90, 0x67
128};
129
c801d85f
KB
130//-----------------------------------------------------------------------------
131// local functions
132//-----------------------------------------------------------------------------
133
134extern void wxFlushResources(void);
135
136//-----------------------------------------------------------------------------
137// global functions
138//-----------------------------------------------------------------------------
139
140void wxExit(void)
141{
ec758a20 142 gtk_main_quit();
ff7b1510 143}
c801d85f
KB
144
145bool wxYield(void)
146{
ec758a20
RR
147 while (gtk_events_pending() > 0) gtk_main_iteration();
148 return TRUE;
ff7b1510 149}
c801d85f
KB
150
151//-----------------------------------------------------------------------------
152// wxApp
153//-----------------------------------------------------------------------------
154
155IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
156
53010e52
RR
157BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
158 EVT_IDLE(wxApp::OnIdle)
159END_EVENT_TABLE()
160
c801d85f
KB
161gint wxapp_idle_callback( gpointer WXUNUSED(data) )
162{
ec758a20 163 if (wxTheApp) while (wxTheApp->ProcessIdle()) {}
06cfab17 164#if wxUSE_THREADS
f3855ef0 165 wxMutexGuiLeave();
ac57418f 166#endif
f3855ef0 167 usleep(10000);
06cfab17 168#if wxUSE_THREADS
f3855ef0 169 wxMutexGuiEnter();
ac57418f 170#endif
ec758a20 171 return TRUE;
ff7b1510 172}
c801d85f
KB
173
174wxApp::wxApp()
175{
0d2a2b60
RR
176 wxTheApp = this;
177
ec758a20
RR
178 m_topWindow = (wxWindow *) NULL;
179 m_exitOnFrameDelete = TRUE;
0d2a2b60
RR
180
181 m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL );
182
f6fcbb63 183 m_colorCube = (unsigned char*) NULL;
ff7b1510 184}
c801d85f
KB
185
186wxApp::~wxApp(void)
187{
ec758a20 188 gtk_idle_remove( m_idleTag );
f6fcbb63
RR
189
190 if (m_colorCube) free(m_colorCube);
ff7b1510 191}
c801d85f 192
0d2a2b60 193bool wxApp::OnInitGui()
c801d85f 194{
f6fcbb63
RR
195 /* Nothing to do for 15, 16, 24, 32 bit displays */
196
197 GdkVisual *visual = gdk_visual_get_system();
198 if (visual->depth > 8) return TRUE;
bbe0af5b 199
0d2a2b60
RR
200 /* this initiates the standard palette as defined by GdkImlib
201 in the GNOME libraries. it ensures that all GNOME applications
202 use the same 64 colormap entries on 8-bit displays so you
203 can use several rather graphics-heavy applications at the
204 same time.
205 NOTE: this doesn't really seem to work this way... */
bbe0af5b 206
0d2a2b60
RR
207 /*
208 GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
bbe0af5b 209
0d2a2b60
RR
210 for (int i = 0; i < 64; i++)
211 {
212 GdkColor col;
213 col.red = g_palette[i*3 + 0] << 8;
214 col.green = g_palette[i*3 + 1] << 8;
215 col.blue = g_palette[i*3 + 2] << 8;
216 col.pixel = 0;
217
218 gdk_color_alloc( cmap, &col );
219 }
aae24d21 220
0d2a2b60
RR
221 gtk_widget_set_default_colormap( cmap );
222 */
f6fcbb63
RR
223
224 /* initialize color cube for 8-bit color reduction dithering */
225
226 GdkColormap *cmap = gtk_widget_get_default_colormap();
227
228 m_colorCube = (unsigned char*)malloc(32 * 32 * 32);
229
230 for (int r = 0; r < 32; r++)
231 {
232 for (int g = 0; g < 32; g++)
233 {
234 for (int b = 0; b < 32; b++)
235 {
236 int rr = (r << 3) | (r >> 2);
237 int gg = (g << 3) | (g >> 2);
238 int bb = (b << 3) | (b >> 2);
239
240 GdkColor *colors = cmap->colors;
241 int max = 3 * (65536);
242 int index = -1;
243
244 for (int i = 0; i < cmap->size; i++)
245 {
246 int rdiff = ((rr << 8) - colors[i].red);
247 int gdiff = ((gg << 8)- colors[i].green);
248 int bdiff = ((bb << 8)- colors[i].blue);
249 int sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
250 if (sum < max) { index = i; max = sum; }
251 }
252
253 m_colorCube[ (r*1024) + (g*32) + b ] = index;
254 }
255 }
256 }
c801d85f 257
bbe0af5b
RR
258
259 return TRUE;
260}
261
53010e52
RR
262bool wxApp::ProcessIdle(void)
263{
ec758a20
RR
264 wxIdleEvent event;
265 event.SetEventObject( this );
266 ProcessEvent( event );
0cf2cb36 267
ec758a20 268 return event.MoreRequested();
ff7b1510 269}
53010e52
RR
270
271void wxApp::OnIdle( wxIdleEvent &event )
c801d85f 272{
ec758a20 273 static bool inOnIdle = FALSE;
53010e52 274
d524867f 275 /* Avoid recursion (via ProcessEvent default case) */
ec758a20
RR
276 if (inOnIdle)
277 return;
53010e52 278
ec758a20 279 inOnIdle = TRUE;
53010e52 280
d524867f 281 /* 'Garbage' collection of windows deleted with Close(). */
ec758a20 282 DeletePendingObjects();
53010e52 283
d524867f
RR
284 /* flush the logged messages if any */
285 wxLog *log = wxLog::GetActiveTarget();
286 if (log != NULL && log->HasPendingMessages())
287 log->Flush();
53010e52 288
d524867f 289 /* Send OnIdle events to all windows */
ec758a20 290 bool needMore = SendIdleEvents();
53010e52 291
ec758a20
RR
292 if (needMore)
293 event.RequestMore(TRUE);
53010e52 294
ec758a20 295 inOnIdle = FALSE;
ff7b1510 296}
53010e52
RR
297
298bool wxApp::SendIdleEvents(void)
299{
300 bool needMore = FALSE;
e0253070 301
ec758a20
RR
302 wxNode* node = wxTopLevelWindows.First();
303 while (node)
304 {
f3855ef0
RR
305 wxWindow* win = (wxWindow*) node->Data();
306 if (SendIdleEvents(win))
53010e52 307 needMore = TRUE;
ec758a20
RR
308 node = node->Next();
309 }
53010e52 310 return needMore;
ff7b1510 311}
53010e52
RR
312
313bool wxApp::SendIdleEvents( wxWindow* win )
314{
315 bool needMore = FALSE;
316
8bbe427f
VZ
317 wxIdleEvent event;
318 event.SetEventObject(win);
9390a202
RR
319
320 win->OnInternalIdle();
321
8bbe427f 322 win->ProcessEvent(event);
53010e52
RR
323
324 if (event.MoreRequested())
325 needMore = TRUE;
326
8bbe427f
VZ
327 wxNode* node = win->GetChildren().First();
328 while (node)
329 {
330 wxWindow* win = (wxWindow*) node->Data();
331 if (SendIdleEvents(win))
53010e52
RR
332 needMore = TRUE;
333
8bbe427f
VZ
334 node = node->Next();
335 }
53010e52 336 return needMore ;
ff7b1510 337}
c801d85f 338
c801d85f
KB
339int wxApp::MainLoop(void)
340{
ec758a20
RR
341 gtk_main();
342 return 0;
ff7b1510 343}
c801d85f
KB
344
345void wxApp::ExitMainLoop(void)
346{
ec758a20 347 gtk_main_quit();
ff7b1510 348}
c801d85f
KB
349
350bool wxApp::Initialized(void)
351{
ec758a20 352 return m_initialized;
ff7b1510 353}
c801d85f 354
0cf2cb36 355bool wxApp::Pending(void)
c801d85f 356{
ec758a20 357 return FALSE;
ff7b1510 358}
c801d85f 359
0cf2cb36 360void wxApp::Dispatch(void)
c801d85f 361{
ff7b1510 362}
c801d85f
KB
363
364void wxApp::DeletePendingObjects(void)
365{
ec758a20
RR
366 wxNode *node = wxPendingDelete.First();
367 while (node)
368 {
369 wxObject *obj = (wxObject *)node->Data();
0cf2cb36 370
ec758a20 371 delete obj;
c801d85f 372
ec758a20
RR
373 if (wxPendingDelete.Member(obj))
374 delete node;
c801d85f 375
ec758a20
RR
376 node = wxPendingDelete.First();
377 }
ff7b1510 378}
c801d85f
KB
379
380wxWindow *wxApp::GetTopWindow(void)
381{
ec758a20
RR
382 if (m_topWindow) return m_topWindow;
383 wxNode *node = wxTopLevelWindows.First();
384 if (!node) return (wxWindow *) NULL;
385 return (wxWindow*)node->Data();
ff7b1510 386}
c801d85f
KB
387
388void wxApp::SetTopWindow( wxWindow *win )
389{
ec758a20 390 m_topWindow = win;
ff7b1510 391}
c801d85f 392
0d2a2b60 393bool wxApp::Initialize(void)
c801d85f 394{
0d2a2b60
RR
395 wxBuffer = new char[BUFSIZ + 512];
396
397 wxClassInfo::InitializeClasses();
398
399 wxSystemSettings::Init();
f5abe911 400
36b3b54a 401/*
0d2a2b60
RR
402 wxTheFontNameDirectory = new wxFontNameDirectory;
403 wxTheFontNameDirectory->Initialize();
36b3b54a 404*/
c801d85f 405
0d2a2b60
RR
406 wxTheColourDatabase = new wxColourDatabase( wxKEY_STRING );
407 wxTheColourDatabase->Initialize();
a3622daa 408
0d2a2b60
RR
409 wxInitializeStockLists();
410 wxInitializeStockObjects();
c801d85f 411
06cfab17 412#if wxUSE_WX_RESOURCES
0d2a2b60 413 wxTheResourceCache = new wxResourceCache( wxKEY_STRING );
f5abe911 414
0d2a2b60 415 wxInitializeResourceSystem();
f5abe911 416#endif
0cf2cb36 417
0d2a2b60 418 wxImage::InitStandardHandlers();
e0253070 419
0d2a2b60
RR
420 /* no global cursor under X
421 g_globalCursor = new wxCursor; */
422
423 wxModule::RegisterModules();
424 if (!wxModule::InitializeModules()) return FALSE;
425
426 return TRUE;
ff7b1510 427}
c801d85f 428
0d2a2b60 429void wxApp::CleanUp(void)
c801d85f 430{
0d2a2b60 431 wxModule::CleanUpModules();
0cf2cb36 432
06cfab17 433#if wxUSE_WX_RESOURCES
ec758a20 434 wxFlushResources();
a3622daa 435
bbe0af5b
RR
436 if (wxTheResourceCache) delete wxTheResourceCache;
437 wxTheResourceCache = (wxResourceCache*) NULL;
f5abe911
RR
438
439 wxCleanUpResourceSystem();
440#endif
a3622daa 441
0d2a2b60
RR
442 if (wxTheColourDatabase) delete wxTheColourDatabase;
443 wxTheColourDatabase = (wxColourDatabase*) NULL;
444
36b3b54a 445/*
0d2a2b60
RR
446 if (wxTheFontNameDirectory) delete wxTheFontNameDirectory;
447 wxTheFontNameDirectory = (wxFontNameDirectory*) NULL;
36b3b54a 448*/
0d2a2b60
RR
449
450 wxDeleteStockObjects();
451
ec758a20 452 wxDeleteStockLists();
a3622daa 453
ec758a20 454 wxImage::CleanUpHandlers();
0cf2cb36 455
0d2a2b60
RR
456 delete wxTheApp;
457 wxTheApp = (wxApp*) NULL;
458
3e61c765
RR
459 wxSystemSettings::Done();
460
461 delete[] wxBuffer;
462
463 wxClassInfo::CleanUpClasses();
464
0d2a2b60
RR
465 /* check for memory leaks */
466#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
467 if (wxDebugContext::CountObjectsLeft() > 0)
468 {
469 wxLogDebug("There were memory leaks.\n");
470 wxDebugContext::Dump();
471 wxDebugContext::PrintStatistics();
472 }
473#endif
474
475 /* do this as the very last thing because everything else can log messages */
476 wxLog::DontCreateOnDemand();
477
478 wxLog *oldLog = wxLog::SetActiveTarget( (wxLog*) NULL );
479 if (oldLog) delete oldLog;
ff7b1510 480}
0cf2cb36 481
c801d85f
KB
482wxLog *wxApp::CreateLogTarget()
483{
0d2a2b60 484 return new wxLogGui;
c801d85f
KB
485}
486
487//-----------------------------------------------------------------------------
488// wxEntry
489//-----------------------------------------------------------------------------
490
491int wxEntry( int argc, char *argv[] )
492{
0d2a2b60 493 gtk_set_locale();
c801d85f 494
0d2a2b60 495 gtk_init( &argc, &argv );
0cf2cb36 496
0d2a2b60 497 if (!wxApp::Initialize()) return 0;
0cf2cb36 498
ec758a20 499 if (!wxTheApp)
c801d85f 500 {
ec758a20
RR
501 if (!wxApp::GetInitializerFunction())
502 {
503 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
504 return 0;
505 }
0cf2cb36 506
ec758a20 507 wxAppInitializerFunction app_ini = wxApp::GetInitializerFunction();
0cf2cb36 508
ec758a20 509 wxObject *test_app = app_ini();
0cf2cb36 510
ec758a20
RR
511 wxTheApp = (wxApp*) test_app;
512 }
0cf2cb36 513
ec758a20
RR
514 if (!wxTheApp)
515 {
516 printf( "wxWindows error: wxTheApp == NULL\n" );
517 return 0;
518 }
c801d85f 519
ec758a20
RR
520 wxTheApp->argc = argc;
521 wxTheApp->argv = argv;
0cf2cb36 522
ec758a20
RR
523 char name[200];
524 strcpy( name, argv[0] );
525 strcpy( name, wxFileNameFromPath(name) );
526 wxStripExtension( name );
527 wxTheApp->SetAppName( name );
e0253070 528
bbe0af5b 529 if (!wxTheApp->OnInitGui()) return 0;
c801d85f 530
0d2a2b60
RR
531 /* Here frames insert themselves automatically
532 * into wxTopLevelWindows by getting created
533 * in OnInit(). */
0cf2cb36 534
ec758a20 535 if (!wxTheApp->OnInit()) return 0;
c801d85f 536
ec758a20 537 wxTheApp->m_initialized = (wxTopLevelWindows.Number() > 0);
0cf2cb36 538
ec758a20 539 int retValue = 0;
0cf2cb36 540
ec758a20 541 if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
0cf2cb36 542
0d2a2b60
RR
543 wxWindow *topWindow = wxTheApp->GetTopWindow();
544 if (topWindow)
ec758a20 545 {
0d2a2b60
RR
546 /* Forcibly delete the window. */
547 if (topWindow->IsKindOf(CLASSINFO(wxFrame)) ||
548 topWindow->IsKindOf(CLASSINFO(wxDialog)) )
549 {
550 topWindow->Close( TRUE );
551 wxTheApp->DeletePendingObjects();
552 }
553 else
554 {
555 delete topWindow;
556 wxTheApp->SetTopWindow( (wxWindow*) NULL );
557 }
ec758a20 558 }
e0253070 559
0d2a2b60 560 wxTheApp->OnExit();
0cf2cb36 561
0d2a2b60
RR
562 /* flush the logged messages if any */
563 wxLog *log = wxLog::GetActiveTarget();
564 if (log != NULL && log->HasPendingMessages())
565 log->Flush();
566
567 wxApp::CleanUp();
184b5d99 568
ec758a20 569 return retValue;
ff7b1510 570}
1a56f55c 571