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