]> git.saurik.com Git - wxWidgets.git/blame - src/x11/app.cpp
copyright update
[wxWidgets.git] / src / x11 / app.cpp
CommitLineData
83df96d6
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: app.cpp
3// Purpose: wxApp
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13 #pragma implementation "app.h"
14#endif
15
83df96d6
JS
16#include "wx/frame.h"
17#include "wx/app.h"
18#include "wx/utils.h"
19#include "wx/gdicmn.h"
20#include "wx/pen.h"
21#include "wx/brush.h"
22#include "wx/cursor.h"
23#include "wx/icon.h"
83df96d6
JS
24#include "wx/dialog.h"
25#include "wx/msgdlg.h"
26#include "wx/log.h"
27#include "wx/module.h"
28#include "wx/memory.h"
29#include "wx/log.h"
30#include "wx/intl.h"
1b0fb34b 31#include "wx/evtloop.h"
45ff6421 32#include "wx/cmdline.h"
83df96d6
JS
33
34#if wxUSE_THREADS
35 #include "wx/thread.h"
36#endif
37
38#if wxUSE_WX_RESOURCES
39 #include "wx/resource.h"
40#endif
41
42#ifdef __VMS__
43#pragma message disable nosimpint
44#endif
83df96d6
JS
45#include <X11/Xlib.h>
46#include <X11/Xutil.h>
47#include <X11/Xresource.h>
48#include <X11/Xatom.h>
49#ifdef __VMS__
50#pragma message enable nosimpint
51#endif
52
7eaac9f5 53#include "wx/x11/private.h"
83df96d6
JS
54
55#include <string.h>
56
83df96d6
JS
57extern wxList wxPendingDelete;
58
59wxApp *wxTheApp = NULL;
60
61wxHashTable *wxWidgetHashTable = NULL;
62
63IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
64
65BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
66 EVT_IDLE(wxApp::OnIdle)
67END_EVENT_TABLE()
68
69#ifdef __WXDEBUG__
1b0fb34b 70typedef int (*XErrorHandlerFunc)(Display *, XErrorEvent *);
83df96d6 71
1b0fb34b 72XErrorHandlerFunc gs_pfnXErrorHandler = 0;
83df96d6 73
1b0fb34b
JS
74static int wxXErrorHandler(Display *dpy, XErrorEvent *xevent)
75{
76 // just forward to the default handler for now
77 return gs_pfnXErrorHandler(dpy, xevent);
78}
83df96d6
JS
79#endif // __WXDEBUG__
80
81long wxApp::sm_lastMessageTime = 0;
a11672a4 82WXDisplay *wxApp::ms_display = NULL;
83df96d6
JS
83
84bool wxApp::Initialize()
85{
83df96d6
JS
86 wxClassInfo::InitializeClasses();
87
88 // GL: I'm annoyed ... I don't know where to put this and I don't want to
89 // create a module for that as it's part of the core.
90#if wxUSE_THREADS
91 wxPendingEventsLocker = new wxCriticalSection();
92#endif
93
94 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
95 wxTheColourDatabase->Initialize();
96
97 wxInitializeStockLists();
98 wxInitializeStockObjects();
99
100#if wxUSE_WX_RESOURCES
101 wxInitializeResourceSystem();
102#endif
103
83df96d6
JS
104 wxWidgetHashTable = new wxHashTable(wxKEY_INTEGER);
105
106 wxModule::RegisterModules();
107 if (!wxModule::InitializeModules()) return FALSE;
108
109 return TRUE;
110}
111
112void wxApp::CleanUp()
113{
114 delete wxWidgetHashTable;
115 wxWidgetHashTable = NULL;
116
117 wxModule::CleanUpModules();
118
119#if wxUSE_WX_RESOURCES
120 wxCleanUpResourceSystem();
121#endif
122
83df96d6
JS
123 delete wxTheColourDatabase;
124 wxTheColourDatabase = NULL;
125
a11672a4
RR
126 wxDeleteStockObjects();
127
128 wxDeleteStockLists();
129
130 delete wxTheApp;
131 wxTheApp = NULL;
83df96d6 132
83df96d6
JS
133 wxClassInfo::CleanUpClasses();
134
83df96d6
JS
135#if wxUSE_THREADS
136 delete wxPendingEvents;
137 delete wxPendingEventsLocker;
138#endif
139
140#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
141 // At this point we want to check if there are any memory
142 // blocks that aren't part of the wxDebugContext itself,
143 // as a special case. Then when dumping we need to ignore
144 // wxDebugContext, too.
145 if (wxDebugContext::CountObjectsLeft(TRUE) > 0)
146 {
ba696cfa 147 wxLogDebug("There were memory leaks.");
83df96d6
JS
148 wxDebugContext::Dump();
149 wxDebugContext::PrintStatistics();
150 }
151#endif
152
153 // do it as the very last thing because everything else can log messages
154 wxLog::DontCreateOnDemand();
155 // do it as the very last thing because everything else can log messages
156 delete wxLog::SetActiveTarget(NULL);
157}
158
45ff6421
JS
159// This is set within wxEntryStart -- too early on
160// to put these in wxTheApp
161static int g_newArgc = 0;
162static wxChar** g_newArgv = NULL;
163
a11672a4
RR
164// NB: argc and argv may be changed here, pass by reference!
165int wxEntryStart( int& argc, char *argv[] )
166{
167#ifdef __WXDEBUG__
168 // install the X error handler
169 gs_pfnXErrorHandler = XSetErrorHandler( wxXErrorHandler );
170#endif // __WXDEBUG__
171
45ff6421
JS
172 /// TODO
173#if 0
3a0b23eb 174 // Parse the arguments.
45ff6421
JS
175#endif
176
a11672a4
RR
177 Display* xdisplay = XOpenDisplay(NULL);
178
179 if (!xdisplay)
180 {
181 wxLogError( _("wxWindows could not open display. Exiting.") );
182 return -1;
183 }
184
185 wxApp::ms_display = (WXDisplay*) xdisplay;
186
187 XSelectInput( xdisplay, XDefaultRootWindow(xdisplay), PropertyChangeMask);
188
189// wxSetDetectableAutoRepeat( TRUE );
190
191 if (!wxApp::Initialize())
192 return -1;
193
194 return 0;
195}
196
197
198int wxEntryInitGui()
199{
200 int retValue = 0;
201
202 if ( !wxTheApp->OnInitGui() )
203 retValue = -1;
204
205 return retValue;
206}
207
208
83df96d6
JS
209int wxEntry( int argc, char *argv[] )
210{
211#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
212 // This seems to be necessary since there are 'rogue'
213 // objects present at this point (perhaps global objects?)
214 // Setting a checkpoint will ignore them as far as the
215 // memory checking facility is concerned.
216 // Of course you may argue that memory allocated in globals should be
217 // checked, but this is a reasonable compromise.
218 wxDebugContext::SetCheckpoint();
219#endif
a11672a4
RR
220 int err = wxEntryStart(argc, argv);
221 if (err)
222 return err;
83df96d6
JS
223
224 if (!wxTheApp)
225 {
226 if (!wxApp::GetInitializerFunction())
227 {
228 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
229 return 0;
230 };
231
232 wxTheApp = (wxApp*) (* wxApp::GetInitializerFunction()) ();
233 };
234
235 if (!wxTheApp)
236 {
237 printf( "wxWindows error: wxTheApp == NULL\n" );
238 return 0;
239 };
240
241 wxTheApp->SetClassName(wxFileNameFromPath(argv[0]));
242 wxTheApp->SetAppName(wxFileNameFromPath(argv[0]));
243
45ff6421
JS
244 // The command line may have been changed
245 // by stripping out -display etc.
246 if (g_newArgc > 0)
247 {
248 wxTheApp->argc = g_newArgc;
249 wxTheApp->argv = g_newArgv;
250 }
251 else
252 {
253 wxTheApp->argc = argc;
254 wxTheApp->argv = argv;
255 }
83df96d6 256
a11672a4
RR
257 int retValue;
258 retValue = wxEntryInitGui();
83df96d6
JS
259
260 // Here frames insert themselves automatically into wxTopLevelWindows by
261 // getting created in OnInit().
a11672a4
RR
262 if ( retValue == 0 )
263 {
264 if ( !wxTheApp->OnInit() )
265 retValue = -1;
266 }
83df96d6 267
a11672a4 268 if ( retValue == 0 )
83df96d6
JS
269 {
270 if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
271 }
272
273 // flush the logged messages if any
274 wxLog *pLog = wxLog::GetActiveTarget();
275 if ( pLog != NULL && pLog->HasPendingMessages() )
276 pLog->Flush();
277
278 delete wxLog::SetActiveTarget(new wxLogStderr); // So dialog boxes aren't used
279 // for further messages
280
281 if (wxTheApp->GetTopWindow())
282 {
283 delete wxTheApp->GetTopWindow();
284 wxTheApp->SetTopWindow(NULL);
285 }
286
287 wxTheApp->DeletePendingObjects();
288
289 wxTheApp->OnExit();
290
291 wxApp::CleanUp();
292
293 return retValue;
294};
295
296// Static member initialization
297wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
298
299wxApp::wxApp()
300{
301 m_topWindow = NULL;
302 wxTheApp = this;
303 m_className = "";
304 m_wantDebugOutput = TRUE ;
305 m_appName = "";
306 argc = 0;
307 argv = NULL;
308 m_exitOnFrameDelete = TRUE;
83df96d6 309 m_mainColormap = (WXColormap) NULL;
7eaac9f5 310 m_topLevelWidget = (WXWindow) NULL;
83df96d6 311 m_maxRequestSize = 0;
1b0fb34b 312 m_mainLoop = NULL;
83df96d6
JS
313}
314
315bool wxApp::Initialized()
316{
317 if (GetTopWindow())
318 return TRUE;
319 else
320 return FALSE;
321}
322
323int wxApp::MainLoop()
324{
1b0fb34b
JS
325 int rt;
326 m_mainLoop = new wxEventLoop;
83df96d6 327
1b0fb34b 328 rt = m_mainLoop->Run();
83df96d6 329
1b0fb34b
JS
330 delete m_mainLoop;
331 m_mainLoop = NULL;
332 return rt;
333}
83df96d6 334
1b0fb34b
JS
335// Processes an X event.
336void wxApp::ProcessXEvent(WXEvent* _event)
337{
338 XEvent* event = (XEvent*) _event;
83df96d6 339
1b0fb34b
JS
340 wxWindow* win = NULL;
341 Window window = event->xany.window;
342 Window actualWindow = window;
83df96d6 343
1b0fb34b
JS
344 // Find the first wxWindow that corresponds to this event window
345 // TODO: may need to translate coordinates from actualWindow
346 // to window, if the receiving window != wxWindow window
774b90fb
JS
347 // while (window && !(win = wxGetWindowFromTable(window)))
348 // window = wxGetWindowParent(window);
349
350 // Because we're receiving events after a window
351 // has been destroyed, assume a 1:1 match between
352 // Window and wxWindow, so if it's not in the table,
353 // it must have been destroyed.
354
355 win = wxGetWindowFromTable(window);
356 if (!win)
45ff6421 357 return;
83df96d6 358
1b0fb34b
JS
359 switch (event->type)
360 {
361 case KeyPress:
83df96d6 362 {
b513212d
JS
363 if (win && !win->IsEnabled())
364 return;
365
1b0fb34b
JS
366 {
367 if (win)
368 {
369 wxKeyEvent keyEvent(wxEVT_KEY_DOWN);
7266b672 370 wxTranslateKeyEvent(keyEvent, win, window, event);
ba696cfa
RR
371
372 wxLogDebug( "OnKey from %s", win->GetName().c_str() );
1b0fb34b
JS
373
374 // We didn't process wxEVT_KEY_DOWN, so send
7266b672 375 // wxEVT_CHAR
b513212d 376 if (!win->GetEventHandler()->ProcessEvent( keyEvent ))
1b0fb34b 377 {
7266b672 378 keyEvent.SetEventType(wxEVT_CHAR);
b513212d 379 win->GetEventHandler()->ProcessEvent( keyEvent );
1b0fb34b
JS
380 }
381
382 // We intercepted and processed the key down event
383 return;
384 }
385 }
386 return;
83df96d6 387 }
1b0fb34b 388 case KeyRelease:
7eaac9f5 389 {
b513212d
JS
390 if (win && !win->IsEnabled())
391 return;
392
1b0fb34b
JS
393 if (win)
394 {
395 wxKeyEvent keyEvent(wxEVT_KEY_UP);
396 wxTranslateKeyEvent(keyEvent, win, window, event);
397
b513212d 398 win->GetEventHandler()->ProcessEvent( keyEvent );
1b0fb34b 399 }
83df96d6 400 return;
7eaac9f5 401 }
1b0fb34b 402 case PropertyNotify:
7eaac9f5 403 {
1b0fb34b 404 HandlePropertyChange(_event);
83df96d6 405 return;
7eaac9f5 406 }
b513212d 407 case ClientMessage:
3a0b23eb
JS
408 {
409 if (win && !win->IsEnabled())
410 return;
411
b513212d
JS
412 Atom wm_delete_window = XInternAtom(wxGlobalDisplay(), "WM_DELETE_WINDOW", True);;
413 Atom wm_protocols = XInternAtom(wxGlobalDisplay(), "WM_PROTOCOLS", True);;
414
415 if (event->xclient.message_type == wm_protocols)
416 {
6a44bffd 417 if ((Atom) (event->xclient.data.l[0]) == wm_delete_window)
b513212d
JS
418 {
419 if (win)
420 {
421 win->Close(FALSE);
422 }
423 }
424 }
425 return;
426 }
c31a82c1
RR
427 case ConfigureNotify:
428 {
429 if (win)
430 {
431 wxSizeEvent sizeEvent( wxSize(event->xconfigure.width,event->xconfigure.height), win->GetId() );
432 sizeEvent.SetEventObject( win );
433
434 win->GetEventHandler()->ProcessEvent( sizeEvent );
435 }
436 }
1b0fb34b 437 case ResizeRequest:
7eaac9f5 438 {
1b0fb34b
JS
439 /* Terry Gitnick <terryg@scientech.com> - 1/21/98
440 * If resize event, don't resize until the last resize event for this
441 * window is recieved. Prevents flicker as windows are resized.
442 */
443
7266b672 444 Display *disp = (Display*) wxGetDisplay();
1b0fb34b
JS
445 XEvent report;
446
447 // to avoid flicker
448 report = * event;
449 while( XCheckTypedWindowEvent (disp, actualWindow, ResizeRequest, &report));
450
451 // TODO: when implementing refresh optimization, we can use
452 // XtAddExposureToRegion to expand the window's paint region.
453
454 if (win)
455 {
456 wxSize sz = win->GetSize();
457 wxSizeEvent sizeEvent(sz, win->GetId());
458 sizeEvent.SetEventObject(win);
459
b513212d 460 win->GetEventHandler()->ProcessEvent( sizeEvent );
1b0fb34b
JS
461 }
462
7eaac9f5
JS
463 return;
464 }
1b0fb34b 465 case Expose:
7eaac9f5 466 {
1b0fb34b
JS
467 if (win)
468 {
1934d291
RR
469 win->GetUpdateRegion().Union( event->xexpose.x, event->xexpose.y,
470 event->xexpose.width, event->xexpose.height);
ba696cfa
RR
471
472 win->GetClearRegion().Union( event->xexpose.x, event->xexpose.y,
473 event->xexpose.width, event->xexpose.height);
474
475 // if (event->xexpose.count == 0)
476 // win->Update();
1b0fb34b
JS
477 }
478
7eaac9f5
JS
479 return;
480 }
1b0fb34b
JS
481 case EnterNotify:
482 case LeaveNotify:
483 case ButtonPress:
484 case ButtonRelease:
485 case MotionNotify:
7eaac9f5 486 {
b513212d
JS
487 if (win && !win->IsEnabled())
488 return;
489
1b0fb34b
JS
490 if (win)
491 {
492 wxMouseEvent wxevent;
493 wxTranslateMouseEvent(wxevent, win, window, event);
b513212d 494 win->GetEventHandler()->ProcessEvent( wxevent );
1b0fb34b 495 }
7eaac9f5
JS
496 return;
497 }
1b0fb34b
JS
498 case FocusIn:
499 {
500 if (win && event->xfocus.detail != NotifyPointer)
501 {
ba696cfa
RR
502 wxLogDebug( "FocusIn from %s", win->GetName().c_str() );
503
1b0fb34b
JS
504 wxFocusEvent focusEvent(wxEVT_SET_FOCUS, win->GetId());
505 focusEvent.SetEventObject(win);
b513212d 506 win->GetEventHandler()->ProcessEvent(focusEvent);
1b0fb34b
JS
507 }
508 break;
509 }
510 case FocusOut:
511 {
512 if (win && event->xfocus.detail != NotifyPointer)
513 {
ba696cfa
RR
514 wxLogDebug( "FocusOut from %s\n", win->GetName().c_str() );
515
1b0fb34b
JS
516 wxFocusEvent focusEvent(wxEVT_KILL_FOCUS, win->GetId());
517 focusEvent.SetEventObject(win);
b513212d 518 win->GetEventHandler()->ProcessEvent(focusEvent);
1b0fb34b
JS
519 }
520 break;
521 }
b513212d
JS
522 case DestroyNotify:
523 {
524 // Do we want to process this (for top-level windows)?
525 // But we want to be able to veto closes, anyway
526 break;
527 }
1b0fb34b
JS
528 default:
529 {
45ff6421
JS
530#ifdef __WXDEBUG__
531 //wxString eventName = wxGetXEventName(XEvent& event);
532 //wxLogDebug(wxT("Event %s not handled"), eventName.c_str());
533#endif
1b0fb34b
JS
534 break;
535 }
83df96d6
JS
536 }
537}
538
539// Returns TRUE if more time is needed.
1b0fb34b
JS
540// Note that this duplicates wxEventLoopImpl::SendIdleEvent
541// but ProcessIdle may be needed by apps, so is kept.
83df96d6
JS
542bool wxApp::ProcessIdle()
543{
544 wxIdleEvent event;
545 event.SetEventObject(this);
546 ProcessEvent(event);
547
548 return event.MoreRequested();
549}
550
551void wxApp::ExitMainLoop()
552{
1b0fb34b
JS
553 if (m_mainLoop)
554 m_mainLoop->Exit(0);
83df96d6
JS
555}
556
557// Is a message/event pending?
558bool wxApp::Pending()
559{
1b0fb34b 560 return wxEventLoop::GetActive()->Pending();
83df96d6
JS
561}
562
563// Dispatch a message.
564void wxApp::Dispatch()
565{
1b0fb34b 566 wxEventLoop::GetActive()->Dispatch();
83df96d6
JS
567}
568
569// This should be redefined in a derived class for
570// handling property change events for XAtom IPC.
571void wxApp::HandlePropertyChange(WXEvent *event)
572{
573 // by default do nothing special
7eaac9f5
JS
574 // TODO: what to do for X11
575 // XtDispatchEvent((XEvent*) event); /* let Motif do the work */
83df96d6
JS
576}
577
578void wxApp::OnIdle(wxIdleEvent& event)
579{
0d1dff01 580 static bool s_inOnIdle = FALSE;
83df96d6
JS
581
582 // Avoid recursion (via ProcessEvent default case)
0d1dff01 583 if (s_inOnIdle)
83df96d6
JS
584 return;
585
0d1dff01 586 s_inOnIdle = TRUE;
83df96d6 587
0d1dff01
RR
588 // Resend in the main thread events which have been prepared in other
589 // threads
83df96d6
JS
590 ProcessPendingEvents();
591
0d1dff01 592 // 'Garbage' collection of windows deleted with Close()
83df96d6
JS
593 DeletePendingObjects();
594
83df96d6
JS
595 // Send OnIdle events to all windows
596 bool needMore = SendIdleEvents();
597
598 if (needMore)
599 event.RequestMore(TRUE);
600
0d1dff01 601 s_inOnIdle = FALSE;
83df96d6
JS
602}
603
604void wxWakeUpIdle()
605{
606 // **** please implement me! ****
607 // Wake up the idle handler processor, even if it is in another thread...
608}
609
610
611// Send idle event to all top-level windows
612bool wxApp::SendIdleEvents()
613{
614 bool needMore = FALSE;
615
616 wxWindowList::Node* node = wxTopLevelWindows.GetFirst();
617 while (node)
618 {
619 wxWindow* win = node->GetData();
620 if (SendIdleEvents(win))
621 needMore = TRUE;
622 node = node->GetNext();
623 }
624
625 return needMore;
626}
627
628// Send idle event to window and all subwindows
629bool wxApp::SendIdleEvents(wxWindow* win)
630{
631 bool needMore = FALSE;
632
633 wxIdleEvent event;
634 event.SetEventObject(win);
0d1dff01
RR
635
636 win->GetEventHandler()->ProcessEvent(event);
637
638 win->OnInternalIdle();
83df96d6
JS
639
640 if (event.MoreRequested())
641 needMore = TRUE;
642
643 wxNode* node = win->GetChildren().First();
644 while (node)
645 {
646 wxWindow* win = (wxWindow*) node->Data();
647 if (SendIdleEvents(win))
648 needMore = TRUE;
649
650 node = node->Next();
651 }
0d1dff01
RR
652
653 return needMore;
83df96d6
JS
654}
655
656void wxApp::DeletePendingObjects()
657{
658 wxNode *node = wxPendingDelete.First();
659 while (node)
660 {
661 wxObject *obj = (wxObject *)node->Data();
662
663 delete obj;
664
665 if (wxPendingDelete.Member(obj))
666 delete node;
667
668 // Deleting one object may have deleted other pending
669 // objects, so start from beginning of list again.
670 node = wxPendingDelete.First();
671 }
672}
673
674// Create an application context
675bool wxApp::OnInitGui()
676{
ca7497c2
JS
677 // Eventually this line will be removed, but for
678 // now we don't want to try popping up a dialog
679 // for error messages.
680 delete wxLog::SetActiveTarget(new wxLogStderr);
a11672a4 681
ea596687
JS
682 if (!wxAppBase::OnInitGui())
683 return FALSE;
684
83df96d6 685
a11672a4
RR
686 GetMainColormap( wxApp::GetDisplay() );
687 m_maxRequestSize = XMaxRequestSize( (Display*) wxApp::GetDisplay() );
83df96d6
JS
688
689 return TRUE;
690}
691
692WXColormap wxApp::GetMainColormap(WXDisplay* display)
693{
694 if (!display) /* Must be called first with non-NULL display */
695 return m_mainColormap;
696
697 int defaultScreen = DefaultScreen((Display*) display);
698 Screen* screen = XScreenOfDisplay((Display*) display, defaultScreen);
699
700 Colormap c = DefaultColormapOfScreen(screen);
701
702 if (!m_mainColormap)
703 m_mainColormap = (WXColormap) c;
704
705 return (WXColormap) c;
706}
707
8354aa92 708Window wxGetWindowParent(Window window)
7eaac9f5 709{
86fd8bda
RR
710 wxASSERT_MSG( window, "invalid window" );
711
712 return (Window) 0;
713
7eaac9f5
JS
714 Window parent, root = 0;
715 unsigned int noChildren = 0;
ea596687
JS
716 Window* children = NULL;
717 int res = XQueryTree((Display*) wxGetDisplay(), window, & root, & parent,
718 & children, & noChildren);
719 if (children)
720 XFree(children);
721 if (res)
7eaac9f5
JS
722 return parent;
723 else
724 return (Window) 0;
725}
726
83df96d6
JS
727void wxExit()
728{
729 int retValue = 0;
730 if (wxTheApp)
731 retValue = wxTheApp->OnExit();
732
733 wxApp::CleanUp();
734 /*
735 * Exit in some platform-specific way. Not recommended that the app calls this:
736 * only for emergencies.
737 */
738 exit(retValue);
739}
740
741// Yield to other processes
742
743bool wxApp::Yield(bool onlyIfNeeded)
744{
745 bool s_inYield = FALSE;
746
747 if ( s_inYield )
748 {
749 if ( !onlyIfNeeded )
750 {
751 wxFAIL_MSG( wxT("wxYield called recursively" ) );
752 }
753
754 return FALSE;
755 }
756
757 s_inYield = TRUE;
758
759 while (wxTheApp && wxTheApp->Pending())
760 wxTheApp->Dispatch();
761
762 s_inYield = FALSE;
763
764 return TRUE;
765}
766
767// TODO use XmGetPixmap (?) to get the really standard icons!
768
769// XPM hack: make the arrays const
770#define static static const
771
772#include "wx/generic/info.xpm"
773#include "wx/generic/error.xpm"
774#include "wx/generic/question.xpm"
775#include "wx/generic/warning.xpm"
776
777#undef static
778
779wxIcon
780wxApp::GetStdIcon(int which) const
781{
782 switch(which)
783 {
784 case wxICON_INFORMATION:
785 return wxIcon(info_xpm);
786
787 case wxICON_QUESTION:
788 return wxIcon(question_xpm);
789
790 case wxICON_EXCLAMATION:
791 return wxIcon(warning_xpm);
792
793 default:
794 wxFAIL_MSG("requested non existent standard icon");
795 // still fall through
796
797 case wxICON_HAND:
798 return wxIcon(error_xpm);
799 }
800}
801
7edcafa4
JS
802void wxApp::OnAssert(const wxChar *file, int line, const wxChar *msg)
803{
804 // While the GUI isn't working that well, just print out the
805 // message.
806#if 0
807 wxAppBase::OnAssert(file, line, msg);
808#else
809 wxString msg2;
810 msg2.Printf("At file %s:%d: %s", file, line, msg);
811 wxLogDebug(msg2);
812#endif
813}
814