This keyword is not expanded by Git which means it's not replaced with the correct revision value in the releases made using git-based scripts and it's confusing to have lines with unexpanded "$Id$" in the released files. As expanding them with Git is not that simple (it could be done with git archive and export-subst attribute) and there are not many benefits in having them in the first place, just remove all these lines. If nothing else, this will make an eventual transition to Git simpler. Closes #14487. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
608 lines
18 KiB
C++
608 lines
18 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: emulator.cpp
|
|
// Purpose: Emulator wxWidgets sample
|
|
// Author: Julian Smart
|
|
// Modified by:
|
|
// Created: 04/01/98
|
|
// Copyright: (c) Julian Smart
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ============================================================================
|
|
// declarations
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// headers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// For compilers that support precompilation, includes "wx/wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
// for all others, include the necessary headers (this file is usually all you
|
|
// need because it includes almost all "standard" wxWidgets headers)
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/wx.h"
|
|
#endif
|
|
|
|
#include "wx/confbase.h"
|
|
#include "wx/fileconf.h"
|
|
#include "wx/cmdline.h"
|
|
#include "wx/image.h"
|
|
#include "wx/file.h"
|
|
#include "wx/filename.h"
|
|
|
|
#ifdef __WXX11__
|
|
#include "wx/x11/reparent.h"
|
|
#endif
|
|
|
|
#include "emulator.h"
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// resources
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// the application icon (under Windows and OS/2 it is in resources)
|
|
#ifndef wxHAS_IMAGES_IN_RESOURCES
|
|
#include "emulator.xpm"
|
|
#endif
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// event tables and other macros for wxWidgets
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// the event tables connect the wxWidgets events with the functions (event
|
|
// handlers) which process them. It can be also done at run-time, but for the
|
|
// simple menu events like this the static method is much simpler.
|
|
BEGIN_EVENT_TABLE(wxEmulatorFrame, wxFrame)
|
|
EVT_MENU(Emulator_Quit, wxEmulatorFrame::OnQuit)
|
|
EVT_MENU(Emulator_About, wxEmulatorFrame::OnAbout)
|
|
EVT_CLOSE(wxEmulatorFrame::OnCloseWindow)
|
|
END_EVENT_TABLE()
|
|
|
|
// Create a new application object: this macro will allow wxWidgets to create
|
|
// the application object during program execution (it's better than using a
|
|
// static object for many reasons) and also declares the accessor function
|
|
// wxGetApp() which will return the reference of the right type (i.e. wxEmulatorApp and
|
|
// not wxApp)
|
|
IMPLEMENT_APP(wxEmulatorApp)
|
|
|
|
static const wxCmdLineEntryDesc sg_cmdLineDesc[] =
|
|
{
|
|
{ wxCMD_LINE_OPTION, "u", "use-display", "display number to use (default 100)" },
|
|
|
|
{ wxCMD_LINE_SWITCH, "h", "help", "displays help on the command line parameters" },
|
|
{ wxCMD_LINE_SWITCH, "v", "version", "print version" },
|
|
|
|
{ wxCMD_LINE_PARAM, NULL, NULL, "config file 1", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
|
|
|
|
wxCMD_LINE_DESC_END
|
|
};
|
|
|
|
|
|
// ============================================================================
|
|
// implementation
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// the application class
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxEmulatorApp::wxEmulatorApp()
|
|
{
|
|
m_xnestWindow = NULL;
|
|
m_containerWindow = NULL;
|
|
m_displayNumber = wxT("100");
|
|
m_xnestPID = 0;
|
|
|
|
}
|
|
|
|
// 'Main program' equivalent: the program execution "starts" here
|
|
bool wxEmulatorApp::OnInit()
|
|
{
|
|
#if wxUSE_LOG
|
|
wxLog::DisableTimestamp();
|
|
#endif // wxUSE_LOG
|
|
wxInitAllImageHandlers();
|
|
|
|
wxString currentDir = wxGetCwd();
|
|
|
|
// Use argv to get current app directory
|
|
m_appDir = wxFindAppPath(argv[0], currentDir, wxT("WXEMUDIR"));
|
|
|
|
// If the development version, go up a directory.
|
|
#ifdef __WXMSW__
|
|
if ((m_appDir.Right(5).CmpNoCase(wxT("DEBUG")) == 0) ||
|
|
(m_appDir.Right(11).CmpNoCase(wxT("DEBUGSTABLE")) == 0) ||
|
|
(m_appDir.Right(7).CmpNoCase(wxT("RELEASE")) == 0) ||
|
|
(m_appDir.Right(13).CmpNoCase(wxT("RELEASESTABLE")) == 0)
|
|
)
|
|
m_appDir = wxPathOnly(m_appDir);
|
|
#endif
|
|
|
|
// Parse the command-line parameters and options
|
|
wxCmdLineParser parser(sg_cmdLineDesc, argc, argv);
|
|
int res;
|
|
{
|
|
wxLogNull log;
|
|
res = parser.Parse();
|
|
}
|
|
if (res == -1 || res > 0 || parser.Found(wxT("h")))
|
|
{
|
|
#ifdef __X__
|
|
wxLog::SetActiveTarget(new wxLogStderr);
|
|
#endif
|
|
parser.Usage();
|
|
return false;
|
|
}
|
|
if (parser.Found(wxT("v")))
|
|
{
|
|
#ifdef __X__
|
|
wxLog::SetActiveTarget(new wxLogStderr);
|
|
#endif
|
|
wxString msg;
|
|
msg.Printf(wxT("wxWidgets PDA Emulator (c) Julian Smart, 2002 Version %.2f, %s"), wxEMULATOR_VERSION, __DATE__);
|
|
wxLogMessage(msg);
|
|
return false;
|
|
}
|
|
if (parser.Found(wxT("u"), & m_displayNumber))
|
|
{
|
|
// Should only be number, so strip out anything before
|
|
// and including a : character
|
|
if (m_displayNumber.Find(wxT(':')) != -1)
|
|
{
|
|
m_displayNumber = m_displayNumber.AfterFirst(wxT(':'));
|
|
}
|
|
}
|
|
if (parser.GetParamCount() == 0)
|
|
{
|
|
m_emulatorInfo.m_emulatorFilename = wxT("default.wxe");
|
|
}
|
|
else if (parser.GetParamCount() > 0)
|
|
{
|
|
m_emulatorInfo.m_emulatorFilename = parser.GetParam(0);
|
|
}
|
|
|
|
// Load the emulation info
|
|
if (!LoadEmulator(m_appDir))
|
|
{
|
|
//wxMessageBox(wxT("Sorry, could not load this emulator. Please check bitmaps are valid."));
|
|
return false;
|
|
}
|
|
|
|
// create the main application window
|
|
wxEmulatorFrame *frame = new wxEmulatorFrame(wxT("wxEmulator"),
|
|
wxPoint(50, 50), wxSize(450, 340));
|
|
|
|
#if wxUSE_STATUSBAR
|
|
frame->SetStatusText(m_emulatorInfo.m_emulatorTitle, 0);
|
|
|
|
wxString sizeStr;
|
|
sizeStr.Printf(wxT("Screen: %dx%d"), (int) m_emulatorInfo.m_emulatorScreenSize.x,
|
|
(int) m_emulatorInfo.m_emulatorScreenSize.y);
|
|
frame->SetStatusText(sizeStr, 1);
|
|
#endif // wxUSE_STATUSBAR
|
|
|
|
m_containerWindow = new wxEmulatorContainer(frame, wxID_ANY);
|
|
|
|
frame->SetClientSize(m_emulatorInfo.m_emulatorDeviceSize.x,
|
|
m_emulatorInfo.m_emulatorDeviceSize.y);
|
|
|
|
// and show it (the frames, unlike simple controls, are not shown when
|
|
// created initially)
|
|
frame->Show(true);
|
|
|
|
#ifdef __WXX11__
|
|
m_xnestWindow = new wxAdoptedWindow;
|
|
|
|
wxString cmd;
|
|
cmd.Printf(wxT("Xnest :%s -geometry %dx%d"),
|
|
m_displayNumber.c_str(),
|
|
(int) m_emulatorInfo.m_emulatorScreenSize.x,
|
|
(int) m_emulatorInfo.m_emulatorScreenSize.y);
|
|
|
|
// Asynchronously executes Xnest
|
|
m_xnestPID = wxExecute(cmd);
|
|
if (0 == m_xnestPID)
|
|
{
|
|
frame->Destroy();
|
|
wxMessageBox(wxT("Sorry, could not run Xnest. Please check your PATH."));
|
|
return false;
|
|
}
|
|
|
|
wxReparenter reparenter;
|
|
if (!reparenter.WaitAndReparent(m_containerWindow, m_xnestWindow, wxT("Xnest")))
|
|
{
|
|
wxMessageBox(wxT("Sorry, could not reparent Xnest.."));
|
|
frame->Destroy();
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
m_containerWindow->DoResize();
|
|
|
|
// success: wxApp::OnRun() will be called which will enter the main message
|
|
// loop and the application will run. If we returned false here, the
|
|
// application would exit immediately.
|
|
return true;
|
|
}
|
|
|
|
// Prepend the current program directory to the name
|
|
wxString wxEmulatorApp::GetFullAppPath(const wxString& filename) const
|
|
{
|
|
wxString path(m_appDir);
|
|
if (path.Last() != '\\' && path.Last() != '/' && filename[0] != '\\' && filename[0] != '/')
|
|
#ifdef __X__
|
|
path += '/';
|
|
#else
|
|
path += '\\';
|
|
#endif
|
|
path += filename;
|
|
|
|
return path;
|
|
}
|
|
|
|
|
|
// Load the specified emulator.
|
|
// For now, hard-wired. TODO: make this configurable
|
|
bool wxEmulatorApp::LoadEmulator(const wxString& appDir)
|
|
{
|
|
// Load config file and bitmaps
|
|
return m_emulatorInfo.Load(appDir);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// main frame
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// frame constructor
|
|
wxEmulatorFrame::wxEmulatorFrame(const wxString& title,
|
|
const wxPoint& pos, const wxSize& size)
|
|
: wxFrame(NULL, wxID_ANY, title, pos, size)
|
|
{
|
|
// set the frame icon
|
|
SetIcon(wxICON(emulator));
|
|
|
|
#if wxUSE_MENUS
|
|
// create a menu bar
|
|
wxMenu *menuFile = new wxMenu;
|
|
|
|
// the "About" item should be in the help menu
|
|
wxMenu *helpMenu = new wxMenu;
|
|
helpMenu->Append(Emulator_About, wxT("&About\tF1"), wxT("Show about dialog"));
|
|
|
|
menuFile->Append(Emulator_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
|
|
|
|
// now append the freshly created menu to the menu bar...
|
|
wxMenuBar *menuBar = new wxMenuBar();
|
|
menuBar->Append(menuFile, wxT("&File"));
|
|
menuBar->Append(helpMenu, wxT("&Help"));
|
|
|
|
// ... and attach this menu bar to the frame
|
|
SetMenuBar(menuBar);
|
|
#endif // wxUSE_MENUS
|
|
|
|
#if wxUSE_STATUSBAR
|
|
// create a status bar just for fun (by default with 1 pane only)
|
|
CreateStatusBar(2);
|
|
#endif // wxUSE_STATUSBAR
|
|
}
|
|
|
|
|
|
// event handlers
|
|
|
|
void wxEmulatorFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
// true is to force the frame to close
|
|
Close(true);
|
|
}
|
|
|
|
void wxEmulatorFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxString msg;
|
|
msg.Printf( wxT("wxEmulator is an environment for testing embedded X11 apps.\n"));
|
|
|
|
wxMessageBox(msg, wxT("About wxEmulator"), wxOK | wxICON_INFORMATION, this);
|
|
}
|
|
|
|
void wxEmulatorFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
|
|
{
|
|
#ifdef __WXX11__
|
|
if (wxGetApp().m_xnestWindow)
|
|
{
|
|
wxGetApp().m_xnestWindow->SetHandle((WXWindow) NULL);
|
|
}
|
|
#endif
|
|
this->Destroy();
|
|
if (wxGetApp().m_xnestPID > 0)
|
|
{
|
|
wxKill(wxGetApp().m_xnestPID);
|
|
wxGetApp().m_xnestPID = 0;
|
|
}
|
|
}
|
|
|
|
IMPLEMENT_CLASS(wxEmulatorContainer, wxWindow)
|
|
|
|
BEGIN_EVENT_TABLE(wxEmulatorContainer, wxWindow)
|
|
EVT_SIZE(wxEmulatorContainer::OnSize)
|
|
EVT_PAINT(wxEmulatorContainer::OnPaint)
|
|
EVT_ERASE_BACKGROUND(wxEmulatorContainer::OnEraseBackground)
|
|
END_EVENT_TABLE()
|
|
|
|
wxEmulatorContainer::wxEmulatorContainer(wxWindow* parent, wxWindowID id):
|
|
wxWindow(parent, id, wxDefaultPosition, wxDefaultSize)
|
|
{
|
|
}
|
|
|
|
void wxEmulatorContainer::OnSize(wxSizeEvent& WXUNUSED(event))
|
|
{
|
|
DoResize();
|
|
}
|
|
|
|
void wxEmulatorContainer::DoResize()
|
|
{
|
|
wxSize sz = GetClientSize();
|
|
if (wxGetApp().m_xnestWindow
|
|
#ifdef __WXX11__
|
|
&& wxGetApp().m_xnestWindow->X11GetMainWindow()
|
|
#endif
|
|
)
|
|
{
|
|
int deviceWidth = wxGetApp().m_emulatorInfo.m_emulatorDeviceSize.x;
|
|
int deviceHeight = wxGetApp().m_emulatorInfo.m_emulatorDeviceSize.y;
|
|
|
|
int x = wxMax(0, (int) ((sz.x - deviceWidth)/2.0));
|
|
int y = wxMax(0, (int) ((sz.y - deviceHeight)/2.0));
|
|
|
|
x += wxGetApp().m_emulatorInfo.m_emulatorScreenPosition.x;
|
|
y += wxGetApp().m_emulatorInfo.m_emulatorScreenPosition.y;
|
|
|
|
wxGetApp().m_xnestWindow->Move(x, y);
|
|
}
|
|
Refresh();
|
|
}
|
|
|
|
void wxEmulatorContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
|
|
{
|
|
wxPaintDC dc(this);
|
|
|
|
wxSize sz = GetClientSize();
|
|
if (wxGetApp().m_emulatorInfo.m_emulatorBackgroundBitmap.IsOk())
|
|
{
|
|
int deviceWidth = wxGetApp().m_emulatorInfo.m_emulatorDeviceSize.x;
|
|
int deviceHeight = wxGetApp().m_emulatorInfo.m_emulatorDeviceSize.y;
|
|
|
|
int x = wxMax(0, (int) ((sz.x - deviceWidth)/2.0));
|
|
int y = wxMax(0, (int) ((sz.y - deviceHeight)/2.0));
|
|
|
|
dc.DrawBitmap(wxGetApp().m_emulatorInfo.m_emulatorBackgroundBitmap, x, y);
|
|
}
|
|
}
|
|
|
|
void wxEmulatorContainer::OnEraseBackground(wxEraseEvent& event)
|
|
{
|
|
wxDC* dc wxDUMMY_INITIALIZE(NULL);
|
|
|
|
if (event.GetDC())
|
|
{
|
|
dc = event.GetDC();
|
|
}
|
|
else
|
|
{
|
|
dc = new wxClientDC(this);
|
|
}
|
|
|
|
dc->SetBackground(wxBrush(wxGetApp().m_emulatorInfo.m_emulatorBackgroundColour, wxSOLID));
|
|
dc->Clear();
|
|
|
|
if (!event.GetDC())
|
|
delete dc;
|
|
}
|
|
|
|
// Information about the emulator decorations
|
|
|
|
void wxEmulatorInfo::Copy(const wxEmulatorInfo& info)
|
|
{
|
|
m_emulatorFilename = info.m_emulatorFilename;
|
|
m_emulatorTitle = info.m_emulatorTitle;
|
|
m_emulatorDescription = info.m_emulatorDescription;
|
|
m_emulatorScreenPosition = info.m_emulatorScreenPosition;
|
|
m_emulatorScreenSize = info.m_emulatorScreenSize;
|
|
m_emulatorBackgroundBitmap = info.m_emulatorBackgroundBitmap;
|
|
m_emulatorBackgroundBitmapName = info.m_emulatorBackgroundBitmapName;
|
|
m_emulatorBackgroundColour = info.m_emulatorBackgroundColour;
|
|
m_emulatorDeviceSize = info.m_emulatorDeviceSize;
|
|
}
|
|
|
|
// Initialisation
|
|
void wxEmulatorInfo::Init()
|
|
{
|
|
m_emulatorDeviceSize = wxSize(260, 340);
|
|
m_emulatorScreenSize = wxSize(240, 320);
|
|
}
|
|
|
|
// Loads bitmaps
|
|
bool wxEmulatorInfo::Load(const wxString& appDir)
|
|
{
|
|
// Try to find absolute path
|
|
wxString absoluteConfigPath = m_emulatorFilename;
|
|
if ( !::wxIsAbsolutePath(absoluteConfigPath) )
|
|
{
|
|
wxString currDir = wxGetCwd();
|
|
absoluteConfigPath = currDir + wxString(wxFILE_SEP_PATH) + m_emulatorFilename;
|
|
if ( !wxFile::Exists(absoluteConfigPath) )
|
|
{
|
|
absoluteConfigPath = appDir + wxString(wxFILE_SEP_PATH)
|
|
+ m_emulatorFilename;
|
|
}
|
|
}
|
|
|
|
if ( !wxFile::Exists(absoluteConfigPath) )
|
|
{
|
|
wxString str;
|
|
str.Printf( wxT("Could not find config file %s"),
|
|
absoluteConfigPath.c_str() );
|
|
|
|
wxMessageBox(str);
|
|
return false;
|
|
}
|
|
|
|
wxString rootPath = wxPathOnly(absoluteConfigPath);
|
|
|
|
{
|
|
wxFileConfig config(wxT("wxEmulator"), wxT("wxWidgets"),
|
|
absoluteConfigPath, wxEmptyString, wxCONFIG_USE_LOCAL_FILE);
|
|
|
|
config.Read(wxT("/General/title"), & m_emulatorTitle);
|
|
config.Read(wxT("/General/description"), & m_emulatorDescription);
|
|
config.Read(wxT("/General/backgroundBitmap"), & m_emulatorBackgroundBitmapName);
|
|
|
|
wxString colString;
|
|
if (config.Read(wxT("/General/backgroundColour"), & colString) ||
|
|
config.Read(wxT("/General/backgroundColor"), & colString)
|
|
)
|
|
{
|
|
m_emulatorBackgroundColour = wxHexStringToColour(colString);
|
|
}
|
|
|
|
int x = 0, y = 0, w = 0, h = 0, dw = 0, dh = 0;
|
|
config.Read(wxT("/General/screenX"), & x);
|
|
config.Read(wxT("/General/screenY"), & y);
|
|
config.Read(wxT("/General/screenWidth"), & w);
|
|
config.Read(wxT("/General/screenHeight"), & h);
|
|
if (config.Read(wxT("/General/deviceWidth"), & dw) && config.Read(wxT("/General/deviceHeight"), & dh))
|
|
{
|
|
m_emulatorDeviceSize = wxSize(dw, dh);
|
|
}
|
|
|
|
m_emulatorScreenPosition = wxPoint(x, y);
|
|
m_emulatorScreenSize = wxSize(w, h);
|
|
}
|
|
|
|
if (!m_emulatorBackgroundBitmapName.empty())
|
|
{
|
|
wxString absoluteBackgroundBitmapName = rootPath + wxString(wxFILE_SEP_PATH) + m_emulatorBackgroundBitmapName;
|
|
if ( !wxFile::Exists(absoluteBackgroundBitmapName) )
|
|
{
|
|
wxString str;
|
|
str.Printf( wxT("Could not find bitmap %s"),
|
|
absoluteBackgroundBitmapName.c_str() );
|
|
wxMessageBox(str);
|
|
return false;
|
|
}
|
|
|
|
wxBitmapType type = wxDetermineImageType(m_emulatorBackgroundBitmapName);
|
|
if (type == wxBITMAP_TYPE_INVALID)
|
|
return false;
|
|
|
|
if (!m_emulatorBackgroundBitmap.LoadFile(m_emulatorBackgroundBitmapName, type))
|
|
{
|
|
wxString str;
|
|
str.Printf( wxT("Could not load bitmap file %s"),
|
|
m_emulatorBackgroundBitmapName.c_str() );
|
|
wxMessageBox(str);
|
|
return false;
|
|
}
|
|
|
|
m_emulatorDeviceSize = wxSize(m_emulatorBackgroundBitmap.GetWidth(),
|
|
m_emulatorBackgroundBitmap.GetHeight());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Returns the image type, or -1, determined from the extension.
|
|
wxBitmapType wxDetermineImageType(const wxString& filename)
|
|
{
|
|
wxString path, name, ext;
|
|
|
|
wxFileName::SplitPath(filename, & path, & name, & ext);
|
|
|
|
ext.MakeLower();
|
|
if (ext == wxT("jpg") || ext == wxT("jpeg"))
|
|
return wxBITMAP_TYPE_JPEG;
|
|
if (ext == wxT("gif"))
|
|
return wxBITMAP_TYPE_GIF;
|
|
if (ext == wxT("bmp"))
|
|
return wxBITMAP_TYPE_BMP;
|
|
if (ext == wxT("png"))
|
|
return wxBITMAP_TYPE_PNG;
|
|
if (ext == wxT("pcx"))
|
|
return wxBITMAP_TYPE_PCX;
|
|
if (ext == wxT("tif") || ext == wxT("tiff"))
|
|
return wxBITMAP_TYPE_TIFF;
|
|
|
|
return wxBITMAP_TYPE_INVALID;
|
|
}
|
|
|
|
// Convert a colour to a 6-digit hex string
|
|
wxString wxColourToHexString(const wxColour& col)
|
|
{
|
|
wxString hex;
|
|
|
|
hex += wxDecToHex(col.Red());
|
|
hex += wxDecToHex(col.Green());
|
|
hex += wxDecToHex(col.Blue());
|
|
|
|
return hex;
|
|
}
|
|
|
|
// Convert 6-digit hex string to a colour
|
|
wxColour wxHexStringToColour(const wxString& hex)
|
|
{
|
|
unsigned char r = (unsigned char)wxHexToDec(hex.Mid(0, 2));
|
|
unsigned char g = (unsigned char)wxHexToDec(hex.Mid(2, 2));
|
|
unsigned char b = (unsigned char)wxHexToDec(hex.Mid(4, 2));
|
|
|
|
return wxColour(r, g, b);
|
|
}
|
|
|
|
// Find the absolute path where this application has been run from.
|
|
// argv0 is wxTheApp->argv[0]
|
|
// cwd is the current working directory (at startup)
|
|
// appVariableName is the name of a variable containing the directory for this app, e.g.
|
|
// MYAPPDIR. This is checked first.
|
|
|
|
wxString wxFindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName)
|
|
{
|
|
wxString str;
|
|
|
|
// Try appVariableName
|
|
if (!appVariableName.empty())
|
|
{
|
|
str = wxGetenv(appVariableName);
|
|
if (!str.empty())
|
|
return str;
|
|
}
|
|
|
|
if (wxIsAbsolutePath(argv0))
|
|
return wxPathOnly(argv0);
|
|
else
|
|
{
|
|
// Is it a relative path?
|
|
wxString currentDir(cwd);
|
|
if (!wxEndsWithPathSeparator(currentDir))
|
|
currentDir += wxFILE_SEP_PATH;
|
|
|
|
str = currentDir + argv0;
|
|
if ( wxFile::Exists(str) )
|
|
return wxPathOnly(str);
|
|
}
|
|
|
|
// OK, it's neither an absolute path nor a relative path.
|
|
// Search PATH.
|
|
|
|
wxPathList pathList;
|
|
pathList.AddEnvList(wxT("PATH"));
|
|
str = pathList.FindAbsoluteValidPath(argv0);
|
|
if (!str.empty())
|
|
return wxPathOnly(str);
|
|
|
|
// Failed
|
|
return wxEmptyString;
|
|
}
|
|
|