]> git.saurik.com Git - wxWidgets.git/blame - src/mgl/app.cpp
update to the latest version of the patch at #10320 the wxApp::DoYield implementation
[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"
d7ae4a62 35#include "wx/private/fontmgr.h"
32b8ec41
VZ
36
37//-----------------------------------------------------------------------------
505f0a85 38// wxApp::Exit()
32b8ec41
VZ
39//-----------------------------------------------------------------------------
40
e2478fde 41void wxApp::Exit()
32b8ec41 42{
7bdc1879 43 MGL_exit();
32b8ec41
VZ
44 exit(0);
45}
46
47//-----------------------------------------------------------------------------
48// wxYield
49//-----------------------------------------------------------------------------
50
d48b06bd 51bool wxApp::DoYield(bool onlyIfNeeded, long eventsToProcess)
32b8ec41 52{
d181e877 53 if ( m_isInsideYield )
e1218bd6
VS
54 {
55 if ( !onlyIfNeeded )
56 {
57 wxFAIL_MSG( wxT("wxYield called recursively" ) );
58 }
59
0471d486 60 return false;
e1218bd6
VS
61 }
62
7bdc1879
VS
63#if wxUSE_THREADS
64 if ( !wxThread::IsMain() )
65 {
66 // can't process events from other threads, MGL is thread-unsafe
0471d486 67 return true;
7bdc1879
VS
68 }
69#endif // wxUSE_THREADS
70
d181e877 71 m_isInsideYield = true;
d48b06bd 72 m_eventsToProcessInsideYield = eventsToProcess;
7bdc1879
VS
73
74 wxLog::Suspend();
75
2ddff00c
VZ
76 wxEventLoopBase * const eventLoop = wxEventLoop::GetActive();
77 if ( eventLoop )
ef344ff8 78 {
d48b06bd
FM
79 // TODO: implement event filtering using the eventsToProcess mask
80
2ddff00c
VZ
81 while (eventLoop->Pending())
82 eventLoop->Dispatch();
ef344ff8 83 }
7c9955d1 84
7bdc1879
VS
85 /* it's necessary to call ProcessIdle() to update the frames sizes which
86 might have been changed (it also will update other things set from
87 OnUpdateUI() which is a nice (and desired) side effect) */
88 while (wxTheApp->ProcessIdle()) { }
89
90 wxLog::Resume();
91
d181e877 92 m_isInsideYield = false;
7bdc1879 93
0471d486 94 return true;
32b8ec41
VZ
95}
96
7bdc1879 97
32b8ec41
VZ
98//-----------------------------------------------------------------------------
99// wxWakeUpIdle
100//-----------------------------------------------------------------------------
101
e2478fde 102void wxApp::WakeUpIdle()
32b8ec41 103{
7bdc1879
VS
104#if wxUSE_THREADS
105 if (!wxThread::IsMain())
106 wxMutexGuiEnter();
107#endif
108
e2478fde
VZ
109 while (wxTheApp->ProcessIdle())
110 ;
7bdc1879
VS
111
112#if wxUSE_THREADS
113 if (!wxThread::IsMain())
114 wxMutexGuiLeave();
115#endif
32b8ec41
VZ
116}
117
58061670
VS
118//-----------------------------------------------------------------------------
119// Root window
120//-----------------------------------------------------------------------------
121
122class wxRootWindow : public wxWindow
123{
124 public:
0471d486 125 wxRootWindow() : wxWindow(NULL, wxID_ANY)
58061670
VS
126 {
127 SetMGLwindow_t(MGL_wmGetRootWindow(g_winMng));
128 SetBackgroundColour(wxTHEME_COLOUR(DESKTOP));
129 }
d3c7fc99 130 virtual ~wxRootWindow()
58061670
VS
131 {
132 // we don't want to delete MGL_WM's rootWnd
7c9955d1 133 m_wnd = NULL;
58061670
VS
134 }
135
0471d486 136 virtual bool AcceptsFocus() const { return false; }
7c9955d1 137
b7d5acd0 138 DECLARE_DYNAMIC_CLASS(wxRootWindow)
58061670
VS
139};
140
b7d5acd0
VS
141IMPLEMENT_DYNAMIC_CLASS(wxRootWindow, wxWindow)
142
58061670
VS
143static wxRootWindow *gs_rootWindow = NULL;
144
145//-----------------------------------------------------------------------------
146// MGL initialization
147//-----------------------------------------------------------------------------
148
fedec981 149static bool wxCreateMGL_WM(const wxVideoMode& displayMode)
58061670
VS
150{
151 int mode;
58061670 152 int refresh = MGL_DEFAULT_REFRESH;
7c9955d1 153
58061670 154#if wxUSE_SYSTEM_OPTIONS
05c9ccbe 155 if ( wxSystemOptions::HasOption(wxT("mgl.screen-refresh")) )
58061670
VS
156 refresh = wxSystemOptions::GetOptionInt(wxT("mgl.screen-refresh"));
157#endif
7c9955d1
JS
158
159 mode = MGL_findMode(displayMode.GetWidth(),
160 displayMode.GetHeight(),
634f6a1f 161 displayMode.GetDepth());
58061670
VS
162 if ( mode == -1 )
163 {
7c9955d1 164 wxLogError(_("Mode %ix%i-%i not available."),
d76048f5
VS
165 displayMode.GetWidth(),
166 displayMode.GetHeight(),
634f6a1f 167 displayMode.GetDepth());
0471d486 168 return false;
58061670
VS
169 }
170 g_displayDC = new MGLDisplayDC(mode, 1, refresh);
171 if ( !g_displayDC->isValid() )
172 {
173 delete g_displayDC;
174 g_displayDC = NULL;
0471d486 175 return false;
58061670 176 }
7c9955d1 177
58061670
VS
178 g_winMng = MGL_wmCreate(g_displayDC->getDC());
179 if (!g_winMng)
0471d486 180 return false;
1f43b5c9 181
0471d486 182 return true;
58061670
VS
183}
184
185static void wxDestroyMGL_WM()
186{
187 if ( g_winMng )
188 {
189 MGL_wmDestroy(g_winMng);
190 g_winMng = NULL;
191 }
192 if ( g_displayDC )
193 {
194 delete g_displayDC;
195 g_displayDC = NULL;
196 }
197}
198
32b8ec41
VZ
199//-----------------------------------------------------------------------------
200// wxApp
201//-----------------------------------------------------------------------------
202
203IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
204
752464f9 205wxApp::wxApp()
7bdc1879
VS
206{
207}
208
209wxApp::~wxApp()
210{
211}
212
fedec981 213wxVideoMode wxGetDefaultDisplayMode()
a3e76614
VS
214{
215 wxString mode;
216 unsigned w, h, bpp;
217
7c9955d1 218 if ( !wxGetEnv(wxT("WXMODE"), &mode) ||
a3e76614
VS
219 (wxSscanf(mode.c_str(), _T("%ux%u-%u"), &w, &h, &bpp) != 3) )
220 {
221 w = 640, h = 480, bpp = 16;
222 }
223
fedec981 224 return wxVideoMode(w, h, bpp);
a3e76614
VS
225}
226
fedec981 227bool wxApp::SetDisplayMode(const wxVideoMode& mode)
634f6a1f
VS
228{
229 if ( !mode.IsOk() )
230 {
0471d486 231 return false;
634f6a1f
VS
232 }
233 if ( g_displayDC != NULL )
234 {
235 // FIXME_MGL -- we currently don't allow to switch video mode
1f43b5c9 236 // more than once. This can hopefully be changed...
634f6a1f 237 wxFAIL_MSG(wxT("Can't change display mode after intialization!"));
0471d486 238 return false;
634f6a1f 239 }
1f43b5c9
VS
240
241 if ( !wxCreateMGL_WM(mode) )
0471d486 242 return false;
1f43b5c9
VS
243 gs_rootWindow = new wxRootWindow;
244
634f6a1f 245 m_displayMode = mode;
1f43b5c9 246
0471d486 247 return true;
634f6a1f
VS
248}
249
7bdc1879
VS
250bool wxApp::OnInitGui()
251{
7bdc1879 252 if ( !wxAppBase::OnInitGui() )
0471d486 253 return false;
7bdc1879 254
d76048f5
VS
255#ifdef __WXDEBUG__
256 // MGL redirects stdout and stderr to physical console, so lets redirect
0471d486 257 // it to file in debug build. Do it only when WXSTDERR environment variable is set
343e418c
VS
258 wxString redirect;
259 if ( wxGetEnv(wxT("WXSTDERR"), &redirect) )
260 freopen(redirect.mb_str(), "wt", stderr);
0471d486 261#endif // __WXDEBUG__
2ec3892d 262
d76048f5
VS
263 wxLog *oldLog = wxLog::SetActiveTarget(new wxLogGui);
264 if ( oldLog ) delete oldLog;
265
0471d486 266 return true;
7bdc1879
VS
267}
268
05e2b077 269bool wxApp::Initialize(int& argc, wxChar **argv)
7bdc1879 270{
05e2b077
VZ
271#ifdef __DJGPP__
272 // VS: disable long filenames under DJGPP as the very first thing,
273 // since SciTech MGL doesn't like them much...
274 wxSetEnv(wxT("LFN"), wxT("N"));
275#endif
276
79481be2
MW
277 // intialize MGL before creating wxFontsManager since it uses MGL funcs
278 if ( MGL_init(".", NULL) == 0 )
279 {
280 wxLogError(_("Cannot initialize SciTech MGL!"));
281 return false;
282 }
283
94826170 284 if ( !wxAppBase::Initialize(argc, argv) )
ddfca47f 285 {
79481be2 286 MGL_exit();
94826170
VZ
287 return false;
288 }
7bdc1879 289
7bdc1879
VS
290#if wxUSE_INTL
291 wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
292#endif
293
94826170 294 return true;
32b8ec41
VZ
295}
296
bfb8eb7e
MW
297// Modules are cleaned up after wxApp::CleanUp(), and some modules may
298// require MGL to still be alive, e.g. the stock fonts need the fonts
299// manager. So append this module last minute in wxApp::CleanUp() to close
300// down MGL after all the other modules have been cleaned up.
301//
302struct wxMGLFinalCleanup: public wxModule
303{
304 bool OnInit() { return true; }
305
306 void OnExit()
307 {
d7ae4a62 308 wxFontsManager::CleanUp();
bfb8eb7e
MW
309
310 wxDestroyMGL_WM();
311 MGL_exit();
312 }
313};
314
7bdc1879
VS
315void wxApp::CleanUp()
316{
d76048f5
VS
317 delete gs_rootWindow;
318
94826170 319 wxAppBase::CleanUp();
7bdc1879 320
bfb8eb7e 321 wxModule::RegisterModule(new wxMGLFinalCleanup);
7bdc1879 322}