1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "app.h"
19 #include "wx/gdicmn.h"
21 #include "wx/dialog.h"
23 #include "wx/module.h"
24 #include "wx/memory.h"
27 #include "wx/evtloop.h"
29 #include "wx/filename.h"
32 #include "wx/univ/theme.h"
33 #include "wx/univ/renderer.h"
36 #include "wx/thread.h"
39 #include "wx/x11/private.h"
43 //------------------------------------------------------------------------
45 //------------------------------------------------------------------------
47 extern wxList wxPendingDelete
;
49 wxHashTable
*wxWidgetHashTable
= NULL
;
50 wxHashTable
*wxClientWidgetHashTable
= NULL
;
52 wxApp
*wxTheApp
= NULL
;
54 // This is set within wxEntryStart -- too early on
55 // to put these in wxTheApp
56 static bool g_showIconic
= FALSE
;
57 static wxSize g_initialSize
= wxDefaultSize
;
59 // This is required for wxFocusEvent::SetWindow(). It will only
60 // work for focus events which we provoke ourselves (by calling
61 // SetFocus()). It will not work for those events, which X11
63 static wxWindow
*g_nextFocus
= NULL
;
64 static wxWindow
*g_prevFocus
= NULL
;
66 //------------------------------------------------------------------------
68 //------------------------------------------------------------------------
71 typedef int (*XErrorHandlerFunc
)(Display
*, XErrorEvent
*);
73 XErrorHandlerFunc gs_pfnXErrorHandler
= 0;
75 static int wxXErrorHandler(Display
*dpy
, XErrorEvent
*xevent
)
77 // just forward to the default handler for now
78 if (gs_pfnXErrorHandler
)
79 return gs_pfnXErrorHandler(dpy
, xevent
);
85 //------------------------------------------------------------------------
87 //------------------------------------------------------------------------
89 long wxApp::sm_lastMessageTime
= 0;
90 WXDisplay
*wxApp::ms_display
= NULL
;
92 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
94 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
95 EVT_IDLE(wxApp::OnIdle
)
98 bool wxApp::Initialize()
100 wxClassInfo::InitializeClasses();
103 wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
106 // GL: I'm annoyed ... I don't know where to put this and I don't want to
107 // create a module for that as it's part of the core.
109 wxPendingEventsLocker
= new wxCriticalSection();
112 wxTheColourDatabase
= new wxColourDatabase(wxKEY_STRING
);
113 wxTheColourDatabase
->Initialize();
115 wxInitializeStockLists();
116 wxInitializeStockObjects();
118 wxWidgetHashTable
= new wxHashTable(wxKEY_INTEGER
);
119 wxClientWidgetHashTable
= new wxHashTable(wxKEY_INTEGER
);
121 wxModule::RegisterModules();
122 if (!wxModule::InitializeModules()) return FALSE
;
127 void wxApp::CleanUp()
129 delete wxWidgetHashTable
;
130 wxWidgetHashTable
= NULL
;
131 delete wxClientWidgetHashTable
;
132 wxClientWidgetHashTable
= NULL
;
134 wxModule::CleanUpModules();
136 delete wxTheColourDatabase
;
137 wxTheColourDatabase
= NULL
;
139 wxDeleteStockObjects();
141 wxDeleteStockLists();
146 wxClassInfo::CleanUpClasses();
149 delete wxPendingEvents
;
150 delete wxPendingEventsLocker
;
153 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
154 // At this point we want to check if there are any memory
155 // blocks that aren't part of the wxDebugContext itself,
156 // as a special case. Then when dumping we need to ignore
157 // wxDebugContext, too.
158 if (wxDebugContext::CountObjectsLeft(TRUE
) > 0)
160 wxLogDebug("There were memory leaks.");
161 wxDebugContext::Dump();
162 wxDebugContext::PrintStatistics();
166 // do it as the very last thing because everything else can log messages
167 wxLog::DontCreateOnDemand();
168 // do it as the very last thing because everything else can log messages
169 delete wxLog::SetActiveTarget(NULL
);
172 // NB: argc and argv may be changed here, pass by reference!
173 int wxEntryStart( int& argc
, char *argv
[] )
177 // install the X error handler
178 gs_pfnXErrorHandler
= XSetErrorHandler( wxXErrorHandler
);
180 #endif // __WXDEBUG__
182 char *displayName
= NULL
;
183 bool syncDisplay
= FALSE
;
186 for (i
= 0; i
< argc
; i
++)
188 if (strcmp( argv
[i
], "-display") == 0)
193 displayName
= argv
[i
];
197 else if (strcmp( argv
[i
], "-geometry") == 0)
203 if (sscanf(argv
[i
], "%dx%d", &w
, &h
) != 2)
205 wxLogError( _("Invalid geometry specification '%s'"), wxString::FromAscii(argv
[i
]).c_str() );
209 g_initialSize
= wxSize(w
, h
);
214 else if (strcmp( argv
[i
], "-sync") == 0)
219 else if (strcmp( argv
[i
], "-iconic") == 0)
229 Display
* xdisplay
= XOpenDisplay( displayName
);
232 wxLogError( _("wxWindows could not open display. Exiting.") );
237 XSynchronize(xdisplay
, True
);
239 wxApp::ms_display
= (WXDisplay
*) xdisplay
;
241 XSelectInput( xdisplay
, XDefaultRootWindow(xdisplay
), PropertyChangeMask
);
244 wxSetDetectableAutoRepeat( TRUE
);
247 // Glib's type system required by Pango
251 if (!wxApp::Initialize())
261 if ( !wxTheApp
->OnInitGui() )
268 int wxEntry( int argc
, char *argv
[] )
270 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
271 // This seems to be necessary since there are 'rogue'
272 // objects present at this point (perhaps global objects?)
273 // Setting a checkpoint will ignore them as far as the
274 // memory checking facility is concerned.
275 // Of course you may argue that memory allocated in globals should be
276 // checked, but this is a reasonable compromise.
277 wxDebugContext::SetCheckpoint();
279 int err
= wxEntryStart(argc
, argv
);
285 if (!wxApp::GetInitializerFunction())
287 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
291 wxTheApp
= (wxApp
*) (* wxApp::GetInitializerFunction()) ();
296 printf( "wxWindows error: wxTheApp == NULL\n" );
300 // Command line argument stuff
301 wxTheApp
->argc
= argc
;
303 wxTheApp
->argv
= new wxChar
*[argc
+1];
305 while (mb_argc
< argc
)
307 wxString tmp
= wxString::FromAscii( argv
[mb_argc
] );
308 wxTheApp
->argv
[mb_argc
] = wxStrdup( tmp
.c_str() );
311 wxTheApp
->argv
[mb_argc
] = (wxChar
*)NULL
;
313 wxTheApp
->argv
= argv
;
316 if (wxTheApp
->argc
> 0)
318 wxFileName
fname( wxTheApp
->argv
[0] );
319 wxTheApp
->SetAppName( fname
.GetName() );
322 wxTheApp
->m_showIconic
= g_showIconic
;
323 wxTheApp
->m_initialSize
= g_initialSize
;
326 retValue
= wxEntryInitGui();
328 // Here frames insert themselves automatically into wxTopLevelWindows by
329 // getting created in OnInit().
332 if ( !wxTheApp
->OnInit() )
338 if (wxTheApp
->Initialized()) retValue
= wxTheApp
->OnRun();
341 // flush the logged messages if any
342 wxLog
*pLog
= wxLog::GetActiveTarget();
343 if ( pLog
!= NULL
&& pLog
->HasPendingMessages() )
346 delete wxLog::SetActiveTarget(new wxLogStderr
); // So dialog boxes aren't used
347 // for further messages
349 if (wxTheApp
->GetTopWindow())
351 delete wxTheApp
->GetTopWindow();
352 wxTheApp
->SetTopWindow(NULL
);
355 wxTheApp
->DeletePendingObjects();
364 // Static member initialization
365 wxAppInitializerFunction
wxAppBase::m_appInitFn
= (wxAppInitializerFunction
) NULL
;
369 // TODO: parse the command line
373 m_mainColormap
= (WXColormap
) NULL
;
374 m_topLevelWidget
= (WXWindow
) NULL
;
375 m_maxRequestSize
= 0;
377 m_showIconic
= FALSE
;
378 m_initialSize
= wxDefaultSize
;
392 bool wxApp::Initialized()
400 int wxApp::MainLoop()
403 m_mainLoop
= new wxEventLoop
;
405 rt
= m_mainLoop
->Run();
413 //-----------------------------------------------------------------------
414 // X11 predicate function for exposure compression
415 //-----------------------------------------------------------------------
420 Bool found_non_matching
;
423 static Bool
expose_predicate (Display
*display
, XEvent
*xevent
, XPointer arg
)
425 wxExposeInfo
*info
= (wxExposeInfo
*) arg
;
427 if (info
->found_non_matching
)
430 if (xevent
->xany
.type
!= Expose
)
432 info
->found_non_matching
= TRUE
;
436 if (xevent
->xexpose
.window
!= info
->window
)
438 info
->found_non_matching
= TRUE
;
447 //-----------------------------------------------------------------------
448 // Processes an X event, returning TRUE if the event was processed.
449 //-----------------------------------------------------------------------
451 bool wxApp::ProcessXEvent(WXEvent
* _event
)
453 XEvent
* event
= (XEvent
*) _event
;
455 wxWindow
* win
= NULL
;
456 Window window
= XEventGetWindow(event
);
458 Window actualWindow
= window
;
461 // Find the first wxWindow that corresponds to this event window
462 // Because we're receiving events after a window
463 // has been destroyed, assume a 1:1 match between
464 // Window and wxWindow, so if it's not in the table,
465 // it must have been destroyed.
467 win
= wxGetWindowFromTable(window
);
470 #if wxUSE_TWO_WINDOWS
471 win
= wxGetClientWindowFromTable(window
);
478 wxString windowClass
= win
->GetClassInfo()->GetClassName();
485 #if wxUSE_TWO_WINDOWS && !wxUSE_NANOX
486 if (event
->xexpose
.window
!= (Window
)win
->GetClientAreaWindow())
490 info
.window
= event
->xexpose
.window
;
491 info
.found_non_matching
= FALSE
;
492 while (XCheckIfEvent( wxGlobalDisplay(), &tmp_event
, expose_predicate
, (XPointer
) &info
))
494 // Don't worry about optimizing redrawing the border etc.
496 win
->NeedUpdateNcAreaInIdle();
501 win
->GetUpdateRegion().Union( XExposeEventGetX(event
), XExposeEventGetY(event
),
502 XExposeEventGetWidth(event
), XExposeEventGetHeight(event
));
503 win
->GetClearRegion().Union( XExposeEventGetX(event
), XExposeEventGetY(event
),
504 XExposeEventGetWidth(event
), XExposeEventGetHeight(event
));
509 info
.window
= event
->xexpose
.window
;
510 info
.found_non_matching
= FALSE
;
511 while (XCheckIfEvent( wxGlobalDisplay(), &tmp_event
, expose_predicate
, (XPointer
) &info
))
513 win
->GetUpdateRegion().Union( tmp_event
.xexpose
.x
, tmp_event
.xexpose
.y
,
514 tmp_event
.xexpose
.width
, tmp_event
.xexpose
.height
);
516 win
->GetClearRegion().Union( tmp_event
.xexpose
.x
, tmp_event
.xexpose
.y
,
517 tmp_event
.xexpose
.width
, tmp_event
.xexpose
.height
);
521 // This simplifies the expose and clear areas to simple
523 win
->GetUpdateRegion() = win
->GetUpdateRegion().GetBox();
524 win
->GetClearRegion() = win
->GetClearRegion().GetBox();
526 // If we only have one X11 window, always indicate
527 // that borders might have to be redrawn.
528 if (win
->GetMainWindow() == win
->GetClientAreaWindow())
529 win
->NeedUpdateNcAreaInIdle();
531 // Only erase background, paint in idle time.
532 win
->SendEraseEvents();
544 printf( "GraphicExpose event\n" );
546 wxLogTrace( _T("expose"), _T("GraphicsExpose from %s"), win
->GetName().c_str());
548 win
->GetUpdateRegion().Union( event
->xgraphicsexpose
.x
, event
->xgraphicsexpose
.y
,
549 event
->xgraphicsexpose
.width
, event
->xgraphicsexpose
.height
);
551 win
->GetClearRegion().Union( event
->xgraphicsexpose
.x
, event
->xgraphicsexpose
.y
,
552 event
->xgraphicsexpose
.width
, event
->xgraphicsexpose
.height
);
554 if (event
->xgraphicsexpose
.count
== 0)
556 // Only erase background, paint in idle time.
557 win
->SendEraseEvents();
567 if (!win
->IsEnabled())
570 wxKeyEvent
keyEvent(wxEVT_KEY_DOWN
);
571 wxTranslateKeyEvent(keyEvent
, win
, window
, event
);
573 // wxLogDebug( "OnKey from %s", win->GetName().c_str() );
575 // We didn't process wxEVT_KEY_DOWN, so send wxEVT_CHAR
576 if (win
->GetEventHandler()->ProcessEvent( keyEvent
))
579 keyEvent
.SetEventType(wxEVT_CHAR
);
580 // Do the translation again, retaining the ASCII
582 wxTranslateKeyEvent(keyEvent
, win
, window
, event
, TRUE
);
583 if (win
->GetEventHandler()->ProcessEvent( keyEvent
))
586 if ( (keyEvent
.m_keyCode
== WXK_TAB
) &&
587 win
->GetParent() && (win
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) )
589 wxNavigationKeyEvent new_event
;
590 new_event
.SetEventObject( win
->GetParent() );
591 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
592 new_event
.SetDirection( (keyEvent
.m_keyCode
== WXK_TAB
) );
593 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
594 new_event
.SetWindowChange( keyEvent
.ControlDown() );
595 new_event
.SetCurrentFocus( win
);
596 return win
->GetParent()->GetEventHandler()->ProcessEvent( new_event
);
603 if (!win
->IsEnabled())
606 wxKeyEvent
keyEvent(wxEVT_KEY_UP
);
607 wxTranslateKeyEvent(keyEvent
, win
, window
, event
);
609 return win
->GetEventHandler()->ProcessEvent( keyEvent
);
611 case ConfigureNotify
:
614 if (event
->update
.utype
== GR_UPDATE_SIZE
)
617 if (win
->IsTopLevel())
619 wxTopLevelWindow
*tlw
= (wxTopLevelWindow
*) win
;
620 tlw
->SetConfigureGeometry( XConfigureEventGetX(event
), XConfigureEventGetY(event
),
621 XConfigureEventGetWidth(event
), XConfigureEventGetHeight(event
) );
624 if (win
->IsTopLevel() && win
->IsShown())
626 wxTopLevelWindowX11
*tlw
= (wxTopLevelWindowX11
*) win
;
627 tlw
->SetNeedResizeInIdle();
631 wxSizeEvent
sizeEvent( wxSize(XConfigureEventGetWidth(event
), XConfigureEventGetHeight(event
)), win
->GetId() );
632 sizeEvent
.SetEventObject( win
);
634 return win
->GetEventHandler()->ProcessEvent( sizeEvent
);
643 //wxLogDebug("PropertyNotify: %s", windowClass.c_str());
644 return HandlePropertyChange(_event
);
648 if (!win
->IsEnabled())
651 Atom wm_delete_window
= XInternAtom(wxGlobalDisplay(), "WM_DELETE_WINDOW", True
);
652 Atom wm_protocols
= XInternAtom(wxGlobalDisplay(), "WM_PROTOCOLS", True
);
654 if (event
->xclient
.message_type
== wm_protocols
)
656 if ((Atom
) (event
->xclient
.data
.l
[0]) == wm_delete_window
)
667 printf( "destroy from %s\n", win
->GetName().c_str() );
672 printf( "create from %s\n", win
->GetName().c_str() );
677 printf( "map request from %s\n", win
->GetName().c_str() );
682 printf( "resize request from %s\n", win
->GetName().c_str() );
684 Display
*disp
= (Display
*) wxGetDisplay();
689 while( XCheckTypedWindowEvent (disp
, actualWindow
, ResizeRequest
, &report
));
691 wxSize sz
= win
->GetSize();
692 wxSizeEvent
sizeEvent(sz
, win
->GetId());
693 sizeEvent
.SetEventObject(win
);
695 return win
->GetEventHandler()->ProcessEvent( sizeEvent
);
700 case GR_EVENT_TYPE_CLOSE_REQ
:
717 if (!win
->IsEnabled())
720 // Here we check if the top level window is
721 // disabled, which is one aspect of modality.
723 while (tlw
&& !tlw
->IsTopLevel())
724 tlw
= tlw
->GetParent();
725 if (tlw
&& !tlw
->IsEnabled())
728 if (event
->type
== ButtonPress
)
730 if ((win
!= wxWindow::FindFocus()) && win
->AcceptsFocus())
732 // This might actually be done in wxWindow::SetFocus()
733 // and not here. TODO.
734 g_prevFocus
= wxWindow::FindFocus();
737 wxLogTrace( _T("focus"), _T("About to call SetFocus on %s of type %s due to button press"), win
->GetName().c_str(), win
->GetClassInfo()->GetClassName() );
739 // Record the fact that this window is
740 // getting the focus, because we'll need to
741 // check if its parent is getting a bogus
742 // focus and duly ignore it.
743 // TODO: may need to have this code in SetFocus, too.
744 extern wxWindow
* g_GettingFocus
;
745 g_GettingFocus
= win
;
751 if (event
->type
== LeaveNotify
|| event
->type
== EnterNotify
)
753 // Throw out NotifyGrab and NotifyUngrab
754 if (event
->xcrossing
.mode
!= NotifyNormal
)
758 wxMouseEvent wxevent
;
759 wxTranslateMouseEvent(wxevent
, win
, window
, event
);
760 return win
->GetEventHandler()->ProcessEvent( wxevent
);
765 if ((event
->xfocus
.detail
!= NotifyPointer
) &&
766 (event
->xfocus
.mode
== NotifyNormal
))
769 wxLogTrace( _T("focus"), _T("FocusIn from %s of type %s"), win
->GetName().c_str(), win
->GetClassInfo()->GetClassName() );
771 extern wxWindow
* g_GettingFocus
;
772 if (g_GettingFocus
&& g_GettingFocus
->GetParent() == win
)
774 // Ignore this, this can be a spurious FocusIn
775 // caused by a child having its focus set.
776 g_GettingFocus
= NULL
;
777 wxLogTrace( _T("focus"), _T("FocusIn from %s of type %s being deliberately ignored"), win
->GetName().c_str(), win
->GetClassInfo()->GetClassName() );
782 wxFocusEvent
focusEvent(wxEVT_SET_FOCUS
, win
->GetId());
783 focusEvent
.SetEventObject(win
);
784 focusEvent
.SetWindow( g_prevFocus
);
787 return win
->GetEventHandler()->ProcessEvent(focusEvent
);
796 if ((event
->xfocus
.detail
!= NotifyPointer
) &&
797 (event
->xfocus
.mode
== NotifyNormal
))
800 wxLogTrace( _T("focus"), _T("FocusOut from %s of type %s"), win
->GetName().c_str(), win
->GetClassInfo()->GetClassName() );
802 wxFocusEvent
focusEvent(wxEVT_KILL_FOCUS
, win
->GetId());
803 focusEvent
.SetEventObject(win
);
804 focusEvent
.SetWindow( g_nextFocus
);
806 return win
->GetEventHandler()->ProcessEvent(focusEvent
);
814 //wxString eventName = wxGetXEventName(XEvent& event);
815 //wxLogDebug(wxT("Event %s not handled"), eventName.c_str());
824 // Returns TRUE if more time is needed.
825 // Note that this duplicates wxEventLoopImpl::SendIdleEvent
826 // but ProcessIdle may be needed by apps, so is kept.
827 bool wxApp::ProcessIdle()
830 event
.SetEventObject(this);
833 return event
.MoreRequested();
836 void wxApp::ExitMainLoop()
842 // Is a message/event pending?
843 bool wxApp::Pending()
845 return wxEventLoop::GetActive()->Pending();
848 // Dispatch a message.
849 void wxApp::Dispatch()
851 wxEventLoop::GetActive()->Dispatch();
854 // This should be redefined in a derived class for
855 // handling property change events for XAtom IPC.
856 bool wxApp::HandlePropertyChange(WXEvent
*event
)
858 // by default do nothing special
859 // TODO: what to do for X11
860 // XtDispatchEvent((XEvent*) event);
864 void wxApp::OnIdle(wxIdleEvent
& event
)
866 static bool s_inOnIdle
= FALSE
;
868 // Avoid recursion (via ProcessEvent default case)
874 // Resend in the main thread events which have been prepared in other
876 ProcessPendingEvents();
878 // 'Garbage' collection of windows deleted with Close()
879 DeletePendingObjects();
881 // Send OnIdle events to all windows
882 bool needMore
= SendIdleEvents();
885 event
.RequestMore(TRUE
);
892 // **** please implement me! ****
893 // Wake up the idle handler processor, even if it is in another thread...
897 // Send idle event to all top-level windows
898 bool wxApp::SendIdleEvents()
900 bool needMore
= FALSE
;
902 wxWindowList::Node
* node
= wxTopLevelWindows
.GetFirst();
905 wxWindow
* win
= node
->GetData();
906 if (SendIdleEvents(win
))
908 node
= node
->GetNext();
914 // Send idle event to window and all subwindows
915 bool wxApp::SendIdleEvents(wxWindow
* win
)
917 bool needMore
= FALSE
;
920 event
.SetEventObject(win
);
922 win
->GetEventHandler()->ProcessEvent(event
);
924 if (event
.MoreRequested())
927 wxWindowListNode
* node
= win
->GetChildren().GetFirst();
930 wxWindow
* win
= (wxWindow
*) node
->GetData();
931 if (SendIdleEvents(win
))
934 node
= node
->GetNext();
937 win
->OnInternalIdle();
942 void wxApp::DeletePendingObjects()
944 wxNode
*node
= wxPendingDelete
.GetFirst();
947 wxObject
*obj
= (wxObject
*)node
->GetData();
951 if (wxPendingDelete
.Member(obj
))
954 // Deleting one object may have deleted other pending
955 // objects, so start from beginning of list again.
956 node
= wxPendingDelete
.GetFirst();
960 // Create display, and other initialization
961 bool wxApp::OnInitGui()
963 // Eventually this line will be removed, but for
964 // now we don't want to try popping up a dialog
965 // for error messages.
966 delete wxLog::SetActiveTarget(new wxLogStderr
);
968 if (!wxAppBase::OnInitGui())
971 GetMainColormap( wxApp::GetDisplay() );
973 m_maxRequestSize
= XMaxRequestSize( (Display
*) wxApp::GetDisplay() );
976 m_visualInfo
= new wxXVisualInfo
;
977 wxFillXVisualInfo( m_visualInfo
, (Display
*) wxApp::GetDisplay() );
985 #include <pango/pango.h>
986 #include <pango/pangox.h>
987 #include <pango/pangoxft.h>
989 PangoContext
* wxApp::GetPangoContext()
991 static PangoContext
*ret
= NULL
;
995 Display
*xdisplay
= (Display
*) wxApp::GetDisplay();
998 int xscreen
= DefaultScreen(xdisplay
);
999 static int use_xft
= -1;
1002 wxString val
= wxGetenv( L
"GDK_USE_XFT" );
1003 use_xft
= (val
== L
"1");
1007 ret
= pango_xft_get_context( xdisplay
, xscreen
);
1010 ret
= pango_x_get_context( xdisplay
);
1012 if (!PANGO_IS_CONTEXT(ret
))
1013 wxLogError( wxT("No pango context.") );
1019 WXColormap
wxApp::GetMainColormap(WXDisplay
* display
)
1021 if (!display
) /* Must be called first with non-NULL display */
1022 return m_mainColormap
;
1024 int defaultScreen
= DefaultScreen((Display
*) display
);
1025 Screen
* screen
= XScreenOfDisplay((Display
*) display
, defaultScreen
);
1027 Colormap c
= DefaultColormapOfScreen(screen
);
1029 if (!m_mainColormap
)
1030 m_mainColormap
= (WXColormap
) c
;
1032 return (WXColormap
) c
;
1035 Window
wxGetWindowParent(Window window
)
1037 wxASSERT_MSG( window
, "invalid window" );
1041 Window parent
, root
= 0;
1045 unsigned int noChildren
= 0;
1047 Window
* children
= NULL
;
1049 // #define XQueryTree(d,w,r,p,c,nc) GrQueryTree(w,p,c,nc)
1054 XQueryTree((Display
*) wxGetDisplay(), window
, & root
, & parent
,
1055 & children
, & noChildren
);
1068 retValue
= wxTheApp
->OnExit();
1072 * Exit in some platform-specific way. Not recommended that the app calls this:
1073 * only for emergencies.
1078 // Yield to other processes
1080 bool wxApp::Yield(bool onlyIfNeeded
)
1082 // Sometimes only 2 yields seem
1083 // to do the trick, e.g. in the
1086 for (i
= 0; i
< 2; i
++)
1088 bool s_inYield
= FALSE
;
1092 if ( !onlyIfNeeded
)
1094 wxFAIL_MSG( wxT("wxYield called recursively" ) );
1102 // Make sure we have an event loop object,
1103 // or Pending/Dispatch will fail
1104 wxEventLoop
* eventLoop
= wxEventLoop::GetActive();
1105 wxEventLoop
* newEventLoop
= NULL
;
1108 newEventLoop
= new wxEventLoop
;
1109 wxEventLoop::SetActive(newEventLoop
);
1112 // Call dispatch at least once so that sockets
1114 wxTheApp
->Dispatch();
1116 while (wxTheApp
&& wxTheApp
->Pending())
1117 wxTheApp
->Dispatch();
1120 wxTimer::NotifyTimers();
1126 wxEventLoop::SetActive(NULL
);
1127 delete newEventLoop
;
1138 void wxApp::OnAssert(const wxChar
*file
, int line
, const wxChar
* cond
, const wxChar
*msg
)
1140 // While the GUI isn't working that well, just print out the
1143 wxAppBase::OnAssert(file
, line
, cond
, msg
);
1146 msg2
.Printf("At file %s:%d: %s", file
, line
, msg
);
1151 #endif // __WXDEBUG__