3#include <wx/filename.h>
4#include <wx/platinfo.h>
8#include "base_platform.h"
9#include "ocpn_plugin.h"
10#include "plugin_paths.h"
19const char*
const LINUX_DATA_PATH =
20 "~/.local/share:/usr/local/share:/usr/share";
23extern bool g_bportable;
25static std::vector<std::string> split(
const std::string& s,
char delimiter) {
26 std::vector<std::string> tokens;
28 std::istringstream tokenStream(s);
29 while (std::getline(tokenStream, token, delimiter)) {
30 tokens.push_back(token);
35static std::string expand(
const std::string& s) {
38 return fn.GetFullPath().ToStdString();
49void PluginPaths::initWindowsPaths() {
54 g_BasePlatform->GetPrivateDataDir().ToStdString() +
"\\plugins";
55 m_libdirs.push_back(m_userLibdir);
57 g_BasePlatform->GetPrivateDataDir().ToStdString() +
"\\plugins";
58 m_bindirs = m_libdirs;
60 g_BasePlatform->GetPrivateDataDir().ToStdString() +
"\\plugins";
61 m_datadirs.push_back(m_userDatadir);
65 const string platform_dir = g_BasePlatform->
GetPluginDir().ToStdString();
66 const string winPluginBaseDir =
68 m_userLibdir = winPluginBaseDir;
69 m_userBindir = winPluginBaseDir;
70 m_userDatadir = winPluginBaseDir;
72 m_libdirs.push_back(m_userLibdir);
73 m_libdirs.push_back(g_BasePlatform->
GetPluginDir().ToStdString());
74 m_bindirs = m_libdirs;
76 m_datadirs.push_back(platform_dir +
"\\plugins");
77 m_datadirs.push_back(winPluginBaseDir);
80void PluginPaths::initFlatpackPaths() {
83 const string flathome = m_home +
"/.var/app/org.opencpn.OpenCPN";
84 m_userLibdir = flathome +
"/lib";
85 m_userBindir = flathome +
"/bin";
86 m_userDatadir = flathome +
"/data";
88 m_libdirs.push_back(flathome +
"/lib");
89 m_libdirs.push_back(
"/app/extensions/lib/opencpn");
90 m_libdirs.push_back(
"/app/lib/opencpn");
92 m_bindirs.push_back(flathome +
"/bin");
93 m_bindirs.push_back(
"/app/extensions/bin");
94 m_bindirs.push_back(
"/app/bin");
96 m_datadirs.push_back(flathome +
"/data/plugins");
97 m_datadirs.push_back(
"/app/extensions/share/opencpn/plugins");
98 m_datadirs.push_back(
"/app/share/opencpn/plugins");
101void PluginPaths::initLinuxPaths() {
105 m_userLibdir = g_BasePlatform->GetPrivateDataDir().ToStdString() +
107 m_libdirs.push_back(m_userLibdir);
108 m_userBindir = g_BasePlatform->GetPrivateDataDir().ToStdString() +
110 m_bindirs = m_libdirs;
111 m_userDatadir = g_BasePlatform->GetPrivateDataDir().ToStdString() +
113 m_datadirs.push_back(m_userDatadir);
117 m_userLibdir = m_home +
"/.local/lib";
118 m_userBindir = m_home +
"/.local/bin";
119 m_userDatadir = m_home +
"/.local/share";
121 const string platform_dir = g_BasePlatform->
GetPluginDir().ToStdString();
122 const char*
const envdirs = getenv(
"OPENCPN_PLUGIN_DIRS");
123 string dirlist = envdirs ? envdirs : OCPN_LINUX_LOAD_PATH;
124 m_libdirs = split(dirlist,
':');
125 for (
auto& dir : m_libdirs) {
129 if (envdirs == 0 && dirlist.find(platform_dir) == string::npos) {
130 m_libdirs.push_back(expand(platform_dir));
132 m_bindirs = m_libdirs;
133 for (
auto& dir : m_bindirs) {
136 size_t pos = dir.rfind(
"/lib/opencpn");
137 if (pos == string::npos) {
138 pos = dir.rfind(
"/lib64/opencpn");
140 dir = pos == string::npos ? dir : dir.substr(0, pos) +
"/bin";
142 const char*
const xdg_data_dirs = getenv(
"XDG_DATA_DIRS");
143 dirlist = xdg_data_dirs ? xdg_data_dirs : LINUX_DATA_PATH;
144 m_datadirs = split(dirlist,
':');
145 for (
auto& dir : m_datadirs) {
146 dir +=
"/opencpn/plugins";
148 if (xdg_data_dirs == 0 && dirlist.find(platform_dir) == string::npos) {
149 m_datadirs.push_back(platform_dir +
"/plugins");
153void PluginPaths::initApplePaths() {
156 const string mac_home = m_home +
"/Library/Application Support/OpenCPN";
157 m_userLibdir = mac_home +
"/Contents/PlugIns";
158 m_userBindir = m_userLibdir;
159 m_userDatadir = mac_home +
"/Contents";
161 m_libdirs.push_back(m_userLibdir);
162 wxFileName fn_exe(g_BasePlatform->GetExePath());
163 fn_exe.RemoveLastDir();
165 fn_exe.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR).ToStdString() +
167 m_libdirs.push_back(exeLibDir);
169 m_bindirs = m_libdirs;
171 m_datadirs.push_back(m_userDatadir);
172 m_datadirs.push_back(
"/Applications/OpenCPN.app/Contents/PlugIns");
175void PluginPaths::initAndroidPaths() {
178 const string platform_dir = g_BasePlatform->
GetPluginDir().ToStdString();
181 platform_dir +
"/manPlug";
183 platform_dir +
"/manPlug";
185 g_BasePlatform->GetPrivateDataDir()
189 m_libdirs.push_back(m_userLibdir);
190 m_libdirs.push_back(expand(platform_dir));
192 m_bindirs = m_libdirs;
195PluginPaths::PluginPaths() {
198 wxString wxHome(
"unusable-$HOME");
199 wxGetEnv(
"HOME", &wxHome);
200 m_home = wxHome.ToStdString();
202 auto osSystemId = wxPlatformInfo::Get().GetOperatingSystemId();
203 if (osSystemId & wxOS_WINDOWS) {
205 }
else if (g_BasePlatform->isFlatpacked()) {
207 }
else if (osSystemId & wxOS_UNIX_LINUX) {
208#ifdef __OCPN__ANDROID__
213 }
else if (osSystemId & wxOS_MAC) {
216 wxString os_name = wxPlatformInfo::Get().GetPortIdName();
217 wxLogMessage(_T(
"OS_NAME: ") + os_name);
218 if (os_name.Contains(_T(
"wxQT"))) {
221 wxLogWarning(
"PluginPaths: Unknown platform");
static PluginPaths * getInstance()
Return the singleton instance.