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