]>
Commit | Line | Data |
---|---|---|
3373d6bf JS |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: emulator.cpp | |
be5a51fb | 3 | // Purpose: Emulator wxWidgets sample |
3373d6bf JS |
4 | // Author: Julian Smart |
5 | // Modified by: | |
6 | // Created: 04/01/98 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) Julian Smart | |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | // ============================================================================ | |
13 | // declarations | |
14 | // ============================================================================ | |
15 | ||
653eafdf | 16 | #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) |
3373d6bf JS |
17 | #pragma implementation "emulator.h" |
18 | #endif | |
19 | ||
20 | // ---------------------------------------------------------------------------- | |
21 | // headers | |
22 | // ---------------------------------------------------------------------------- | |
23 | ||
24 | // For compilers that support precompilation, includes "wx/wx.h". | |
25 | #include "wx/wxprec.h" | |
26 | ||
27 | #ifdef __BORLANDC__ | |
28 | #pragma hdrstop | |
29 | #endif | |
30 | ||
31 | // for all others, include the necessary headers (this file is usually all you | |
be5a51fb | 32 | // need because it includes almost all "standard" wxWidgets headers) |
3373d6bf JS |
33 | #ifndef WX_PRECOMP |
34 | #include "wx/wx.h" | |
35 | #endif | |
36 | ||
d1b327e1 JS |
37 | #include "wx/confbase.h" |
38 | #include "wx/fileconf.h" | |
39 | #include "wx/cmdline.h" | |
723c433f | 40 | #include "wx/image.h" |
9f55ceab | 41 | #include "wx/file.h" |
d1b327e1 | 42 | |
abe89c8a | 43 | #ifdef __WXX11__ |
3373d6bf JS |
44 | #include "wx/x11/reparent.h" |
45 | #endif | |
46 | ||
0470b382 JS |
47 | #include "emulator.h" |
48 | ||
3373d6bf JS |
49 | // ---------------------------------------------------------------------------- |
50 | // resources | |
51 | // ---------------------------------------------------------------------------- | |
52 | ||
53 | // the application icon (under Windows and OS/2 it is in resources) | |
54 | #if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__) | |
d1b327e1 | 55 | #include "emulator.xpm" |
3373d6bf JS |
56 | #endif |
57 | ||
58 | // ---------------------------------------------------------------------------- | |
be5a51fb | 59 | // event tables and other macros for wxWidgets |
3373d6bf JS |
60 | // ---------------------------------------------------------------------------- |
61 | ||
be5a51fb | 62 | // the event tables connect the wxWidgets events with the functions (event |
3373d6bf JS |
63 | // handlers) which process them. It can be also done at run-time, but for the |
64 | // simple menu events like this the static method is much simpler. | |
65 | BEGIN_EVENT_TABLE(wxEmulatorFrame, wxFrame) | |
66 | EVT_MENU(Emulator_Quit, wxEmulatorFrame::OnQuit) | |
67 | EVT_MENU(Emulator_About, wxEmulatorFrame::OnAbout) | |
d27294ac | 68 | EVT_CLOSE(wxEmulatorFrame::OnCloseWindow) |
3373d6bf JS |
69 | END_EVENT_TABLE() |
70 | ||
be5a51fb | 71 | // Create a new application object: this macro will allow wxWidgets to create |
3373d6bf JS |
72 | // the application object during program execution (it's better than using a |
73 | // static object for many reasons) and also declares the accessor function | |
74 | // wxGetApp() which will return the reference of the right type (i.e. wxEmulatorApp and | |
75 | // not wxApp) | |
76 | IMPLEMENT_APP(wxEmulatorApp) | |
77 | ||
d1b327e1 JS |
78 | static const wxCmdLineEntryDesc sg_cmdLineDesc[] = |
79 | { | |
dc9b3bf7 | 80 | { wxCMD_LINE_OPTION, _T("u"), _T("use-display"), _T("display number to use (default 100)") }, |
d1b327e1 | 81 | |
dc9b3bf7 JS |
82 | { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("displays help on the command line parameters") }, |
83 | { wxCMD_LINE_SWITCH, _T("v"), _T("version"), _T("print version") }, | |
d1b327e1 | 84 | |
dc9b3bf7 | 85 | { wxCMD_LINE_PARAM, NULL, NULL, _T("config file 1"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, |
d1b327e1 JS |
86 | |
87 | { wxCMD_LINE_NONE } | |
88 | }; | |
89 | ||
90 | ||
3373d6bf JS |
91 | // ============================================================================ |
92 | // implementation | |
93 | // ============================================================================ | |
94 | ||
95 | // ---------------------------------------------------------------------------- | |
96 | // the application class | |
97 | // ---------------------------------------------------------------------------- | |
98 | ||
99 | wxEmulatorApp::wxEmulatorApp() | |
100 | { | |
101 | m_xnestWindow = NULL; | |
102 | m_containerWindow = NULL; | |
d1b327e1 | 103 | m_displayNumber = wxT("100"); |
d27294ac JS |
104 | m_xnestPID = 0; |
105 | ||
3373d6bf JS |
106 | } |
107 | ||
108 | // 'Main program' equivalent: the program execution "starts" here | |
109 | bool wxEmulatorApp::OnInit() | |
110 | { | |
453bacf4 | 111 | #if wxUSE_LOG |
d27294ac | 112 | wxLog::SetTimestamp(NULL); |
453bacf4 | 113 | #endif // wxUSE_LOG |
3373d6bf JS |
114 | wxInitAllImageHandlers(); |
115 | ||
d1b327e1 JS |
116 | wxString currentDir = wxGetCwd(); |
117 | ||
118 | // Use argv to get current app directory | |
119 | m_appDir = wxFindAppPath(argv[0], currentDir, wxT("WXEMUDIR")); | |
abe89c8a | 120 | |
d1b327e1 JS |
121 | // If the development version, go up a directory. |
122 | #ifdef __WXMSW__ | |
dc9b3bf7 JS |
123 | if ((m_appDir.Right(5).CmpNoCase(_T("DEBUG")) == 0) || |
124 | (m_appDir.Right(11).CmpNoCase(_T("DEBUGSTABLE")) == 0) || | |
125 | (m_appDir.Right(7).CmpNoCase(_T("RELEASE")) == 0) || | |
126 | (m_appDir.Right(13).CmpNoCase(_T("RELEASESTABLE")) == 0) | |
d1b327e1 JS |
127 | ) |
128 | m_appDir = wxPathOnly(m_appDir); | |
129 | #endif | |
130 | ||
131 | // Parse the command-line parameters and options | |
132 | wxCmdLineParser parser(sg_cmdLineDesc, argc, argv); | |
133 | int res; | |
134 | { | |
135 | wxLogNull log; | |
136 | res = parser.Parse(); | |
137 | } | |
138 | if (res == -1 || res > 0 || parser.Found(wxT("h"))) | |
139 | { | |
140 | #ifdef __X__ | |
141 | wxLog::SetActiveTarget(new wxLogStderr); | |
142 | #endif | |
143 | parser.Usage(); | |
abe89c8a | 144 | return false; |
d1b327e1 JS |
145 | } |
146 | if (parser.Found(wxT("v"))) | |
147 | { | |
148 | #ifdef __X__ | |
149 | wxLog::SetActiveTarget(new wxLogStderr); | |
150 | #endif | |
151 | wxString msg; | |
be5a51fb | 152 | msg.Printf(wxT("wxWidgets PDA Emulator (c) Julian Smart, 2002 Version %.2f, %s"), wxEMULATOR_VERSION, __DATE__); |
d1b327e1 | 153 | wxLogMessage(msg); |
abe89c8a | 154 | return false; |
d1b327e1 JS |
155 | } |
156 | if (parser.Found(wxT("u"), & m_displayNumber)) | |
157 | { | |
158 | // Should only be number, so strip out anything before | |
159 | // and including a : character | |
160 | if (m_displayNumber.Find(wxT(':')) != -1) | |
161 | { | |
162 | m_displayNumber = m_displayNumber.AfterFirst(wxT(':')); | |
163 | } | |
164 | } | |
165 | if (parser.GetParamCount() == 0) | |
166 | { | |
167 | m_emulatorInfo.m_emulatorFilename = wxT("default.wxe"); | |
168 | } | |
169 | else if (parser.GetParamCount() > 0) | |
170 | { | |
171 | m_emulatorInfo.m_emulatorFilename = parser.GetParam(0); | |
172 | } | |
3373d6bf JS |
173 | |
174 | // Load the emulation info | |
d1b327e1 | 175 | if (!LoadEmulator(m_appDir)) |
3373d6bf | 176 | { |
d1b327e1 | 177 | //wxMessageBox(wxT("Sorry, could not load this emulator. Please check bitmaps are valid.")); |
abe89c8a | 178 | return false; |
3373d6bf | 179 | } |
abe89c8a | 180 | |
d1b327e1 JS |
181 | // create the main application window |
182 | wxEmulatorFrame *frame = new wxEmulatorFrame(_T("wxEmulator"), | |
183 | wxPoint(50, 50), wxSize(450, 340)); | |
abe89c8a | 184 | |
d96cdd4a | 185 | #if wxUSE_STATUSBAR |
d1b327e1 JS |
186 | frame->SetStatusText(m_emulatorInfo.m_emulatorTitle, 0); |
187 | ||
188 | wxString sizeStr; | |
189 | sizeStr.Printf(wxT("Screen: %dx%d"), (int) m_emulatorInfo.m_emulatorScreenSize.x, | |
190 | (int) m_emulatorInfo.m_emulatorScreenSize.y); | |
191 | frame->SetStatusText(sizeStr, 1); | |
d96cdd4a | 192 | #endif // wxUSE_STATUSBAR |
d1b327e1 | 193 | |
abe89c8a | 194 | m_containerWindow = new wxEmulatorContainer(frame, wxID_ANY); |
d1b327e1 JS |
195 | |
196 | frame->SetClientSize(m_emulatorInfo.m_emulatorDeviceSize.x, | |
197 | m_emulatorInfo.m_emulatorDeviceSize.y); | |
abe89c8a | 198 | |
3373d6bf JS |
199 | // and show it (the frames, unlike simple controls, are not shown when |
200 | // created initially) | |
abe89c8a DS |
201 | frame->Show(true); |
202 | ||
203 | #ifdef __WXX11__ | |
3373d6bf JS |
204 | m_xnestWindow = new wxAdoptedWindow; |
205 | ||
206 | wxString cmd; | |
d27294ac | 207 | cmd.Printf(wxT("Xnest :%s -geometry %dx%d"), |
d1b327e1 JS |
208 | m_displayNumber.c_str(), |
209 | (int) m_emulatorInfo.m_emulatorScreenSize.x, | |
210 | (int) m_emulatorInfo.m_emulatorScreenSize.y); | |
3373d6bf | 211 | |
d27294ac JS |
212 | // Asynchronously executes Xnest |
213 | m_xnestPID = wxExecute(cmd); | |
214 | if (0 == m_xnestPID) | |
3373d6bf JS |
215 | { |
216 | frame->Destroy(); | |
217 | wxMessageBox(wxT("Sorry, could not run Xnest. Please check your PATH.")); | |
abe89c8a | 218 | return false; |
3373d6bf | 219 | } |
abe89c8a | 220 | |
3373d6bf JS |
221 | wxReparenter reparenter; |
222 | if (!reparenter.WaitAndReparent(m_containerWindow, m_xnestWindow, wxT("Xnest"))) | |
223 | { | |
224 | wxMessageBox(wxT("Sorry, could not reparent Xnest..")); | |
225 | frame->Destroy(); | |
abe89c8a | 226 | return false; |
3373d6bf | 227 | } |
0470b382 | 228 | |
3373d6bf | 229 | #endif |
d1b327e1 | 230 | m_containerWindow->DoResize(); |
3373d6bf JS |
231 | |
232 | // success: wxApp::OnRun() will be called which will enter the main message | |
abe89c8a | 233 | // loop and the application will run. If we returned false here, the |
3373d6bf | 234 | // application would exit immediately. |
abe89c8a | 235 | return true; |
3373d6bf JS |
236 | } |
237 | ||
d1b327e1 JS |
238 | // Prepend the current program directory to the name |
239 | wxString wxEmulatorApp::GetFullAppPath(const wxString& filename) const | |
3373d6bf | 240 | { |
d1b327e1 JS |
241 | wxString path(m_appDir); |
242 | if (path.Last() != '\\' && path.Last() != '/' && filename[0] != '\\' && filename[0] != '/') | |
243 | #ifdef __X__ | |
244 | path += '/'; | |
245 | #else | |
246 | path += '\\'; | |
247 | #endif | |
248 | path += filename; | |
abe89c8a | 249 | |
d1b327e1 JS |
250 | return path; |
251 | } | |
3373d6bf | 252 | |
3373d6bf | 253 | |
d1b327e1 JS |
254 | // Load the specified emulator. |
255 | // For now, hard-wired. TODO: make this configurable | |
256 | bool wxEmulatorApp::LoadEmulator(const wxString& appDir) | |
257 | { | |
258 | // Load config file and bitmaps | |
259 | return m_emulatorInfo.Load(appDir); | |
3373d6bf JS |
260 | } |
261 | ||
262 | // ---------------------------------------------------------------------------- | |
263 | // main frame | |
264 | // ---------------------------------------------------------------------------- | |
265 | ||
266 | // frame constructor | |
abe89c8a DS |
267 | wxEmulatorFrame::wxEmulatorFrame(const wxString& title, |
268 | const wxPoint& pos, const wxSize& size) | |
269 | : wxFrame(NULL, wxID_ANY, title, pos, size) | |
3373d6bf JS |
270 | { |
271 | // set the frame icon | |
d1b327e1 | 272 | SetIcon(wxICON(emulator)); |
3373d6bf JS |
273 | |
274 | #if wxUSE_MENUS | |
275 | // create a menu bar | |
276 | wxMenu *menuFile = new wxMenu; | |
277 | ||
278 | // the "About" item should be in the help menu | |
279 | wxMenu *helpMenu = new wxMenu; | |
280 | helpMenu->Append(Emulator_About, _T("&About...\tF1"), _T("Show about dialog")); | |
281 | ||
282 | menuFile->Append(Emulator_Quit, _T("E&xit\tAlt-X"), _T("Quit this program")); | |
283 | ||
284 | // now append the freshly created menu to the menu bar... | |
285 | wxMenuBar *menuBar = new wxMenuBar(); | |
286 | menuBar->Append(menuFile, _T("&File")); | |
287 | menuBar->Append(helpMenu, _T("&Help")); | |
288 | ||
289 | // ... and attach this menu bar to the frame | |
290 | SetMenuBar(menuBar); | |
291 | #endif // wxUSE_MENUS | |
292 | ||
293 | #if wxUSE_STATUSBAR | |
294 | // create a status bar just for fun (by default with 1 pane only) | |
295 | CreateStatusBar(2); | |
3373d6bf JS |
296 | #endif // wxUSE_STATUSBAR |
297 | } | |
298 | ||
299 | ||
300 | // event handlers | |
301 | ||
302 | void wxEmulatorFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) | |
303 | { | |
abe89c8a DS |
304 | // true is to force the frame to close |
305 | Close(true); | |
3373d6bf JS |
306 | } |
307 | ||
308 | void wxEmulatorFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) | |
309 | { | |
310 | wxString msg; | |
311 | msg.Printf( _T("wxEmulator is an environment for testing embedded X11 apps.\n")); | |
312 | ||
313 | wxMessageBox(msg, _T("About wxEmulator"), wxOK | wxICON_INFORMATION, this); | |
314 | } | |
315 | ||
dc9b3bf7 | 316 | void wxEmulatorFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event)) |
d27294ac JS |
317 | { |
318 | #ifdef __WXX11__ | |
319 | if (wxGetApp().m_xnestWindow) | |
320 | { | |
321 | wxGetApp().m_xnestWindow->SetHandle((WXWindow) NULL); | |
322 | } | |
323 | #endif | |
324 | this->Destroy(); | |
325 | if (wxGetApp().m_xnestPID > 0) | |
326 | { | |
327 | wxKill(wxGetApp().m_xnestPID); | |
328 | wxGetApp().m_xnestPID = 0; | |
329 | } | |
330 | } | |
331 | ||
3373d6bf JS |
332 | IMPLEMENT_CLASS(wxEmulatorContainer, wxWindow) |
333 | ||
334 | BEGIN_EVENT_TABLE(wxEmulatorContainer, wxWindow) | |
335 | EVT_SIZE(wxEmulatorContainer::OnSize) | |
336 | EVT_PAINT(wxEmulatorContainer::OnPaint) | |
337 | EVT_ERASE_BACKGROUND(wxEmulatorContainer::OnEraseBackground) | |
338 | END_EVENT_TABLE() | |
339 | ||
340 | wxEmulatorContainer::wxEmulatorContainer(wxWindow* parent, wxWindowID id): | |
341 | wxWindow(parent, id, wxDefaultPosition, wxDefaultSize) | |
342 | { | |
343 | } | |
344 | ||
dc9b3bf7 | 345 | void wxEmulatorContainer::OnSize(wxSizeEvent& WXUNUSED(event)) |
0470b382 JS |
346 | { |
347 | DoResize(); | |
348 | } | |
349 | ||
350 | void wxEmulatorContainer::DoResize() | |
3373d6bf JS |
351 | { |
352 | wxSize sz = GetClientSize(); | |
d27294ac JS |
353 | if (wxGetApp().m_xnestWindow |
354 | #ifdef __WXX11__ | |
355 | && wxGetApp().m_xnestWindow->GetMainWindow() | |
356 | #endif | |
357 | ) | |
3373d6bf | 358 | { |
d1b327e1 JS |
359 | int deviceWidth = wxGetApp().m_emulatorInfo.m_emulatorDeviceSize.x; |
360 | int deviceHeight = wxGetApp().m_emulatorInfo.m_emulatorDeviceSize.y; | |
abe89c8a | 361 | |
d1b327e1 JS |
362 | int x = wxMax(0, (int) ((sz.x - deviceWidth)/2.0)); |
363 | int y = wxMax(0, (int) ((sz.y - deviceHeight)/2.0)); | |
abe89c8a | 364 | |
3373d6bf JS |
365 | x += wxGetApp().m_emulatorInfo.m_emulatorScreenPosition.x; |
366 | y += wxGetApp().m_emulatorInfo.m_emulatorScreenPosition.y; | |
abe89c8a | 367 | |
3373d6bf JS |
368 | wxGetApp().m_xnestWindow->Move(x, y); |
369 | } | |
370 | Refresh(); | |
371 | } | |
372 | ||
dc9b3bf7 | 373 | void wxEmulatorContainer::OnPaint(wxPaintEvent& WXUNUSED(event)) |
3373d6bf JS |
374 | { |
375 | wxPaintDC dc(this); | |
abe89c8a | 376 | |
3373d6bf JS |
377 | wxSize sz = GetClientSize(); |
378 | if (wxGetApp().m_emulatorInfo.m_emulatorBackgroundBitmap.Ok()) | |
379 | { | |
d1b327e1 JS |
380 | int deviceWidth = wxGetApp().m_emulatorInfo.m_emulatorDeviceSize.x; |
381 | int deviceHeight = wxGetApp().m_emulatorInfo.m_emulatorDeviceSize.y; | |
abe89c8a | 382 | |
d1b327e1 JS |
383 | int x = wxMax(0, (int) ((sz.x - deviceWidth)/2.0)); |
384 | int y = wxMax(0, (int) ((sz.y - deviceHeight)/2.0)); | |
abe89c8a | 385 | |
3373d6bf JS |
386 | dc.DrawBitmap(wxGetApp().m_emulatorInfo.m_emulatorBackgroundBitmap, x, y); |
387 | } | |
388 | } | |
389 | ||
390 | void wxEmulatorContainer::OnEraseBackground(wxEraseEvent& event) | |
391 | { | |
abe89c8a DS |
392 | wxDC* dc wxDUMMY_INITIALIZE(NULL); |
393 | ||
3373d6bf JS |
394 | if (event.GetDC()) |
395 | { | |
396 | dc = event.GetDC(); | |
397 | } | |
398 | else | |
399 | { | |
400 | dc = new wxClientDC(this); | |
401 | } | |
abe89c8a | 402 | |
3373d6bf JS |
403 | dc->SetBackground(wxBrush(wxGetApp().m_emulatorInfo.m_emulatorBackgroundColour, wxSOLID)); |
404 | dc->Clear(); | |
abe89c8a | 405 | |
3373d6bf JS |
406 | if (!event.GetDC()) |
407 | delete dc; | |
408 | } | |
409 | ||
410 | // Information about the emulator decorations | |
411 | ||
412 | void wxEmulatorInfo::Copy(const wxEmulatorInfo& info) | |
413 | { | |
d1b327e1 | 414 | m_emulatorFilename = info.m_emulatorFilename; |
3373d6bf JS |
415 | m_emulatorTitle = info.m_emulatorTitle; |
416 | m_emulatorDescription = info.m_emulatorDescription; | |
417 | m_emulatorScreenPosition = info.m_emulatorScreenPosition; | |
418 | m_emulatorScreenSize = info.m_emulatorScreenSize; | |
419 | m_emulatorBackgroundBitmap = info.m_emulatorBackgroundBitmap; | |
420 | m_emulatorBackgroundBitmapName = info.m_emulatorBackgroundBitmapName; | |
421 | m_emulatorBackgroundColour = info.m_emulatorBackgroundColour; | |
d1b327e1 | 422 | m_emulatorDeviceSize = info.m_emulatorDeviceSize; |
3373d6bf JS |
423 | } |
424 | ||
425 | // Initialisation | |
426 | void wxEmulatorInfo::Init() | |
427 | { | |
d1b327e1 JS |
428 | m_emulatorDeviceSize = wxSize(260, 340); |
429 | m_emulatorScreenSize = wxSize(240, 320); | |
3373d6bf JS |
430 | } |
431 | ||
432 | // Loads bitmaps | |
d1b327e1 | 433 | bool wxEmulatorInfo::Load(const wxString& appDir) |
3373d6bf | 434 | { |
d1b327e1 JS |
435 | // Try to find absolute path |
436 | wxString absoluteConfigPath = m_emulatorFilename; | |
abe89c8a | 437 | if ( !::wxIsAbsolutePath(absoluteConfigPath) ) |
d1b327e1 JS |
438 | { |
439 | wxString currDir = wxGetCwd(); | |
440 | absoluteConfigPath = currDir + wxString(wxFILE_SEP_PATH) + m_emulatorFilename; | |
abe89c8a | 441 | if ( !wxFile::Exists(absoluteConfigPath) ) |
d1b327e1 | 442 | { |
abe89c8a DS |
443 | absoluteConfigPath = appDir + wxString(wxFILE_SEP_PATH) |
444 | + m_emulatorFilename; | |
d1b327e1 JS |
445 | } |
446 | } | |
abe89c8a DS |
447 | |
448 | if ( !wxFile::Exists(absoluteConfigPath) ) | |
d1b327e1 JS |
449 | { |
450 | wxString str; | |
abe89c8a DS |
451 | str.Printf( wxT("Could not find config file %s"), |
452 | absoluteConfigPath.c_str() ); | |
453 | ||
d1b327e1 | 454 | wxMessageBox(str); |
abe89c8a | 455 | return false; |
d1b327e1 | 456 | } |
3373d6bf | 457 | |
d1b327e1 JS |
458 | wxString rootPath = wxPathOnly(absoluteConfigPath); |
459 | ||
460 | { | |
be5a51fb | 461 | wxFileConfig config(wxT("wxEmulator"), wxT("wxWidgets"), |
d1b327e1 JS |
462 | absoluteConfigPath, wxEmptyString, wxCONFIG_USE_LOCAL_FILE); |
463 | ||
464 | config.Read(wxT("/General/title"), & m_emulatorTitle); | |
465 | config.Read(wxT("/General/description"), & m_emulatorDescription); | |
466 | config.Read(wxT("/General/backgroundBitmap"), & m_emulatorBackgroundBitmapName); | |
467 | ||
468 | wxString colString; | |
469 | if (config.Read(wxT("/General/backgroundColour"), & colString) || | |
470 | config.Read(wxT("/General/backgroundColor"), & colString) | |
471 | ) | |
472 | { | |
473 | m_emulatorBackgroundColour = wxHexStringToColour(colString); | |
474 | } | |
475 | ||
476 | int x = 0, y = 0, w = 0, h = 0, dw = 0, dh = 0; | |
477 | config.Read(wxT("/General/screenX"), & x); | |
478 | config.Read(wxT("/General/screenY"), & y); | |
479 | config.Read(wxT("/General/screenWidth"), & w); | |
480 | config.Read(wxT("/General/screenHeight"), & h); | |
481 | if (config.Read(wxT("/General/deviceWidth"), & dw) && config.Read(wxT("/General/deviceHeight"), & dh)) | |
482 | { | |
483 | m_emulatorDeviceSize = wxSize(dw, dh); | |
484 | } | |
485 | ||
486 | m_emulatorScreenPosition = wxPoint(x, y); | |
487 | m_emulatorScreenSize = wxSize(w, h); | |
488 | } | |
abe89c8a | 489 | |
d1b327e1 JS |
490 | if (!m_emulatorBackgroundBitmapName.IsEmpty()) |
491 | { | |
492 | wxString absoluteBackgroundBitmapName = rootPath + wxString(wxFILE_SEP_PATH) + m_emulatorBackgroundBitmapName; | |
abe89c8a | 493 | if ( !wxFile::Exists(absoluteBackgroundBitmapName) ) |
d1b327e1 JS |
494 | { |
495 | wxString str; | |
abe89c8a DS |
496 | str.Printf( wxT("Could not find bitmap %s"), |
497 | absoluteBackgroundBitmapName.c_str() ); | |
d1b327e1 | 498 | wxMessageBox(str); |
abe89c8a | 499 | return false; |
d1b327e1 | 500 | } |
abe89c8a | 501 | |
723c433f GD |
502 | wxBitmapType type = wxDetermineImageType(m_emulatorBackgroundBitmapName); |
503 | if (type == wxBITMAP_TYPE_INVALID) | |
abe89c8a DS |
504 | return false; |
505 | ||
d1b327e1 JS |
506 | if (!m_emulatorBackgroundBitmap.LoadFile(m_emulatorBackgroundBitmapName, type)) |
507 | { | |
508 | wxString str; | |
abe89c8a DS |
509 | str.Printf( wxT("Could not load bitmap file %s"), |
510 | m_emulatorBackgroundBitmapName.c_str() ); | |
d1b327e1 | 511 | wxMessageBox(str); |
abe89c8a | 512 | return false; |
d1b327e1 | 513 | } |
abe89c8a | 514 | |
d1b327e1 JS |
515 | m_emulatorDeviceSize = wxSize(m_emulatorBackgroundBitmap.GetWidth(), |
516 | m_emulatorBackgroundBitmap.GetHeight()); | |
517 | } | |
abe89c8a | 518 | return true; |
3373d6bf JS |
519 | } |
520 | ||
521 | // Returns the image type, or -1, determined from the extension. | |
723c433f | 522 | wxBitmapType wxDetermineImageType(const wxString& filename) |
3373d6bf JS |
523 | { |
524 | wxString path, name, ext; | |
525 | ||
526 | wxSplitPath(filename, & path, & name, & ext); | |
527 | ||
528 | ext.MakeLower(); | |
dc9b3bf7 | 529 | if (ext == _T("jpg") || ext == _T("jpeg")) |
3373d6bf | 530 | return wxBITMAP_TYPE_JPEG; |
dc9b3bf7 | 531 | if (ext == _T("gif")) |
3373d6bf | 532 | return wxBITMAP_TYPE_GIF; |
dc9b3bf7 | 533 | if (ext == _T("bmp")) |
3373d6bf | 534 | return wxBITMAP_TYPE_BMP; |
dc9b3bf7 | 535 | if (ext == _T("png")) |
3373d6bf | 536 | return wxBITMAP_TYPE_PNG; |
dc9b3bf7 | 537 | if (ext == _T("pcx")) |
3373d6bf | 538 | return wxBITMAP_TYPE_PCX; |
dc9b3bf7 | 539 | if (ext == _T("tif") || ext == _T("tiff")) |
3373d6bf | 540 | return wxBITMAP_TYPE_TIF; |
abe89c8a | 541 | |
723c433f | 542 | return wxBITMAP_TYPE_INVALID; |
3373d6bf JS |
543 | } |
544 | ||
d1b327e1 JS |
545 | // Convert a colour to a 6-digit hex string |
546 | wxString wxColourToHexString(const wxColour& col) | |
547 | { | |
548 | wxString hex; | |
549 | ||
550 | hex += wxDecToHex(col.Red()); | |
551 | hex += wxDecToHex(col.Green()); | |
552 | hex += wxDecToHex(col.Blue()); | |
553 | ||
554 | return hex; | |
555 | } | |
556 | ||
557 | // Convert 6-digit hex string to a colour | |
558 | wxColour wxHexStringToColour(const wxString& hex) | |
559 | { | |
254a2129 WS |
560 | unsigned char r = (unsigned char)wxHexToDec(hex.Mid(0, 2)); |
561 | unsigned char g = (unsigned char)wxHexToDec(hex.Mid(2, 2)); | |
562 | unsigned char b = (unsigned char)wxHexToDec(hex.Mid(4, 2)); | |
d1b327e1 JS |
563 | |
564 | return wxColour(r, g, b); | |
565 | } | |
566 | ||
567 | // Find the absolute path where this application has been run from. | |
568 | // argv0 is wxTheApp->argv[0] | |
569 | // cwd is the current working directory (at startup) | |
570 | // appVariableName is the name of a variable containing the directory for this app, e.g. | |
571 | // MYAPPDIR. This is checked first. | |
572 | ||
573 | wxString wxFindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName) | |
574 | { | |
575 | wxString str; | |
576 | ||
577 | // Try appVariableName | |
578 | if (!appVariableName.IsEmpty()) | |
579 | { | |
580 | str = wxGetenv(appVariableName); | |
581 | if (!str.IsEmpty()) | |
582 | return str; | |
583 | } | |
584 | ||
585 | if (wxIsAbsolutePath(argv0)) | |
586 | return wxPathOnly(argv0); | |
587 | else | |
588 | { | |
589 | // Is it a relative path? | |
590 | wxString currentDir(cwd); | |
083f7497 | 591 | if (!wxEndsWithPathSeparator(currentDir)) |
d1b327e1 JS |
592 | currentDir += wxFILE_SEP_PATH; |
593 | ||
594 | str = currentDir + argv0; | |
abe89c8a | 595 | if ( wxFile::Exists(str) ) |
d1b327e1 JS |
596 | return wxPathOnly(str); |
597 | } | |
598 | ||
599 | // OK, it's neither an absolute path nor a relative path. | |
600 | // Search PATH. | |
601 | ||
602 | wxPathList pathList; | |
603 | pathList.AddEnvList(wxT("PATH")); | |
604 | str = pathList.FindAbsoluteValidPath(argv0); | |
605 | if (!str.IsEmpty()) | |
606 | return wxPathOnly(str); | |
607 | ||
608 | // Failed | |
609 | return wxEmptyString; | |
610 | } | |
3373d6bf | 611 |