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