]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/app.cpp
adding constants
[wxWidgets.git] / src / gtk / app.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
88a7a4e1 2// Name: src/gtk/app.cpp
c801d85f
KB
3// Purpose:
4// Author: Robert Roebling
32e9da8b 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling, Julian Smart
65571936 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
df744f4d 10#ifdef __VMS
f3858bf5
JJ
11// vms_jackets.h should for proper working be included before anything else
12# include <vms_jackets.h>
ff7d1dcb 13#undef ConnectionNumber
df744f4d
JJ
14#endif
15
f3858bf5
JJ
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
c801d85f 19#include "wx/app.h"
88a7a4e1
WS
20
21#ifndef WX_PRECOMP
22 #include "wx/intl.h"
e4db172a 23 #include "wx/log.h"
de6185e2 24 #include "wx/utils.h"
fdf565fe 25 #include "wx/dialog.h"
9eddec69 26 #include "wx/settings.h"
246c5004 27 #include "wx/msgdlg.h"
5b56bffb 28 #include "wx/memory.h"
48a1108e 29 #include "wx/font.h"
dd05139a 30 #include "wx/gdicmn.h"
155ecd4c 31 #include "wx/image.h"
88a7a4e1
WS
32#endif
33
b1ac3b56 34#include "wx/file.h"
2b5f62a0 35#include "wx/filename.h"
031b2a7b 36#include "wx/module.h"
fe593cc5 37#include "wx/thread.h"
afb74891 38
62be94e1 39#ifdef __WXGPE__
88a7a4e1 40 #include <gpe/init.h>
62be94e1
RR
41#endif
42
df028524
VS
43#ifdef __WXUNIVERSAL__
44 #include "wx/univ/theme.h"
45 #include "wx/univ/renderer.h"
46#endif
47
20e05ffb 48#include <unistd.h>
2b5f62a0
VZ
49
50#ifdef HAVE_POLL
51 #if defined(__VMS)
52 #include <poll.h>
53 #else
54 // bug in the OpenBSD headers: at least in 3.1 there is no extern "C"
55 // in neither poll.h nor sys/poll.h which results in link errors later
56 #ifdef __OPENBSD__
57 extern "C"
58 {
59 #endif
60
61 #include <sys/poll.h>
62
63 #ifdef __OPENBSD__
64 };
65 #endif
66 #endif // platform
67#else // !HAVE_POLL
68 // we implement poll() ourselves using select() which is supposed exist in
69 // all modern Unices
70 #include <sys/types.h>
71 #include <sys/time.h>
72 #include <unistd.h>
bc023abb
MW
73 #ifdef HAVE_SYS_SELECT_H
74 #include <sys/select.h>
75 #endif
2b5f62a0
VZ
76#endif // HAVE_POLL/!HAVE_POLL
77
17a1ebd1 78#include "wx/unix/private.h"
e8106239 79#include "wx/gtk/win_gtk.h"
84833214 80#include "wx/gtk/private.h"
c801d85f 81
c259ffdf 82#include <gdk/gdkx.h>
24178e4a 83
2b850ae1
RR
84//-----------------------------------------------------------------------------
85// link GnomeVFS
86//-----------------------------------------------------------------------------
87
88#if wxUSE_LIBGNOMEVFS
89#include "wx/html/forcelnk.h"
90FORCE_LINK(gnome_vfs)
91#endif
92
c801d85f
KB
93//-----------------------------------------------------------------------------
94// global data
95//-----------------------------------------------------------------------------
96
de6185e2 97bool g_mainThreadLocked = false;
96997d65 98gint g_pendingTag = 0;
3ac8d3bc 99
c2fa61e8 100static GtkWidget *gs_RootWindow = (GtkWidget*) NULL;
d76fe38b 101
c801d85f 102//-----------------------------------------------------------------------------
3133cb9f 103// idle system
c801d85f
KB
104//-----------------------------------------------------------------------------
105
90350682 106void wxapp_install_idle_handler();
bf9e3e73 107
fe593cc5
VS
108#if wxUSE_THREADS
109static wxMutex gs_idleTagsMutex;
110#endif
111
bf9e3e73
RR
112//-----------------------------------------------------------------------------
113// wxYield
114//-----------------------------------------------------------------------------
53a8af59 115
1ee339ee
VZ
116// not static because used by textctrl.cpp
117//
118// MT-FIXME
88a7a4e1 119bool wxIsInsideYield = false;
1ee339ee 120
8461e4c2 121bool wxApp::Yield(bool onlyIfNeeded)
c801d85f 122{
1ee339ee 123 if ( wxIsInsideYield )
8461e4c2
VZ
124 {
125 if ( !onlyIfNeeded )
126 {
127 wxFAIL_MSG( wxT("wxYield called recursively" ) );
128 }
129
88a7a4e1 130 return false;
8461e4c2
VZ
131 }
132
6dc5fd71
VZ
133#if wxUSE_THREADS
134 if ( !wxThread::IsMain() )
135 {
136 // can't call gtk_main_iteration() from other threads like this
88a7a4e1 137 return true;
6dc5fd71
VZ
138 }
139#endif // wxUSE_THREADS
140
88a7a4e1 141 wxIsInsideYield = true;
e90c1d2a 142
c263eb03
VS
143 // We need to remove idle callbacks or the loop will
144 // never finish.
145 wxTheApp->RemoveIdleTag();
acfd422a 146
dd7641ef 147#if wxUSE_LOG
2ed3265e
VZ
148 // disable log flushing from here because a call to wxYield() shouldn't
149 // normally result in message boxes popping up &c
150 wxLog::Suspend();
dd7641ef 151#endif
2ed3265e 152
406a6f6b
VZ
153 while (gtk_events_pending())
154 gtk_main_iteration();
155
5375a1f5
RR
156 // It's necessary to call ProcessIdle() to update the frames sizes which
157 // might have been changed (it also will update other things set from
be88a6ad 158 // OnUpdateUI() which is a nice (and desired) side effect). But we
5375a1f5
RR
159 // call ProcessIdle() only once since this is not meant for longish
160 // background jobs (controlled by wxIdleEvent::RequestMore() and the
161 // return value of Processidle().
162 ProcessIdle();
2ed3265e 163
dd7641ef 164#if wxUSE_LOG
2ed3265e
VZ
165 // let the logs be flashed again
166 wxLog::Resume();
dd7641ef 167#endif
7741c4e1 168
88a7a4e1 169 wxIsInsideYield = false;
99ba739f 170
88a7a4e1 171 return true;
acfd422a
RR
172}
173
bf9e3e73
RR
174//-----------------------------------------------------------------------------
175// wxWakeUpIdle
176//-----------------------------------------------------------------------------
177
68567a96
MR
178// RR/KH: No wxMutexGui calls are needed here according to the GTK faq,
179// http://www.gtk.org/faq/#AEN500 - this caused problems for wxPostEvent.
19722331 180
e2478fde 181void wxApp::WakeUpIdle()
bf9e3e73 182{
c263eb03 183 wxapp_install_idle_handler();
bf9e3e73
RR
184}
185
186//-----------------------------------------------------------------------------
187// local functions
188//-----------------------------------------------------------------------------
189
90350682
VZ
190// the callback functions must be extern "C" to comply with GTK+ declarations
191extern "C"
192{
193
3133cb9f 194static gint wxapp_pending_callback( gpointer WXUNUSED(data) )
acfd422a
RR
195{
196 if (!wxTheApp) return TRUE;
c2fa61e8 197
5375a1f5 198 // When getting called from GDK's time-out handler
96997d65 199 // we are no longer within GDK's grab on the GUI
5375a1f5 200 // thread so we must lock it here ourselves.
96997d65
RR
201 gdk_threads_enter();
202
5375a1f5 203 // Sent idle event to all who request them.
96997d65 204 wxTheApp->ProcessPendingEvents();
e90c1d2a 205
fe593cc5
VS
206 {
207#if wxUSE_THREADS
208 wxMutexLocker lock(gs_idleTagsMutex);
209#endif
210 g_pendingTag = 0;
211 }
96997d65 212
5375a1f5 213 // Flush the logged messages if any.
1b2dab34
RR
214#if wxUSE_LOG
215 wxLog::FlushActive();
216#endif // wxUSE_LOG
217
96997d65
RR
218 // Release lock again
219 gdk_threads_leave();
220
221 // Return FALSE to indicate that no more idle events are
222 // to be sent (single shot instead of continuous stream)
223 return FALSE;
224}
225
3133cb9f 226static gint wxapp_idle_callback( gpointer WXUNUSED(data) )
96997d65 227{
a5f1fd3e
VZ
228 if (!wxTheApp)
229 return TRUE;
230
231#ifdef __WXDEBUG__
6d477bb4
VZ
232 // don't generate the idle events while the assert modal dialog is shown,
233 // this completely confuses the apps which don't expect to be reentered
234 // from some safely-looking functions
a5f1fd3e
VZ
235 if ( wxTheApp->IsInAssert() )
236 {
94a6f0f8
JS
237 // But repaint the assertion message if necessary
238 if (wxTopLevelWindows.GetCount() > 0)
239 {
b1d4dd7a 240 wxWindow* win = (wxWindow*) wxTopLevelWindows.GetLast()->GetData();
13a7abf9 241 if (win->IsKindOf(CLASSINFO(wxMessageDialog)))
94a6f0f8
JS
242 win->OnInternalIdle();
243 }
6d477bb4 244 return TRUE;
a5f1fd3e
VZ
245 }
246#endif // __WXDEBUG__
c2fa61e8 247
5375a1f5 248 // When getting called from GDK's time-out handler
924ef850 249 // we are no longer within GDK's grab on the GUI
5375a1f5 250 // thread so we must lock it here ourselves.
924ef850 251 gdk_threads_enter();
094637f6 252
5375a1f5
RR
253 // Indicate that we are now in idle mode and event handlers
254 // will have to reinstall the idle handler again.
fe593cc5
VS
255 {
256#if wxUSE_THREADS
257 wxMutexLocker lock(gs_idleTagsMutex);
258#endif
e4db172a 259 g_isIdle = true;
fe593cc5
VS
260 wxTheApp->m_idleTag = 0;
261 }
094637f6 262
0faa7620 263 bool moreIdles;
8ab9a536 264
3133cb9f 265 // Send idle event to all who request them as long as
5375a1f5 266 // no events have popped up in the event queue.
0faa7620 267 while ( (moreIdles = wxTheApp->ProcessIdle()) && gtk_events_pending() == 0)
6d477bb4 268 ;
c9e35272 269
96997d65 270 // Release lock again
924ef850 271 gdk_threads_leave();
acfd422a 272
8ab9a536
RR
273 // Return FALSE if no more idle events are to be sent
274 return moreIdles;
acfd422a 275}
8801832d 276
90350682
VZ
277#if wxUSE_THREADS
278
2b5f62a0
VZ
279#ifdef HAVE_POLL
280 #define wxPoll poll
281 #define wxPollFd pollfd
282#else // !HAVE_POLL
283
284typedef GPollFD wxPollFd;
285
286int wxPoll(wxPollFd *ufds, unsigned int nfds, int timeout)
287{
288 // convert timeout from ms to struct timeval (s/us)
289 timeval tv_timeout;
290 tv_timeout.tv_sec = timeout/1000;
291 tv_timeout.tv_usec = (timeout%1000)*1000;
292
293 // remember the highest fd used here
294 int fdMax = -1;
295
296 // and fill the sets for select()
297 fd_set readfds;
298 fd_set writefds;
299 fd_set exceptfds;
17a1ebd1
VZ
300 wxFD_ZERO(&readfds);
301 wxFD_ZERO(&writefds);
302 wxFD_ZERO(&exceptfds);
2b5f62a0
VZ
303
304 unsigned int i;
305 for ( i = 0; i < nfds; i++ )
306 {
17a1ebd1 307 wxASSERT_MSG( ufds[i].fd < wxFD_SETSIZE, _T("fd out of range") );
2b5f62a0
VZ
308
309 if ( ufds[i].events & G_IO_IN )
17a1ebd1 310 wxFD_SET(ufds[i].fd, &readfds);
2b5f62a0
VZ
311
312 if ( ufds[i].events & G_IO_PRI )
17a1ebd1 313 wxFD_SET(ufds[i].fd, &exceptfds);
2b5f62a0
VZ
314
315 if ( ufds[i].events & G_IO_OUT )
17a1ebd1 316 wxFD_SET(ufds[i].fd, &writefds);
2b5f62a0
VZ
317
318 if ( ufds[i].fd > fdMax )
319 fdMax = ufds[i].fd;
320 }
321
322 fdMax++;
323 int res = select(fdMax, &readfds, &writefds, &exceptfds, &tv_timeout);
324
325 // translate the results back
326 for ( i = 0; i < nfds; i++ )
327 {
328 ufds[i].revents = 0;
329
17a1ebd1 330 if ( wxFD_ISSET(ufds[i].fd, &readfds ) )
2b5f62a0
VZ
331 ufds[i].revents |= G_IO_IN;
332
17a1ebd1 333 if ( wxFD_ISSET(ufds[i].fd, &exceptfds ) )
2b5f62a0
VZ
334 ufds[i].revents |= G_IO_PRI;
335
17a1ebd1 336 if ( wxFD_ISSET(ufds[i].fd, &writefds ) )
2b5f62a0
VZ
337 ufds[i].revents |= G_IO_OUT;
338 }
339
340 return res;
341}
342
343#endif // HAVE_POLL/!HAVE_POLL
344
3133cb9f 345static gint wxapp_poll_func( GPollFD *ufds, guint nfds, gint timeout )
acfd422a 346{
90350682 347 gdk_threads_enter();
7b90a8f2 348
90350682 349 wxMutexGuiLeave();
e4db172a 350 g_mainThreadLocked = true;
7941ba11 351
2b5f62a0
VZ
352 // we rely on the fact that glib GPollFD struct is really just pollfd but
353 // I wonder how wise is this in the long term (VZ)
354 gint res = wxPoll( (wxPollFd *) ufds, nfds, timeout );
90350682 355
90350682 356 wxMutexGuiEnter();
de6185e2 357 g_mainThreadLocked = false;
90350682 358
90350682
VZ
359 gdk_threads_leave();
360
3133cb9f 361 return res;
ff7b1510 362}
c801d85f 363
90350682
VZ
364#endif // wxUSE_THREADS
365
366} // extern "C"
367
3133cb9f 368void wxapp_install_idle_handler()
b453e1b2 369{
fe593cc5
VS
370#if wxUSE_THREADS
371 wxMutexLocker lock(gs_idleTagsMutex);
372#endif
373
c263eb03
VS
374 // Don't install the handler if it's already installed. This test *MUST*
375 // be done when gs_idleTagsMutex is locked!
376 if (!g_isIdle)
377 return;
378
e8617760
GD
379 // GD: this assert is raised when using the thread sample (which works)
380 // so the test is probably not so easy. Can widget callbacks be
381 // triggered from child threads and, if so, for which widgets?
382 // wxASSERT_MSG( wxThread::IsMain() || gs_WakeUpIdle, wxT("attempt to install idle handler from widget callback in child thread (should be exclusively from wxWakeUpIdle)") );
d5f3e1eb 383
3133cb9f 384 wxASSERT_MSG( wxTheApp->m_idleTag == 0, wxT("attempt to install idle handler twice") );
c2fa61e8 385
de6185e2 386 g_isIdle = false;
96997d65 387
3133cb9f 388 if (g_pendingTag == 0)
5d038ec5 389 g_pendingTag = g_idle_add_full( 900, wxapp_pending_callback, NULL, NULL );
e90c1d2a 390
3133cb9f
RR
391 // This routine gets called by all event handlers
392 // indicating that the idle is over. It may also
393 // get called from other thread for sending events
394 // to the main thread (and processing these in
395 // idle time). Very low priority.
5d038ec5 396 wxTheApp->m_idleTag = g_idle_add_full( 1000, wxapp_idle_callback, NULL, NULL );
b453e1b2
RR
397}
398
005f5d18
RR
399//-----------------------------------------------------------------------------
400// Access to the root window global
401//-----------------------------------------------------------------------------
402
403GtkWidget* wxGetRootWindow()
404{
405 if (gs_RootWindow == NULL)
406 {
407 gs_RootWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL );
408 gtk_widget_realize( gs_RootWindow );
409 }
410 return gs_RootWindow;
411}
412
c801d85f
KB
413//-----------------------------------------------------------------------------
414// wxApp
415//-----------------------------------------------------------------------------
416
417IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
418
53010e52 419BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
955a9197 420 EVT_IDLE(wxAppBase::OnIdle)
53010e52
RR
421END_EVENT_TABLE()
422
c801d85f
KB
423wxApp::wxApp()
424{
a5f1fd3e 425#ifdef __WXDEBUG__
de6185e2 426 m_isInAssert = false;
a5f1fd3e
VZ
427#endif // __WXDEBUG__
428
df5ddbca 429 m_idleTag = 0;
e4db172a 430 g_isIdle = true;
df5ddbca 431 wxapp_install_idle_handler();
094637f6 432
6b3eb77a 433#if wxUSE_THREADS
15894949 434 g_main_context_set_poll_func( NULL, wxapp_poll_func );
6b3eb77a 435#endif
60acb947 436
a6f5aa49
VZ
437 // this is NULL for a "regular" wxApp, but is set (and freed) by a wxGLApp
438 m_glVisualInfo = (void *) NULL;
34a34b02 439 m_glFBCInfo = (void *) NULL;
ff7b1510 440}
c801d85f 441
60acb947 442wxApp::~wxApp()
c801d85f 443{
5d038ec5
MR
444 if (m_idleTag)
445 g_source_remove( m_idleTag );
ff7b1510 446}
c801d85f 447
0d2a2b60 448bool wxApp::OnInitGui()
c801d85f 449{
1e6feb95 450 if ( !wxAppBase::OnInitGui() )
de6185e2 451 return false;
1e6feb95 452
a6f5aa49
VZ
453 // if this is a wxGLApp (derived from wxApp), and we've already
454 // chosen a specific visual, then derive the GdkVisual from that
005f5d18
RR
455 if (m_glVisualInfo != NULL)
456 {
005f5d18 457 // seems gtk_widget_set_default_visual no longer exists?
a6f5aa49 458 GdkVisual* vis = gtk_widget_get_default_visual();
a6f5aa49
VZ
459
460 GdkColormap *colormap = gdk_colormap_new( vis, FALSE );
461 gtk_widget_set_default_colormap( colormap );
a6f5aa49 462 }
be88a6ad 463
005f5d18
RR
464 // On some machines, the default visual is just 256 colours, so
465 // we make sure we get the best. This can sometimes be wasteful.
2286341c 466
005f5d18
RR
467 else
468 if ((gdk_visual_get_best() != gdk_visual_get_system()) && (m_useBestVisual))
b134516c 469 {
2d4dc3a4
OK
470 /* seems gtk_widget_set_default_visual no longer exists? */
471 GdkVisual* vis = gtk_widget_get_default_visual();
f6fcbb63 472
b134516c
RR
473 GdkColormap *colormap = gdk_colormap_new( vis, FALSE );
474 gtk_widget_set_default_colormap( colormap );
f6fcbb63 475 }
c801d85f 476
88a7a4e1 477 return true;
bbe0af5b
RR
478}
479
005f5d18
RR
480GdkVisual *wxApp::GetGdkVisual()
481{
482 GdkVisual *visual = NULL;
be88a6ad 483
005f5d18 484 if (m_glVisualInfo)
7b775074 485 visual = gdkx_visual_get( ((XVisualInfo *) m_glVisualInfo)->visualid );
005f5d18 486 else
22a3bce4 487 visual = gdk_drawable_get_visual( wxGetRootWindow()->window );
be88a6ad 488
005f5d18 489 wxASSERT( visual );
be88a6ad 490
005f5d18
RR
491 return visual;
492}
493
abca8ebf 494bool wxApp::Initialize(int& argc, wxChar **argv)
c801d85f 495{
c156411a 496 bool init_result;
68567a96 497
924ef850 498#if wxUSE_THREADS
ac131bab
MR
499 if (!g_thread_supported())
500 g_thread_init(NULL);
05e2b077 501#endif // wxUSE_THREADS
2286341c 502
0d2a2b60 503 gtk_set_locale();
c801d85f 504
f9862abd
JS
505 // We should have the wxUSE_WCHAR_T test on the _outside_
506#if wxUSE_WCHAR_T
68567a96
MR
507 // gtk+ 2.0 supports Unicode through UTF-8 strings
508 wxConvCurrent = &wxConvUTF8;
05e2b077
VZ
509#else // !wxUSE_WCHAR_T
510 if (!wxOKlibc())
511 wxConvCurrent = (wxMBConv*) NULL;
512#endif // wxUSE_WCHAR_T/!wxUSE_WCHAR_T
002f4218 513
845905d5
MW
514 // decide which conversion to use for the file names
515
516 // (1) this variable exists for the sole purpose of specifying the encoding
517 // of the filenames for GTK+ programs, so use it if it is set
518 wxString encName(wxGetenv(_T("G_FILENAME_ENCODING")));
29c326b7 519 encName = encName.BeforeFirst(_T(','));
d24b23b7
MW
520 if (encName == _T("@locale"))
521 encName.clear();
845905d5 522 encName.MakeUpper();
68567a96 523#if wxUSE_INTL
845905d5
MW
524 if (encName.empty())
525 {
526 // (2) if a non default locale is set, assume that the user wants his
527 // filenames in this locale too
528 encName = wxLocale::GetSystemEncodingName().Upper();
529 // (3) finally use UTF-8 by default
530 if (encName.empty() || encName == _T("US-ASCII"))
531 encName = _T("UTF-8");
532 wxSetEnv(_T("G_FILENAME_ENCODING"), encName);
533 }
534#else
535 if (encName.empty())
536 encName = _T("UTF-8");
537#endif // wxUSE_INTL
538 static wxConvBrokenFileNames fileconv(encName);
539 wxConvFileName = &fileconv;
66bf0099 540
05e2b077
VZ
541#if wxUSE_UNICODE
542 // gtk_init() wants UTF-8, not wchar_t, so convert
543 int i;
0d8dda32 544 char **argvGTK = new char *[argc + 1];
05e2b077 545 for ( i = 0; i < argc; i++ )
924ef850 546 {
05e2b077 547 argvGTK[i] = wxStrdupA(wxConvUTF8.cWX2MB(argv[i]));
924ef850 548 }
0cf2cb36 549
05e2b077 550 argvGTK[argc] = NULL;
954de0f1 551
05e2b077 552 int argcGTK = argc;
68567a96 553
62be94e1 554#ifdef __WXGPE__
c156411a 555 init_result = true; // is there a _check() version of this?
62be94e1
RR
556 gpe_application_init( &argcGTK, &argvGTK );
557#else
c156411a 558 init_result = gtk_init_check( &argcGTK, &argvGTK );
62be94e1 559#endif
954de0f1 560
05e2b077 561 if ( argcGTK != argc )
924ef850 562 {
05e2b077
VZ
563 // we have to drop the parameters which were consumed by GTK+
564 for ( i = 0; i < argcGTK; i++ )
565 {
0d8dda32 566 while ( strcmp(wxConvUTF8.cWX2MB(argv[i]), argvGTK[i]) != 0 )
05e2b077
VZ
567 {
568 memmove(argv + i, argv + i + 1, argc - i);
569 }
570 }
0cf2cb36 571
05e2b077 572 argc = argcGTK;
2b5f62a0 573 }
05e2b077 574 //else: gtk_init() didn't modify our parameters
e0253070 575
05e2b077
VZ
576 // free our copy
577 for ( i = 0; i < argcGTK; i++ )
0151c3eb 578 {
05e2b077 579 free(argvGTK[i]);
0151c3eb 580 }
0cf2cb36 581
05e2b077
VZ
582 delete [] argvGTK;
583#else // !wxUSE_UNICODE
584 // gtk_init() shouldn't actually change argv itself (just its contents) so
585 // it's ok to pass pointer to it
c156411a 586 init_result = gtk_init_check( &argc, &argv );
05e2b077 587#endif // wxUSE_UNICODE/!wxUSE_UNICODE
0cf2cb36 588
c156411a
RD
589 if (!init_result) {
590 wxLogError(wxT("Unable to initialize gtk, is DISPLAY set properly?"));
591 return false;
592 }
68567a96 593
05e2b077
VZ
594 // we can not enter threads before gtk_init is done
595 gdk_threads_enter();
0cf2cb36 596
abca8ebf
VZ
597 if ( !wxAppBase::Initialize(argc, argv) )
598 {
599 gdk_threads_leave();
600
601 return false;
602 }
603
e4db172a 604 wxSetDetectableAutoRepeat( true );
be88a6ad 605
05e2b077
VZ
606#if wxUSE_INTL
607 wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
608#endif
be88a6ad 609
05e2b077
VZ
610 return true;
611}
0cf2cb36 612
05e2b077
VZ
613void wxApp::CleanUp()
614{
05e2b077 615 gdk_threads_leave();
abca8ebf
VZ
616
617 wxAppBase::CleanUp();
ff7b1510 618}
1a56f55c 619
a5f1fd3e
VZ
620#ifdef __WXDEBUG__
621
2d97237d
VZ
622void wxApp::OnAssertFailure(const wxChar *file,
623 int line,
624 const wxChar* func,
625 const wxChar* cond,
626 const wxChar *msg)
a5f1fd3e 627{
88a7a4e1 628 m_isInAssert = true;
a5f1fd3e 629
2d97237d 630 wxAppBase::OnAssertFailure(file, line, func, cond, msg);
a5f1fd3e 631
de6185e2 632 m_isInAssert = false;
a5f1fd3e
VZ
633}
634
635#endif // __WXDEBUG__
636
fe593cc5
VS
637void wxApp::RemoveIdleTag()
638{
639#if wxUSE_THREADS
640 wxMutexLocker lock(gs_idleTagsMutex);
641#endif
c263eb03
VS
642 if (!g_isIdle)
643 {
5d038ec5 644 g_source_remove( wxTheApp->m_idleTag );
c263eb03 645 wxTheApp->m_idleTag = 0;
e4db172a 646 g_isIdle = true;
c263eb03 647 }
fe593cc5 648}