]> git.saurik.com Git - wxWidgets.git/blob - src/mgl/app.cpp
Upport scrolling changes and mouse wheel changes.
[wxWidgets.git] / src / mgl / app.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mgl/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 #include "wx/app.h"
18
19 #ifndef WX_PRECOMP
20 #include "wx/settings.h"
21 #include "wx/frame.h"
22 #include "wx/dialog.h"
23 #include "wx/log.h"
24 #include "wx/intl.h"
25 #include "wx/module.h"
26 #endif
27
28 #include "wx/evtloop.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 #include "wx/private/fontmgr.h"
36
37 //-----------------------------------------------------------------------------
38 // wxApp::Exit()
39 //-----------------------------------------------------------------------------
40
41 void wxApp::Exit()
42 {
43 MGL_exit();
44 exit(0);
45 }
46
47 //-----------------------------------------------------------------------------
48 // wxYield
49 //-----------------------------------------------------------------------------
50
51 static bool gs_inYield = false;
52
53 bool wxApp::Yield(bool onlyIfNeeded)
54 {
55 if ( gs_inYield )
56 {
57 if ( !onlyIfNeeded )
58 {
59 wxFAIL_MSG( wxT("wxYield called recursively" ) );
60 }
61
62 return false;
63 }
64
65 #if wxUSE_THREADS
66 if ( !wxThread::IsMain() )
67 {
68 // can't process events from other threads, MGL is thread-unsafe
69 return true;
70 }
71 #endif // wxUSE_THREADS
72
73 gs_inYield = true;
74
75 wxLog::Suspend();
76
77 wxEventLoopBase * const eventLoop = wxEventLoop::GetActive();
78 if ( eventLoop )
79 {
80 while (eventLoop->Pending())
81 eventLoop->Dispatch();
82 }
83
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
91 gs_inYield = false;
92
93 return true;
94 }
95
96
97 //-----------------------------------------------------------------------------
98 // wxWakeUpIdle
99 //-----------------------------------------------------------------------------
100
101 void wxApp::WakeUpIdle()
102 {
103 #if wxUSE_THREADS
104 if (!wxThread::IsMain())
105 wxMutexGuiEnter();
106 #endif
107
108 while (wxTheApp->ProcessIdle())
109 ;
110
111 #if wxUSE_THREADS
112 if (!wxThread::IsMain())
113 wxMutexGuiLeave();
114 #endif
115 }
116
117 //-----------------------------------------------------------------------------
118 // Root window
119 //-----------------------------------------------------------------------------
120
121 class wxRootWindow : public wxWindow
122 {
123 public:
124 wxRootWindow() : wxWindow(NULL, wxID_ANY)
125 {
126 SetMGLwindow_t(MGL_wmGetRootWindow(g_winMng));
127 SetBackgroundColour(wxTHEME_COLOUR(DESKTOP));
128 }
129 virtual ~wxRootWindow()
130 {
131 // we don't want to delete MGL_WM's rootWnd
132 m_wnd = NULL;
133 }
134
135 virtual bool AcceptsFocus() const { return false; }
136
137 DECLARE_DYNAMIC_CLASS(wxRootWindow)
138 };
139
140 IMPLEMENT_DYNAMIC_CLASS(wxRootWindow, wxWindow)
141
142 static wxRootWindow *gs_rootWindow = NULL;
143
144 //-----------------------------------------------------------------------------
145 // MGL initialization
146 //-----------------------------------------------------------------------------
147
148 static bool wxCreateMGL_WM(const wxVideoMode& displayMode)
149 {
150 int mode;
151 int refresh = MGL_DEFAULT_REFRESH;
152
153 #if wxUSE_SYSTEM_OPTIONS
154 if ( wxSystemOptions::HasOption(wxT("mgl.screen-refresh")) )
155 refresh = wxSystemOptions::GetOptionInt(wxT("mgl.screen-refresh"));
156 #endif
157
158 mode = MGL_findMode(displayMode.GetWidth(),
159 displayMode.GetHeight(),
160 displayMode.GetDepth());
161 if ( mode == -1 )
162 {
163 wxLogError(_("Mode %ix%i-%i not available."),
164 displayMode.GetWidth(),
165 displayMode.GetHeight(),
166 displayMode.GetDepth());
167 return false;
168 }
169 g_displayDC = new MGLDisplayDC(mode, 1, refresh);
170 if ( !g_displayDC->isValid() )
171 {
172 delete g_displayDC;
173 g_displayDC = NULL;
174 return false;
175 }
176
177 g_winMng = MGL_wmCreate(g_displayDC->getDC());
178 if (!g_winMng)
179 return false;
180
181 return true;
182 }
183
184 static 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
198 //-----------------------------------------------------------------------------
199 // wxApp
200 //-----------------------------------------------------------------------------
201
202 IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
203
204 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
205 EVT_IDLE(wxAppBase::OnIdle)
206 END_EVENT_TABLE()
207
208
209 wxApp::wxApp()
210 {
211 }
212
213 wxApp::~wxApp()
214 {
215 }
216
217 wxVideoMode wxGetDefaultDisplayMode()
218 {
219 wxString mode;
220 unsigned w, h, bpp;
221
222 if ( !wxGetEnv(wxT("WXMODE"), &mode) ||
223 (wxSscanf(mode.c_str(), _T("%ux%u-%u"), &w, &h, &bpp) != 3) )
224 {
225 w = 640, h = 480, bpp = 16;
226 }
227
228 return wxVideoMode(w, h, bpp);
229 }
230
231 bool wxApp::SetDisplayMode(const wxVideoMode& mode)
232 {
233 if ( !mode.IsOk() )
234 {
235 return false;
236 }
237 if ( g_displayDC != NULL )
238 {
239 // FIXME_MGL -- we currently don't allow to switch video mode
240 // more than once. This can hopefully be changed...
241 wxFAIL_MSG(wxT("Can't change display mode after intialization!"));
242 return false;
243 }
244
245 if ( !wxCreateMGL_WM(mode) )
246 return false;
247 gs_rootWindow = new wxRootWindow;
248
249 m_displayMode = mode;
250
251 return true;
252 }
253
254 bool wxApp::OnInitGui()
255 {
256 if ( !wxAppBase::OnInitGui() )
257 return false;
258
259 #ifdef __WXDEBUG__
260 // MGL redirects stdout and stderr to physical console, so lets redirect
261 // it to file in debug build. Do it only when WXSTDERR environment variable is set
262 wxString redirect;
263 if ( wxGetEnv(wxT("WXSTDERR"), &redirect) )
264 freopen(redirect.mb_str(), "wt", stderr);
265 #endif // __WXDEBUG__
266
267 wxLog *oldLog = wxLog::SetActiveTarget(new wxLogGui);
268 if ( oldLog ) delete oldLog;
269
270 return true;
271 }
272
273 bool wxApp::Initialize(int& argc, wxChar **argv)
274 {
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
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
288 if ( !wxAppBase::Initialize(argc, argv) )
289 {
290 MGL_exit();
291 return false;
292 }
293
294 #if wxUSE_INTL
295 wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
296 #endif
297
298 return true;
299 }
300
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 //
306 struct wxMGLFinalCleanup: public wxModule
307 {
308 bool OnInit() { return true; }
309
310 void OnExit()
311 {
312 wxFontsManager::CleanUp();
313
314 wxDestroyMGL_WM();
315 MGL_exit();
316 }
317 };
318
319 void wxApp::CleanUp()
320 {
321 delete gs_rootWindow;
322
323 wxAppBase::CleanUp();
324
325 wxModule::RegisterModule(new wxMGLFinalCleanup);
326 }