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