]> git.saurik.com Git - wxWidgets.git/blame - src/motif/app.cpp
Use wxVisualAttributes (partially #if'd out until tested further.)
[wxWidgets.git] / src / motif / app.cpp
CommitLineData
4bb6408c
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
afb74891 9// Licence: wxWindows licence
4bb6408c
JS
10/////////////////////////////////////////////////////////////////////////////
11
14f355c2 12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
ee31c392 13 #pragma implementation "app.h"
4bb6408c
JS
14#endif
15
1248b41f
MB
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
bcd055ae
JJ
19#ifdef __VMS
20#define XtParent XTPARENT
21#define XtDisplay XTDISPLAY
22#endif
23
4bb6408c
JS
24#include "wx/app.h"
25#include "wx/utils.h"
4bb6408c
JS
26#include "wx/module.h"
27#include "wx/memory.h"
8bedcdce
RR
28#include "wx/log.h"
29#include "wx/intl.h"
7e1bcfa8 30#include "wx/evtloop.h"
ed39ff57 31#include "wx/hash.h"
9ce8d6a2 32#include "wx/hashmap.h"
b412f9be 33
7bcb11d3 34#if wxUSE_THREADS
dfe1eee3 35 #include "wx/thread.h"
7bcb11d3 36#endif
4bb6408c 37
338dd992
JJ
38#ifdef __VMS__
39#pragma message disable nosimpint
40#endif
4bb6408c
JS
41#include <Xm/Xm.h>
42#include <X11/Xlib.h>
43#include <X11/Xutil.h>
44#include <X11/Xresource.h>
45#include <X11/Xatom.h>
338dd992
JJ
46#ifdef __VMS__
47#pragma message enable nosimpint
48#endif
4bb6408c
JS
49
50#include "wx/motif/private.h"
51
52#include <string.h>
53
eb6fa4b4
MB
54struct wxPerDisplayData
55{
56 wxPerDisplayData()
57 { m_visualInfo = NULL; m_topLevelWidget = NULL; }
58
59 wxXVisualInfo* m_visualInfo;
60 Widget m_topLevelWidget;
61};
62
63WX_DECLARE_VOIDPTR_HASH_MAP( wxPerDisplayData, wxPerDisplayDataMap );
64
65static void wxTLWidgetDestroyCallback(Widget w, XtPointer clientData,
66 XtPointer ptr);
67static WXWidget wxCreateTopLevelWidget( WXDisplay* display );
9ce8d6a2 68
4bb6408c 69extern wxList wxPendingDelete;
7e1bcfa8 70extern bool wxAddIdleCallback();
7491d644 71
4bb6408c
JS
72wxHashTable *wxWidgetHashTable = NULL;
73
4bb6408c 74IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
9c6e1335 75
4bb6408c 76BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
955a9197 77 EVT_IDLE(wxAppBase::OnIdle)
4bb6408c 78END_EVENT_TABLE()
4bb6408c 79
e838cc14
VZ
80#ifdef __WXDEBUG__
81 typedef int (*XErrorHandlerFunc)(Display *, XErrorEvent *);
82
83 XErrorHandlerFunc gs_pfnXErrorHandler = 0;
84
85 static int wxXErrorHandler(Display *dpy, XErrorEvent *xevent)
86 {
87 // just forward to the default handler for now
88 return gs_pfnXErrorHandler(dpy, xevent);
89 }
90#endif // __WXDEBUG__
91
05e2b077 92bool wxApp::Initialize(int& argc, wxChar **argv)
4bb6408c 93{
94826170
VZ
94 if ( !wxAppBase::Initialize(argc, argv) )
95 return false;
afb74891 96
4bb6408c 97 wxWidgetHashTable = new wxHashTable(wxKEY_INTEGER);
afb74891 98
94826170 99 return true;
4bb6408c
JS
100}
101
102void wxApp::CleanUp()
103{
e6be3e7c
MB
104 delete wxWidgetHashTable;
105 wxWidgetHashTable = NULL;
106
94826170 107 wxAppBase::CleanUp();
4bb6408c
JS
108}
109
e2478fde
VZ
110void wxApp::Exit()
111{
112 wxApp::CleanUp();
113
114 wxAppConsole::Exit();
115}
116
e6be3e7c 117// ============================================================================
05e2b077 118// wxApp
e6be3e7c
MB
119// ============================================================================
120
4bb6408c
JS
121wxApp::wxApp()
122{
4bb6408c
JS
123 argc = 0;
124 argv = NULL;
afb74891 125
f15b55ce 126 m_mainLoop = new wxEventLoop;
4bb6408c
JS
127 m_mainColormap = (WXColormap) NULL;
128 m_appContext = (WXAppContext) NULL;
47bc1060 129 m_initialDisplay = (WXDisplay*) 0;
eb6fa4b4 130 m_perDisplayData = new wxPerDisplayDataMap;
4bb6408c
JS
131}
132
7e1bcfa8
MB
133wxApp::~wxApp()
134{
f15b55ce 135 delete m_mainLoop;
9ce8d6a2 136
eb6fa4b4
MB
137 for( wxPerDisplayDataMap::iterator it = m_perDisplayData->begin(),
138 end = m_perDisplayData->end();
9ce8d6a2
MB
139 it != end; ++it )
140 {
eb6fa4b4
MB
141 delete it->second.m_visualInfo;
142 XtDestroyWidget( it->second.m_topLevelWidget );
9ce8d6a2
MB
143 }
144
eb6fa4b4
MB
145 delete m_perDisplayData;
146
57bfe3be 147 wxApp::SetInstance(NULL);
7e1bcfa8
MB
148}
149
4bb6408c
JS
150int wxApp::MainLoop()
151{
2d120f83 152 /*
4bb6408c
JS
153 * Sit around forever waiting to process X-events. Property Change
154 * event are handled special, because they have to refer to
155 * the root window rather than to a widget. therefore we can't
156 * use an Xt-eventhandler.
157 */
afb74891 158
4bb6408c 159 XSelectInput(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()),
2d120f83
JS
160 XDefaultRootWindow(XtDisplay((Widget) wxTheApp->GetTopLevelWidget())),
161 PropertyChangeMask);
afb74891 162
f15b55ce 163 m_mainLoop->Run();
afb74891 164
8aa04e8b
JS
165 return 0;
166}
167
4bb6408c
JS
168// This should be redefined in a derived class for
169// handling property change events for XAtom IPC.
170void wxApp::HandlePropertyChange(WXEvent *event)
171{
172 // by default do nothing special
173 XtDispatchEvent((XEvent*) event); /* let Motif do the work */
174}
175
edc1cd8b
JS
176static char *fallbackResources[] = {
177 "*menuBar.marginHeight: 0",
178 "*menuBar.shadowThickness: 1",
179 "*background: #c0c0c0",
180 "*foreground: black",
181 NULL
182};
183
4bb6408c
JS
184// Create an application context
185bool wxApp::OnInitGui()
186{
fd304d98
MB
187 if( !wxAppBase::OnInitGui() )
188 return FALSE;
189
4bb6408c 190 XtToolkitInitialize() ;
edc1cd8b
JS
191 wxTheApp->m_appContext = (WXAppContext) XtCreateApplicationContext();
192 XtAppSetFallbackResources((XtAppContext) wxTheApp->m_appContext, fallbackResources);
193
4bb6408c 194 Display *dpy = XtOpenDisplay((XtAppContext) wxTheApp->m_appContext,(String)NULL,NULL,
d3a80c92 195 wxTheApp->GetClassName().c_str(), NULL, 0,
4bb6408c 196# if XtSpecificationRelease < 5
9c6e1335 197 (Cardinal*) &argc,
4bb6408c 198# else
9c6e1335 199 &argc,
4bb6408c 200# endif
9c6e1335
VZ
201 argv);
202
4bb6408c 203 if (!dpy) {
c88b736c
MB
204 // if you don't log to stderr, nothing will be shown...
205 delete wxLog::SetActiveTarget(new wxLogStderr);
7bcb11d3 206 wxString className(wxTheApp->GetClassName());
9c6e1335 207 wxLogError(_("wxWindows could not open display for '%s': exiting."),
d3a80c92 208 className.c_str());
2d120f83 209 exit(-1);
4bb6408c 210 }
47bc1060 211 m_initialDisplay = (WXDisplay*) dpy;
afb74891 212
e838cc14
VZ
213#ifdef __WXDEBUG__
214 // install the X error handler
215 gs_pfnXErrorHandler = XSetErrorHandler(wxXErrorHandler);
216#endif // __WXDEBUG__
217
4bb6408c
JS
218 // Add general resize proc
219 XtActionsRec rec;
220 rec.string = "resize";
221 rec.proc = (XtActionProc)wxWidgetResizeProc;
222 XtAppAddActions((XtAppContext) wxTheApp->m_appContext, &rec, 1);
afb74891 223
4bb6408c 224 GetMainColormap(dpy);
afb74891 225
7e1bcfa8
MB
226 wxAddIdleCallback();
227
4bb6408c
JS
228 return TRUE;
229}
230
231WXColormap wxApp::GetMainColormap(WXDisplay* display)
232{
233 if (!display) /* Must be called first with non-NULL display */
2d120f83 234 return m_mainColormap;
a91b47e8
JS
235
236 int defaultScreen = DefaultScreen((Display*) display);
237 Screen* screen = XScreenOfDisplay((Display*) display, defaultScreen);
afb74891 238
a91b47e8 239 Colormap c = DefaultColormapOfScreen(screen);
afb74891 240
4bb6408c 241 if (!m_mainColormap)
2d120f83 242 m_mainColormap = (WXColormap) c;
afb74891 243
4bb6408c
JS
244 return (WXColormap) c;
245}
246
9ce8d6a2
MB
247wxXVisualInfo* wxApp::GetVisualInfo( WXDisplay* display )
248{
eb6fa4b4 249 wxPerDisplayDataMap::iterator it = m_perDisplayData->find( display );
9ce8d6a2 250
eb6fa4b4
MB
251 if( it != m_perDisplayData->end() && it->second.m_visualInfo )
252 return it->second.m_visualInfo;
9ce8d6a2
MB
253
254 wxXVisualInfo* vi = new wxXVisualInfo;
255 wxFillXVisualInfo( vi, (Display*)display );
256
eb6fa4b4 257 (*m_perDisplayData)[display].m_visualInfo = vi;
9ce8d6a2
MB
258
259 return vi;
260}
261
eb6fa4b4
MB
262static void wxTLWidgetDestroyCallback(Widget w, XtPointer clientData,
263 XtPointer ptr)
264{
265 if( wxTheApp )
266 wxTheApp->SetTopLevelWidget( (WXDisplay*)XtDisplay(w),
267 (WXWidget)NULL );
268}
269
270WXWidget wxCreateTopLevelWidget( WXDisplay* display )
271{
272 Widget tlw = XtAppCreateShell( (String)NULL,
273 wxTheApp->GetClassName().c_str(),
274 applicationShellWidgetClass,
275 (Display*)display,
276 NULL, 0 );
732c0bfd 277 XtSetMappedWhenManaged( tlw, False );
dd38c875 278 XtRealizeWidget( tlw );
eb6fa4b4
MB
279
280 XtAddCallback( tlw, XmNdestroyCallback,
281 (XtCallbackProc)wxTLWidgetDestroyCallback,
282 (XtPointer)NULL );
283
284 return (WXWidget)tlw;
285}
286
287WXWidget wxApp::GetTopLevelWidget()
288{
289 WXDisplay* display = wxGetDisplay();
290 wxPerDisplayDataMap::iterator it = m_perDisplayData->find( display );
291
292 if( it != m_perDisplayData->end() && it->second.m_topLevelWidget )
293 return (WXWidget)it->second.m_topLevelWidget;
294
295 WXWidget tlw = wxCreateTopLevelWidget( display );
296 SetTopLevelWidget( display, tlw );
297
298 return tlw;
299}
300
301void wxApp::SetTopLevelWidget(WXDisplay* display, WXWidget widget)
302{
303 (*m_perDisplayData)[display].m_topLevelWidget = (Widget)widget;
304}
305
4bb6408c 306// Yield to other processes
cb2713bf 307
8461e4c2 308bool wxApp::Yield(bool onlyIfNeeded)
4bb6408c 309{
f6afb56a 310 static bool s_inYield = FALSE;
8461e4c2
VZ
311
312 if ( s_inYield )
313 {
314 if ( !onlyIfNeeded )
315 {
316 wxFAIL_MSG( wxT("wxYield called recursively" ) );
317 }
318
319 return FALSE;
320 }
321
322 s_inYield = TRUE;
cb2713bf 323
4bb6408c 324 while (wxTheApp && wxTheApp->Pending())
2d120f83 325 wxTheApp->Dispatch();
518b5d2f 326
8461e4c2 327 s_inYield = FALSE;
cb2713bf 328
4bb6408c
JS
329 return TRUE;
330}
331
d391a345
VZ
332// ----------------------------------------------------------------------------
333// accessors for C modules
334// ----------------------------------------------------------------------------
335
336extern "C" XtAppContext wxGetAppContext()
337{
338 return (XtAppContext)wxTheApp->GetAppContext();
339}