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