]> git.saurik.com Git - wxWidgets.git/blob - src/mgl/app.cpp
Workaround for wxMac since it is unable to dismiss the edit control
[wxWidgets.git] / src / mgl / app.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: app.cpp
3 // Author: Vaclav Slavik
4 // based on GTK and MSW implementations
5 // Id: $Id$
6 // Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #ifdef __BORLANDC__
14 #pragma hdrstop
15 #endif
16
17
18 #ifndef WX_PRECOMP
19 #include "wx/settings.h"
20 #include "wx/frame.h"
21 #include "wx/dialog.h"
22 #include "wx/log.h"
23 #include "wx/intl.h"
24 #endif
25
26 #include "wx/app.h"
27 #include "wx/evtloop.h"
28 #include "wx/module.h"
29 #include "wx/fontutil.h"
30 #include "wx/univ/theme.h"
31 #include "wx/univ/renderer.h"
32 #include "wx/univ/colschem.h"
33 #include "wx/sysopt.h"
34 #include "wx/mgl/private.h"
35
36 //-----------------------------------------------------------------------------
37 // wxApp::Exit()
38 //-----------------------------------------------------------------------------
39
40 void wxApp::Exit()
41 {
42 MGL_exit();
43 exit(0);
44 }
45
46 //-----------------------------------------------------------------------------
47 // wxYield
48 //-----------------------------------------------------------------------------
49
50 static bool gs_inYield = false;
51
52 bool wxApp::Yield(bool onlyIfNeeded)
53 {
54 if ( gs_inYield )
55 {
56 if ( !onlyIfNeeded )
57 {
58 wxFAIL_MSG( wxT("wxYield called recursively" ) );
59 }
60
61 return false;
62 }
63
64 #if wxUSE_THREADS
65 if ( !wxThread::IsMain() )
66 {
67 // can't process events from other threads, MGL is thread-unsafe
68 return true;
69 }
70 #endif // wxUSE_THREADS
71
72 gs_inYield = true;
73
74 wxLog::Suspend();
75
76 if ( wxEventLoop::GetActive() )
77 {
78 while (wxEventLoop::GetActive()->Pending())
79 wxEventLoop::GetActive()->Dispatch();
80 }
81
82 /* it's necessary to call ProcessIdle() to update the frames sizes which
83 might have been changed (it also will update other things set from
84 OnUpdateUI() which is a nice (and desired) side effect) */
85 while (wxTheApp->ProcessIdle()) { }
86
87 wxLog::Resume();
88
89 gs_inYield = false;
90
91 return true;
92 }
93
94
95 //-----------------------------------------------------------------------------
96 // wxWakeUpIdle
97 //-----------------------------------------------------------------------------
98
99 void wxApp::WakeUpIdle()
100 {
101 #if wxUSE_THREADS
102 if (!wxThread::IsMain())
103 wxMutexGuiEnter();
104 #endif
105
106 while (wxTheApp->ProcessIdle())
107 ;
108
109 #if wxUSE_THREADS
110 if (!wxThread::IsMain())
111 wxMutexGuiLeave();
112 #endif
113 }
114
115 //-----------------------------------------------------------------------------
116 // Root window
117 //-----------------------------------------------------------------------------
118
119 class wxRootWindow : public wxWindow
120 {
121 public:
122 wxRootWindow() : wxWindow(NULL, wxID_ANY)
123 {
124 SetMGLwindow_t(MGL_wmGetRootWindow(g_winMng));
125 SetBackgroundColour(wxTHEME_COLOUR(DESKTOP));
126 }
127 ~wxRootWindow()
128 {
129 // we don't want to delete MGL_WM's rootWnd
130 m_wnd = NULL;
131 }
132
133 virtual bool AcceptsFocus() const { return false; }
134
135 DECLARE_DYNAMIC_CLASS(wxRootWindow)
136 };
137
138 IMPLEMENT_DYNAMIC_CLASS(wxRootWindow, wxWindow)
139
140 static wxRootWindow *gs_rootWindow = NULL;
141
142 //-----------------------------------------------------------------------------
143 // MGL initialization
144 //-----------------------------------------------------------------------------
145
146 static bool wxCreateMGL_WM(const wxVideoMode& displayMode)
147 {
148 int mode;
149 int refresh = MGL_DEFAULT_REFRESH;
150
151 #if wxUSE_SYSTEM_OPTIONS
152 if ( wxSystemOptions::HasOption(wxT("mgl.screen-refresh")) )
153 refresh = wxSystemOptions::GetOptionInt(wxT("mgl.screen-refresh"));
154 #endif
155
156 mode = MGL_findMode(displayMode.GetWidth(),
157 displayMode.GetHeight(),
158 displayMode.GetDepth());
159 if ( mode == -1 )
160 {
161 wxLogError(_("Mode %ix%i-%i not available."),
162 displayMode.GetWidth(),
163 displayMode.GetHeight(),
164 displayMode.GetDepth());
165 return false;
166 }
167 g_displayDC = new MGLDisplayDC(mode, 1, refresh);
168 if ( !g_displayDC->isValid() )
169 {
170 delete g_displayDC;
171 g_displayDC = NULL;
172 return false;
173 }
174
175 g_winMng = MGL_wmCreate(g_displayDC->getDC());
176 if (!g_winMng)
177 return false;
178
179 return true;
180 }
181
182 static void wxDestroyMGL_WM()
183 {
184 if ( g_winMng )
185 {
186 MGL_wmDestroy(g_winMng);
187 g_winMng = NULL;
188 }
189 if ( g_displayDC )
190 {
191 delete g_displayDC;
192 g_displayDC = NULL;
193 }
194 }
195
196 //-----------------------------------------------------------------------------
197 // wxApp
198 //-----------------------------------------------------------------------------
199
200 IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
201
202 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
203 EVT_IDLE(wxAppBase::OnIdle)
204 END_EVENT_TABLE()
205
206
207 wxApp::wxApp()
208 {
209 }
210
211 wxApp::~wxApp()
212 {
213 }
214
215 wxVideoMode wxGetDefaultDisplayMode()
216 {
217 wxString mode;
218 unsigned w, h, bpp;
219
220 if ( !wxGetEnv(wxT("WXMODE"), &mode) ||
221 (wxSscanf(mode.c_str(), _T("%ux%u-%u"), &w, &h, &bpp) != 3) )
222 {
223 w = 640, h = 480, bpp = 16;
224 }
225
226 return wxVideoMode(w, h, bpp);
227 }
228
229 bool wxApp::SetDisplayMode(const wxVideoMode& mode)
230 {
231 if ( !mode.IsOk() )
232 {
233 return false;
234 }
235 if ( g_displayDC != NULL )
236 {
237 // FIXME_MGL -- we currently don't allow to switch video mode
238 // more than once. This can hopefully be changed...
239 wxFAIL_MSG(wxT("Can't change display mode after intialization!"));
240 return false;
241 }
242
243 if ( !wxCreateMGL_WM(mode) )
244 return false;
245 gs_rootWindow = new wxRootWindow;
246
247 m_displayMode = mode;
248
249 return true;
250 }
251
252 bool wxApp::OnInitGui()
253 {
254 if ( !wxAppBase::OnInitGui() )
255 return false;
256
257 #ifdef __WXDEBUG__
258 // MGL redirects stdout and stderr to physical console, so lets redirect
259 // it to file in debug build. Do it only when WXSTDERR environment variable is set
260 wxString redirect;
261 if ( wxGetEnv(wxT("WXSTDERR"), &redirect) )
262 freopen(redirect.mb_str(), "wt", stderr);
263 #endif // __WXDEBUG__
264
265 wxLog *oldLog = wxLog::SetActiveTarget(new wxLogGui);
266 if ( oldLog ) delete oldLog;
267
268 return true;
269 }
270
271 bool wxApp::Initialize(int& argc, wxChar **argv)
272 {
273 #ifdef __DJGPP__
274 // VS: disable long filenames under DJGPP as the very first thing,
275 // since SciTech MGL doesn't like them much...
276 wxSetEnv(wxT("LFN"), wxT("N"));
277 #endif
278
279 // intialize MGL before creating wxFontsManager since it uses MGL funcs
280 if ( MGL_init(".", NULL) == 0 )
281 {
282 wxLogError(_("Cannot initialize SciTech MGL!"));
283 return false;
284 }
285
286 // must do it before calling wxAppBase::Initialize(), because fonts are
287 // needed by stock lists which are created there
288 wxTheFontsManager = new wxFontsManager;
289
290 if ( !wxAppBase::Initialize(argc, argv) )
291 {
292 delete wxTheFontsManager;
293 wxTheFontsManager = NULL;
294 MGL_exit();
295 return false;
296 }
297
298 #if wxUSE_INTL
299 wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
300 #endif
301
302 return true;
303 }
304
305 // Modules are cleaned up after wxApp::CleanUp(), and some modules may
306 // require MGL to still be alive, e.g. the stock fonts need the fonts
307 // manager. So append this module last minute in wxApp::CleanUp() to close
308 // down MGL after all the other modules have been cleaned up.
309 //
310 struct wxMGLFinalCleanup: public wxModule
311 {
312 bool OnInit() { return true; }
313
314 void OnExit()
315 {
316 delete wxTheFontsManager;
317 wxTheFontsManager = (wxFontsManager*) NULL;
318
319 wxDestroyMGL_WM();
320 MGL_exit();
321 }
322 };
323
324 void wxApp::CleanUp()
325 {
326 delete gs_rootWindow;
327
328 wxAppBase::CleanUp();
329
330 wxModule::RegisterModule(new wxMGLFinalCleanup);
331 }
332