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