]> git.saurik.com Git - wxWidgets.git/blame - src/mgl/app.cpp
Fix [ 1574240 ] wx.RadioButton doesn't navigate correctly
[wxWidgets.git] / src / mgl / app.cpp
CommitLineData
32b8ec41 1/////////////////////////////////////////////////////////////////////////////
670f9935 2// Name: src/mgl/app.cpp
32b8ec41 3// Author: Vaclav Slavik
7bdc1879 4// based on GTK and MSW implementations
32b8ec41 5// Id: $Id$
c41c20a5 6// Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
65571936 7// Licence: wxWindows licence
32b8ec41
VZ
8/////////////////////////////////////////////////////////////////////////////
9
7bdc1879
VS
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
13#ifdef __BORLANDC__
14 #pragma hdrstop
15#endif
16
670f9935 17#include "wx/app.h"
2ec3892d 18
7bdc1879
VS
19#ifndef WX_PRECOMP
20 #include "wx/settings.h"
7bdc1879
VS
21 #include "wx/frame.h"
22 #include "wx/dialog.h"
2ec3892d 23 #include "wx/log.h"
7bdc1879 24 #include "wx/intl.h"
02761f6c 25 #include "wx/module.h"
7bdc1879 26#endif
32b8ec41 27
90eb13e6 28#include "wx/evtloop.h"
ef344ff8 29#include "wx/fontutil.h"
df028524
VS
30#include "wx/univ/theme.h"
31#include "wx/univ/renderer.h"
58061670 32#include "wx/univ/colschem.h"
05c9ccbe 33#include "wx/sysopt.h"
7bdc1879 34#include "wx/mgl/private.h"
32b8ec41
VZ
35
36//-----------------------------------------------------------------------------
505f0a85 37// wxApp::Exit()
32b8ec41
VZ
38//-----------------------------------------------------------------------------
39
e2478fde 40void wxApp::Exit()
32b8ec41 41{
7bdc1879 42 MGL_exit();
32b8ec41
VZ
43 exit(0);
44}
45
46//-----------------------------------------------------------------------------
47// wxYield
48//-----------------------------------------------------------------------------
49
0471d486 50static bool gs_inYield = false;
7bdc1879 51
e1218bd6 52bool wxApp::Yield(bool onlyIfNeeded)
32b8ec41 53{
e1218bd6
VS
54 if ( gs_inYield )
55 {
56 if ( !onlyIfNeeded )
57 {
58 wxFAIL_MSG( wxT("wxYield called recursively" ) );
59 }
60
0471d486 61 return false;
e1218bd6
VS
62 }
63
7bdc1879
VS
64#if wxUSE_THREADS
65 if ( !wxThread::IsMain() )
66 {
67 // can't process events from other threads, MGL is thread-unsafe
0471d486 68 return true;
7bdc1879
VS
69 }
70#endif // wxUSE_THREADS
71
0471d486 72 gs_inYield = true;
7bdc1879
VS
73
74 wxLog::Suspend();
75
ef344ff8
VS
76 if ( wxEventLoop::GetActive() )
77 {
78 while (wxEventLoop::GetActive()->Pending())
79 wxEventLoop::GetActive()->Dispatch();
80 }
7c9955d1 81
7bdc1879
VS
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
0471d486 89 gs_inYield = false;
7bdc1879 90
0471d486 91 return true;
32b8ec41
VZ
92}
93
7bdc1879 94
32b8ec41
VZ
95//-----------------------------------------------------------------------------
96// wxWakeUpIdle
97//-----------------------------------------------------------------------------
98
e2478fde 99void wxApp::WakeUpIdle()
32b8ec41 100{
7bdc1879
VS
101#if wxUSE_THREADS
102 if (!wxThread::IsMain())
103 wxMutexGuiEnter();
104#endif
105
e2478fde
VZ
106 while (wxTheApp->ProcessIdle())
107 ;
7bdc1879
VS
108
109#if wxUSE_THREADS
110 if (!wxThread::IsMain())
111 wxMutexGuiLeave();
112#endif
32b8ec41
VZ
113}
114
58061670
VS
115//-----------------------------------------------------------------------------
116// Root window
117//-----------------------------------------------------------------------------
118
119class wxRootWindow : public wxWindow
120{
121 public:
0471d486 122 wxRootWindow() : wxWindow(NULL, wxID_ANY)
58061670
VS
123 {
124 SetMGLwindow_t(MGL_wmGetRootWindow(g_winMng));
125 SetBackgroundColour(wxTHEME_COLOUR(DESKTOP));
126 }
d3c7fc99 127 virtual ~wxRootWindow()
58061670
VS
128 {
129 // we don't want to delete MGL_WM's rootWnd
7c9955d1 130 m_wnd = NULL;
58061670
VS
131 }
132
0471d486 133 virtual bool AcceptsFocus() const { return false; }
7c9955d1 134
b7d5acd0 135 DECLARE_DYNAMIC_CLASS(wxRootWindow)
58061670
VS
136};
137
b7d5acd0
VS
138IMPLEMENT_DYNAMIC_CLASS(wxRootWindow, wxWindow)
139
58061670
VS
140static wxRootWindow *gs_rootWindow = NULL;
141
142//-----------------------------------------------------------------------------
143// MGL initialization
144//-----------------------------------------------------------------------------
145
fedec981 146static bool wxCreateMGL_WM(const wxVideoMode& displayMode)
58061670
VS
147{
148 int mode;
58061670 149 int refresh = MGL_DEFAULT_REFRESH;
7c9955d1 150
58061670 151#if wxUSE_SYSTEM_OPTIONS
05c9ccbe 152 if ( wxSystemOptions::HasOption(wxT("mgl.screen-refresh")) )
58061670
VS
153 refresh = wxSystemOptions::GetOptionInt(wxT("mgl.screen-refresh"));
154#endif
7c9955d1
JS
155
156 mode = MGL_findMode(displayMode.GetWidth(),
157 displayMode.GetHeight(),
634f6a1f 158 displayMode.GetDepth());
58061670
VS
159 if ( mode == -1 )
160 {
7c9955d1 161 wxLogError(_("Mode %ix%i-%i not available."),
d76048f5
VS
162 displayMode.GetWidth(),
163 displayMode.GetHeight(),
634f6a1f 164 displayMode.GetDepth());
0471d486 165 return false;
58061670
VS
166 }
167 g_displayDC = new MGLDisplayDC(mode, 1, refresh);
168 if ( !g_displayDC->isValid() )
169 {
170 delete g_displayDC;
171 g_displayDC = NULL;
0471d486 172 return false;
58061670 173 }
7c9955d1 174
58061670
VS
175 g_winMng = MGL_wmCreate(g_displayDC->getDC());
176 if (!g_winMng)
0471d486 177 return false;
1f43b5c9 178
0471d486 179 return true;
58061670
VS
180}
181
182static 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
32b8ec41
VZ
196//-----------------------------------------------------------------------------
197// wxApp
198//-----------------------------------------------------------------------------
199
200IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
201
202BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
955a9197 203 EVT_IDLE(wxAppBase::OnIdle)
32b8ec41
VZ
204END_EVENT_TABLE()
205
206
752464f9 207wxApp::wxApp()
7bdc1879
VS
208{
209}
210
211wxApp::~wxApp()
212{
213}
214
fedec981 215wxVideoMode wxGetDefaultDisplayMode()
a3e76614
VS
216{
217 wxString mode;
218 unsigned w, h, bpp;
219
7c9955d1 220 if ( !wxGetEnv(wxT("WXMODE"), &mode) ||
a3e76614
VS
221 (wxSscanf(mode.c_str(), _T("%ux%u-%u"), &w, &h, &bpp) != 3) )
222 {
223 w = 640, h = 480, bpp = 16;
224 }
225
fedec981 226 return wxVideoMode(w, h, bpp);
a3e76614
VS
227}
228
fedec981 229bool wxApp::SetDisplayMode(const wxVideoMode& mode)
634f6a1f
VS
230{
231 if ( !mode.IsOk() )
232 {
0471d486 233 return false;
634f6a1f
VS
234 }
235 if ( g_displayDC != NULL )
236 {
237 // FIXME_MGL -- we currently don't allow to switch video mode
1f43b5c9 238 // more than once. This can hopefully be changed...
634f6a1f 239 wxFAIL_MSG(wxT("Can't change display mode after intialization!"));
0471d486 240 return false;
634f6a1f 241 }
1f43b5c9
VS
242
243 if ( !wxCreateMGL_WM(mode) )
0471d486 244 return false;
1f43b5c9
VS
245 gs_rootWindow = new wxRootWindow;
246
634f6a1f 247 m_displayMode = mode;
1f43b5c9 248
0471d486 249 return true;
634f6a1f
VS
250}
251
7bdc1879
VS
252bool wxApp::OnInitGui()
253{
7bdc1879 254 if ( !wxAppBase::OnInitGui() )
0471d486 255 return false;
7bdc1879 256
d76048f5
VS
257#ifdef __WXDEBUG__
258 // MGL redirects stdout and stderr to physical console, so lets redirect
0471d486 259 // it to file in debug build. Do it only when WXSTDERR environment variable is set
343e418c
VS
260 wxString redirect;
261 if ( wxGetEnv(wxT("WXSTDERR"), &redirect) )
262 freopen(redirect.mb_str(), "wt", stderr);
0471d486 263#endif // __WXDEBUG__
2ec3892d 264
d76048f5
VS
265 wxLog *oldLog = wxLog::SetActiveTarget(new wxLogGui);
266 if ( oldLog ) delete oldLog;
267
0471d486 268 return true;
7bdc1879
VS
269}
270
05e2b077 271bool wxApp::Initialize(int& argc, wxChar **argv)
7bdc1879 272{
05e2b077
VZ
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
79481be2
MW
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
94826170
VZ
286 // must do it before calling wxAppBase::Initialize(), because fonts are
287 // needed by stock lists which are created there
288 wxTheFontsManager = new wxFontsManager;
32b8ec41 289
94826170 290 if ( !wxAppBase::Initialize(argc, argv) )
ddfca47f 291 {
79481be2
MW
292 delete wxTheFontsManager;
293 wxTheFontsManager = NULL;
294 MGL_exit();
94826170
VZ
295 return false;
296 }
7bdc1879 297
7bdc1879
VS
298#if wxUSE_INTL
299 wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
300#endif
301
94826170 302 return true;
32b8ec41
VZ
303}
304
bfb8eb7e
MW
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//
310struct 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
7bdc1879
VS
324void wxApp::CleanUp()
325{
d76048f5
VS
326 delete gs_rootWindow;
327
94826170 328 wxAppBase::CleanUp();
7bdc1879 329
bfb8eb7e 330 wxModule::RegisterModule(new wxMGLFinalCleanup);
7bdc1879 331}