32#include <wx/filename.h>
33#include <wx/platinfo.h>
44static std::vector<std::string>
split(
const std::string& s,
char delimiter) {
45 std::vector<std::string> tokens;
47 std::istringstream tokenStream(s);
48 while (std::getline(tokenStream, token, delimiter)) {
49 tokens.push_back(token);
54static std::string expand(
const std::string& s) {
57 return fn.GetFullPath().ToStdString();
68void PluginPaths::InitWindowsPaths() {
74 m_libdirs.push_back(m_userLibdir);
77 m_bindirs = m_libdirs;
80 m_datadirs.push_back(m_user_datadir);
85 const string winPluginBaseDir =
87 m_userLibdir = winPluginBaseDir;
88 m_user_bindir = winPluginBaseDir;
89 m_user_datadir = winPluginBaseDir;
91 m_libdirs.push_back(m_userLibdir);
93 m_bindirs = m_libdirs;
95 m_datadirs.push_back(platform_dir +
"\\plugins");
96 m_datadirs.push_back(winPluginBaseDir);
99void PluginPaths::InitFlatpakPaths() {
102 const string flathome = m_home +
"/.var/app/org.opencpn.OpenCPN";
103 m_userLibdir = flathome +
"/lib";
104 m_user_bindir = flathome +
"/bin";
105 m_user_datadir = flathome +
"/data";
107 m_libdirs.push_back(flathome +
"/lib");
108 m_libdirs.push_back(
"/app/extensions/lib/opencpn");
109 m_libdirs.push_back(
"/app/lib/opencpn");
111 m_bindirs.push_back(flathome +
"/bin");
112 m_bindirs.push_back(
"/app/extensions/bin");
113 m_bindirs.push_back(
"/app/bin");
115 m_datadirs.push_back(flathome +
"/data/plugins");
116 m_datadirs.push_back(
"/app/extensions/share/opencpn/plugins");
117 m_datadirs.push_back(
"/app/share/opencpn/plugins");
120void PluginPaths::InitLinuxPaths() {
126 m_libdirs.push_back(m_userLibdir);
129 m_bindirs = m_libdirs;
132 m_datadirs.push_back(m_user_datadir);
136 m_userLibdir = m_home +
"/.local/lib";
137 m_user_bindir = m_home +
"/.local/bin";
138 m_user_datadir = m_home +
"/.local/share";
140 std::vector<std::string> base_plugin_paths;
141#if defined(__WXGTK__) || defined(__WXQT__)
142 char exe_buf[100] = {0};
143 ssize_t len = readlink(
"/proc/self/exe", exe_buf, 99);
146 wxFileName fn(exe_buf);
147 std::string path = fn.GetPath().ToStdString();
148 base_plugin_paths.push_back(expand(path +
"/../lib/opencpn"));
149 if (
g_BasePlatform->GetOSDetail()->osd_arch.find(
"64") != string::npos) {
150 base_plugin_paths.push_back(expand(path +
"/../lib64/opencpn"));
152 base_plugin_paths.push_back(expand(path +
"/../lib32/opencpn"));
157 const char*
const envdirs = getenv(
"OPENCPN_PLUGIN_DIRS");
158 string dirlist = envdirs ? envdirs :
"~/.local/lib/opencpn";
159 m_libdirs =
split(dirlist,
':');
160 for (
auto& dir : m_libdirs) {
163 for (
auto& base_plugin_path : base_plugin_paths) {
164 if (envdirs == 0 && dirlist.find(base_plugin_path) == string::npos) {
166 m_libdirs.push_back(base_plugin_path);
170 m_bindirs = m_libdirs;
171 for (
auto& dir : m_bindirs) {
174 size_t pos = dir.rfind(
"/lib/opencpn");
175 if (pos == string::npos) {
176 pos = dir.rfind(
"/lib64/opencpn");
178 dir = pos == string::npos ? dir : dir.substr(0, pos) +
"/bin";
180 const char*
const xdg_data_dirs = getenv(
"XDG_DATA_DIRS");
181 dirlist = xdg_data_dirs ? xdg_data_dirs :
"~/.local/lib";
182 m_datadirs =
split(dirlist,
':');
183 for (
auto& dir : m_datadirs) {
184 dir +=
"/opencpn/plugins";
186 for (
auto& base_plugin_path : base_plugin_paths) {
187 if (xdg_data_dirs == 0 && dirlist.find(base_plugin_path) == string::npos) {
188 m_datadirs.push_back(base_plugin_path +
"/plugins");
193void PluginPaths::InitApplePaths() {
196 const string mac_home = m_home +
"/Library/Application Support/OpenCPN";
197 m_userLibdir = mac_home +
"/Contents/PlugIns";
198 m_user_bindir = m_userLibdir;
199 m_user_datadir = mac_home +
"/Contents";
201 m_libdirs.push_back(m_userLibdir);
203 fn_exe.RemoveLastDir();
205 fn_exe.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR).ToStdString() +
207 m_libdirs.push_back(exeLibDir);
209 m_bindirs = m_libdirs;
211 m_datadirs.push_back(m_user_datadir);
212 m_datadirs.push_back(
"/Applications/OpenCPN.app/Contents/PlugIns");
215void PluginPaths::InitAndroidPaths() {
221 platform_dir +
"/manPlug";
223 platform_dir +
"/manPlug";
229 m_libdirs.push_back(m_userLibdir);
230 m_libdirs.push_back(expand(platform_dir));
232 m_bindirs = m_libdirs;
235PluginPaths::PluginPaths() {
238 wxString wxHome(
"unusable-$HOME");
239 wxGetEnv(
"HOME", &wxHome);
240 m_home = wxHome.ToStdString();
242 auto osSystemId = wxPlatformInfo::Get().GetOperatingSystemId();
243 if (osSystemId & wxOS_WINDOWS) {
247 }
else if (osSystemId & wxOS_UNIX_LINUX) {
253 }
else if (osSystemId & wxOS_MAC) {
256 wxString os_name = wxPlatformInfo::Get().GetPortIdName();
257 wxLogMessage(
"OS_NAME: " + os_name);
258 if (os_name.Contains(
"wxQT")) {
261 wxLogWarning(
"PluginPaths: Unknown platform");
Accessors for various paths to install plugins and their data.
static PluginPaths * GetInstance()
Return the singleton instance.
Global variables reflecting command line options and arguments.
std::vector< std::string > split(const char *token_string, const std::string &delimiter)
Return vector of items in s separated by delimiter.
bool exists(const std::string &name)
PlugIn Object Definition/API.
Miscellaneous utilities, many of which string related.
Plugin installation and data paths support.