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