63#if (defined(OCPN_GHC_FILESYSTEM) || \
64 (defined(__clang_major__) && (__clang_major__ < 15)))
66#include <ghc/filesystem.hpp>
67namespace fs = ghc::filesystem;
71namespace fs = std::filesystem;
74using namespace std::literals::chrono_literals;
76#include <wx/apptrait.h>
77#include <wx/arrimpl.cpp>
78#include <wx/artprov.h>
79#include <wx/aui/aui.h>
80#include <wx/clrpicker.h>
81#include <wx/cmdline.h>
85#include <wx/display.h>
90#include <wx/jsonreader.h>
91#include <wx/listctrl.h>
93#include <wx/printdlg.h>
95#include <wx/progdlg.h>
96#include <wx/settings.h>
97#include <wx/stdpaths.h>
98#include <wx/tokenzr.h>
100#include "model/ais_decoder.h"
102#include "model/certificates.h"
104#include "model/comm_bridge.h"
105#include "model/comm_n0183_output.h"
106#include "model/comm_vars.h"
107#include "model/config_vars.h"
108#include "model/instance_check.h"
113#include "model/multiplexer.h"
114#include "model/nav_object_database.h"
115#include "model/navutil_base.h"
116#include "model/own_ship.h"
117#include "model/plugin_handler.h"
118#include "model/route.h"
119#include "model/routeman.h"
120#include "model/select.h"
121#include "model/track.h"
123#include "AboutFrameImpl.h"
125#include "ais_info_gui.h"
126#include "AISTargetAlertDialog.h"
127#include "AISTargetListDialog.h"
128#include "AISTargetQueryDialog.h"
129#include "CanvasConfig.h"
135#include "ConfigMgr.h"
136#include "DetailSlider.h"
139#include "gdal/cpl_csv.h"
140#include "glTexCache.h"
141#include "GoToPositionDialog.h"
145#include "observable.h"
147#include "OCPN_AUIManager.h"
148#include "ocpn_frame.h"
149#include "OCPNPlatform.h"
151#include "rest_server_gui.h"
152#include "route_ctx_factory.h"
153#include "routemanagerdialog.h"
154#include "routeman_gui.h"
155#include "RoutePropDlgImpl.h"
158#include "S57QueryDialog.h"
159#include "safe_mode_gui.h"
160#include "SoundFactory.h"
164#include "TrackPropDlg.h"
168#include "glChartCanvas.h"
172#include "model/macutils.h"
176#include "model/garmin_protocol_mgr.h"
177void RedirectIOToConsole();
180#if defined(__WXMSW__) && defined(__MSVC__LEAK)
181#include "Stackwalker.h"
185#include "crashprint.h"
189#include "androidUTIL.h"
195const char *
const kUsage =
198 opencpn [-p] [-f] [-G] [-g] [-P] [-l <str>] [-u <num>] [-U] [-s] [GPX file ...]
199 opencpn --remote [-R] | -q] | -e] |-o <str>]
201Options for starting opencpn
203 -c, --configdir=<dirpath> Use alternative configuration directory.
204 -p, --portable Run in portable mode.
205 -f, --fullscreen Switch to full screen mode on start.
206 -G, --no_opengl Disable OpenGL video acceleration. This setting will
208 -g, --rebuild_gl_raster_cache Rebuild OpenGL raster cache on start.
209 -D, --rebuild_chart_db Rescan chart directories and rebuild the chart database
210 -P, --parse_all_enc Convert all S-57 charts to OpenCPN's internal format on start.
211 -l, --loglevel=<str> Amount of logging: error, warning, message, info, debug or trace
212 -u, --unit_test_1=<num> Display a slideshow of <num> charts and then exit.
213 Zero or negative <num> specifies no limit.
215 -s, --safe_mode Run without plugins, opengl and other "dangerous" stuff
216 -W, --config_wizard Start with initial configuration wizard
218Options manipulating already started opencpn
219 -r, --remote Execute commands on already running instance
220 -R, --raise Make running OpenCPN visible if hidden
221 -q, --quit Terminate already running opencpn
222 -e, --get_rest_endpoint Print rest server endpoint and exit.
223 -o, --open=<GPX file> Open file in running opencpn
226 GPX file GPX-formatted file with waypoints or routes.
230wxDEFINE_EVENT(EVT_N2K_129029, wxCommandEvent);
231wxDEFINE_EVENT(EVT_N2K_129026, wxCommandEvent);
233wxDEFINE_EVENT(EVT_N0183_RMC, wxCommandEvent);
234wxDEFINE_EVENT(EVT_N0183_HDT, wxCommandEvent);
235wxDEFINE_EVENT(EVT_N0183_HDG, wxCommandEvent);
236wxDEFINE_EVENT(EVT_N0183_HDM, wxCommandEvent);
237wxDEFINE_EVENT(EVT_N0183_VTG, wxCommandEvent);
238wxDEFINE_EVENT(EVT_N0183_GSV, wxCommandEvent);
239wxDEFINE_EVENT(EVT_N0183_GGA, wxCommandEvent);
240wxDEFINE_EVENT(EVT_N0183_GLL, wxCommandEvent);
241wxDEFINE_EVENT(EVT_N0183_AIVDO, wxCommandEvent);
251WX_DEFINE_OBJARRAY(ArrayOfCDI);
256bool g_bUpgradeInProcess;
268int g_restore_stackindex;
269int g_restore_dbindex;
270double g_ChartNotRenderScaleFactor;
272LayerList *pLayerList;
284int g_nbrightness = 100;
286bool bDBUpdateInProgress;
291bool g_bshowToolbar =
true;
292bool g_bexpert =
true;
293bool g_bBasicMenus =
false;
295bool bDrawCurrentValues;
297wxString ChartListFileName;
298wxString gWorldMapLocation, gDefaultWorldMapLocation;
299wxString gWorldShapefileLocation;
300wxString *pInit_Chart_Dir;
302wxString g_SENCPrefix;
303wxString g_UserPresLibData;
304wxString g_VisibleLayers;
305wxString g_InvisibleLayers;
306wxString g_VisiNameinLayers;
307wxString g_InVisiNameinLayers;
309bool g_bcompression_wait;
310bool g_FlushNavobjChanges;
311int g_FlushNavobjChangesTimeout;
313wxString g_uploadConnection;
320int g_mem_total, g_mem_initial;
322bool s_bSetSystemTime;
324static unsigned int malloc_max;
326wxDateTime g_start_time;
327wxDateTime g_loglast_time;
328static OcpnSound *_bells_sounds[] = {SoundFactory(), SoundFactory()};
329std::vector<OcpnSound *> bells_sound(_bells_sounds, _bells_sounds + 2);
331OcpnSound *g_anchorwatch_sound = SoundFactory();
333double AnchorPointMinDist;
334bool AnchorAlertOn1, AnchorAlertOn2;
342bool g_bShowDepthUnits;
346bool g_bShowActiveRouteHighway;
349bool g_bPlayShipsBells;
350bool g_bFullscreenToolbar;
352bool g_bTransparentToolbar;
353bool g_bTransparentToolbarInOpenGLOK;
354int g_nAutoHideToolbar;
355bool g_bAutoHideToolbar;
357bool g_bPermanentMOBIcon;
358bool g_bTempShowMenuBar;
360int g_iNavAidRadarRingsNumberVisible;
361bool g_bNavAidRadarRingsShown;
362float g_fNavAidRadarRingsStep;
363int g_pNavAidRadarRingsStepUnits;
364bool g_bWayPointPreventDragging;
365bool g_bConfirmObjectDelete;
366wxColour g_colourOwnshipRangeRingsColour;
370ColorScheme global_color_scheme = GLOBAL_COLOR_SCHEME_DAY;
372wxArrayPtrVoid *UserColourHashTableArray;
373wxColorHashMap *pcurrent_user_color_hash;
382int g_ChartUpdatePeriod;
383int g_SkewCompUpdatePeriod;
385int g_lastClientRectx;
386int g_lastClientRecty;
387int g_lastClientRectw;
388int g_lastClientRecth;
392double g_display_size_mm;
393std::vector<size_t> g_config_display_size_mm;
394bool g_config_display_size_manual;
397int g_ChartScaleFactor;
398float g_MarkScaleFactorExp;
399int g_last_ChartScaleFactor;
400int g_ShipScaleFactor;
401float g_ShipScaleFactorExp;
402int g_ENCSoundingScaleFactor;
403int g_ENCTextScaleFactor;
409s57RegistrarMgr *m_pRegistrarMan;
414#include "model/macutils.h"
423extern bool s_glu_dll_ready;
424extern HINSTANCE s_hGLU_DLL;
430double g_ownship_predictor_minutes;
431double g_ownship_HDTpredictor_miles;
432int g_cog_predictor_style;
433wxString g_cog_predictor_color;
434int g_cog_predictor_endmarker;
435int g_ownship_HDTpredictor_style;
436wxString g_ownship_HDTpredictor_color;
437int g_ownship_HDTpredictor_endmarker;
438int g_ownship_HDTpredictor_width;
440bool g_own_ship_sog_cog_calc;
441int g_own_ship_sog_cog_calc_damp_sec;
446int g_iSoundDeviceIndex;
448int g_S57_dialog_sx, g_S57_dialog_sy;
456bool g_bAutoAnchorMark;
459long gStart_LMT_Offset;
461wxArrayString *pMessageOnceArray;
463bool g_bUseGLL =
true;
494bool g_bsmoothpanzoom;
496bool g_bSmoothRecenter =
true;
498double g_overzoom_emphasis_base;
499bool g_oz_vector_scale;
500double g_plus_minus_zoom_factor;
503bool g_b_legacy_input_filter_behaviour;
510bool g_bFullScreenQuilt =
true;
514ChartGroupArray *g_pGroupArray;
518std::vector<std::string> TideCurrentDataSet;
519wxString g_TCData_Dir;
522bool g_bDeferredInitDone;
523int options_lastPage = 0;
524int options_subpage = 0;
526wxPoint options_lastWindowPos(0, 0);
527wxSize options_lastWindowSize(0, 0);
530bool g_bsimplifiedScalebar;
534bool GetMemoryStatus(
int *mem_total,
int *mem_used);
537int g_nAIS_activity_timer;
539bool g_bEnableZoomToCursor;
542bool g_bDeferredStartTrack;
543bool g_bHighliteTracks;
544wxColour g_colourTrackLineColour;
545wxString g_default_wp_icon;
548double g_TrackIntervalSeconds;
550int g_cm93_zoom_factor;
552bool g_bShowDetailSlider;
553int g_detailslider_dialog_x, g_detailslider_dialog_y;
560bool g_b_overzoom_x =
true;
562int g_OwnShipIconType;
563double g_n_ownship_length_meters;
564double g_n_ownship_beam_meters;
565double g_n_gps_antenna_offset_y;
566double g_n_gps_antenna_offset_x;
567int g_n_ownship_min_mm;
572bool g_bPreserveScaleOnX;
575about *g_pAboutDlgLegacy;
577#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
578wxLocale *plocale_def_lang = 0;
590wxString g_localeOverride;
591bool g_b_assume_azerty;
597bool g_bShowStatusBar;
603int g_AisTargetList_count;
604bool g_bAisTargetList_autosort;
609wxAuiDefaultDockArt *g_pauidockart;
611wxString g_toolbarConfig = _T(
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
616long g_maintoolbar_orient;
617float g_toolbar_scalefactor;
619float g_compass_scalefactor;
621bool g_bShowCompassWin;
623bool g_benable_rotate;
631double gQueryVar = 361.0;
633char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
635int portaudio_initialized;
637char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
640int g_sticky_projection;
642int n_NavMessageShown;
643wxString g_config_version_string;
645wxString g_CmdSoundString;
663bool b_inCompressAllCharts;
667int g_chart_zoom_modifier_raster;
668int g_chart_zoom_modifier_vector;
670bool g_bAdvanceRouteWaypointOnArrivalOnly;
672bool g_bSpaceDropMark;
674wxArrayString g_locale_catalog_array;
675bool b_reloadForPlugins;
676bool g_btrackContinuous;
678unsigned int g_canvasConfig;
680bool g_bmasterToolbarFull =
true;
682int g_AndroidVersionCode;
687WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
689arrayofCanvasPtr g_canvasArray;
690wxString g_lastAppliedTemplateGUID;
696bool g_disable_main_toolbar;
709DEFINE_GUID(GARMIN_DETECT_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81,
710 0x6b, 0xba, 0xe7, 0x22, 0xc0);
714#include <wx/msw/msvcrt.h>
718static const long long lNaN = 0xfff8000000000000;
719#define NAN (*(double *)&lNaN)
723void appendOSDirSlash(wxString *pString);
725void InitializeUserColors(
void);
726void DeInitializeUserColors(
void);
727void SetSystemColors(ColorScheme cs);
729static bool LoadAllPlugIns(
bool load_enabled) {
730 g_Platform->ShowBusySpinner();
731 bool b = PluginLoader::getInstance()->
LoadAllPlugIns(load_enabled);
732 g_Platform->HideBusySpinner();
740#if defined(__WXGTK__) || defined(__WXQT__)
741#include "bitmaps/opencpn.xpm"
744wxString newPrivateFileName(wxString,
const char *name,
745 [[maybe_unused]]
const char *windowsName) {
746 wxString fname = wxString::FromUTF8(name);
747 wxString filePathAndName;
750 if (filePathAndName.Last() != wxFileName::GetPathSeparator())
751 filePathAndName.Append(wxFileName::GetPathSeparator());
754 wxString fwname = wxString::FromUTF8(windowsName);
755 filePathAndName.Append(fwname);
757 filePathAndName.Append(fname);
760 return filePathAndName;
769BEGIN_EVENT_TABLE(
MyApp, wxApp)
770EVT_ACTIVATE_APP(MyApp::OnActivateApp)
773static
void ActivateRoute(const std::
string &guid) {
774 Route *route = g_pRouteMan->FindRouteByGUID(guid);
776 wxLogMessage(
"Cannot activate guid: no such route");
779 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
784 if (wxNOT_FOUND == route->m_RouteNameString.Find(
"MOB")) {
785 point = g_pRouteMan->FindBestActivatePoint(route, gLat, gLon, gCog, gSog);
787 point = route->GetPoint(2);
791 route->m_bRtIsSelected =
false;
794static void ReverseRoute(
const std::string &guid) {
795 Route *route = g_pRouteMan->FindRouteByGUID(guid);
797 wxLogMessage(
"Cannot activate guid: no such route");
804void MyApp::InitRestListeners() {
805 auto activate_route = [&](wxCommandEvent ev) {
806 auto guid = ev.GetString().ToStdString();
810 auto reverse_route = [&](wxCommandEvent ev) {
811 auto guid = ev.GetString().ToStdString();
817bool MyApp::OpenFile(
const std::string &path) {
819 auto result = nav_objects.load_file(path.c_str());
821 std::string s(_(
"Cannot load route or waypoint file: "));
822 s += std::string(
"\"") + path +
"\"";
823 wxMessageBox(s,
"OpenCPN", wxICON_WARNING | wxOK);
829 nav_objects.LoadAllGPXObjects(!nav_objects.IsOpenCPN(), wpt_dups,
true);
831 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
832 pRouteManagerDialog->UpdateLists();
833 LLBBox box = nav_objects.GetBBox();
834 if (box.GetValid()) {
835 gFrame->CenterView(gFrame->GetPrimaryCanvas(), box);
841void MyApp::OnInitCmdLine(wxCmdLineParser &parser) {
844 parser.AddSwitch(
"h",
"help",
"", wxCMD_LINE_OPTION_HELP);
845 parser.AddSwitch(
"p",
"portable");
846 parser.AddOption(
"c",
"configdir",
"", wxCMD_LINE_VAL_STRING,
847 wxCMD_LINE_PARAM_OPTIONAL);
848 parser.AddSwitch(
"f",
"fullscreen");
849 parser.AddSwitch(
"G",
"no_opengl");
850 parser.AddSwitch(
"W",
"config_wizard");
851 parser.AddSwitch(
"g",
"rebuild_gl_raster_cache");
852 parser.AddSwitch(
"D",
"rebuild_chart_db");
853 parser.AddSwitch(
"P",
"parse_all_enc");
854 parser.AddOption(
"l",
"loglevel");
855 parser.AddOption(
"u",
"unit_test_1",
"", wxCMD_LINE_VAL_NUMBER);
856 parser.AddSwitch(
"U",
"unit_test_2");
857 parser.AddParam(
"import GPX files", wxCMD_LINE_VAL_STRING,
858 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
859 parser.AddSwitch(
"s",
"safe_mode");
860 parser.AddSwitch(
"r",
"remote");
861 parser.AddSwitch(
"R",
"raise");
862 parser.AddSwitch(
"q",
"quit");
863 parser.AddSwitch(
"e",
"get_rest_endpoint");
864 parser.AddOption(
"o",
"open",
"", wxCMD_LINE_VAL_STRING,
865 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
871static void ParseLoglevel(wxCmdLineParser &parser) {
872 wxLog::SetLogLevel(wxLOG_Message);
875static void ParseLoglevel(wxCmdLineParser &parser) {
876 const char *strLevel = std::getenv(
"OPENCPN_LOGLEVEL");
877 strLevel = strLevel ? strLevel :
"info";
879 if (parser.Found(
"l", &wxLevel)) {
880 strLevel = wxLevel.c_str();
882 wxLogLevel level = OcpnLog::str2level(strLevel);
883 if (level == OcpnLog::LOG_BADLEVEL) {
884 fprintf(stderr,
"Bad loglevel %s, using \"info\"", strLevel);
887 wxLog::SetLogLevel(level);
892bool MyApp::OnCmdLineHelp(wxCmdLineParser &parser) {
899bool MyApp::OnCmdLineParsed(wxCmdLineParser &parser) {
904 g_unit_test_2 = parser.Found(
"unit_test_2");
905 g_bportable = parser.Found(
"p");
906 g_start_fullscreen = parser.Found(
"fullscreen");
907 g_bdisable_opengl = parser.Found(
"no_opengl");
908 g_rebuild_gl_cache = parser.Found(
"rebuild_gl_raster_cache");
909 g_NeedDBUpdate = parser.Found(
"rebuild_chart_db") ? 2 : 0;
910 g_parse_all_enc = parser.Found(
"parse_all_enc");
911 g_config_wizard = parser.Found(
"config_wizard");
912 if (parser.Found(
"unit_test_1", &number)) {
913 g_unit_test_1 =
static_cast<int>(number);
914 if (g_unit_test_1 == 0) g_unit_test_1 = -1;
916 safe_mode::set_mode(parser.Found(
"safe_mode"));
917 ParseLoglevel(parser);
919 if (parser.Found(
"configdir", &wxstr)) {
920 g_configdir = wxstr.ToStdString();
921 fs::path path(g_configdir);
922 if (!fs::exists(path) || !fs::is_directory(path)) {
923 std::cerr << g_configdir <<
" is not an existing directory.\n";
928 bool has_start_options =
false;
929 static const std::vector<std::string> kStartOptions = {
934 "rebuild_gl_raster_cache",
940 for (
const auto &opt : kStartOptions) {
941 if (parser.Found(opt)) has_start_options =
true;
943 if (has_start_options && parser.Found(
"remote")) {
944 std::cerr <<
"this option is not compatible with --remote\n";
948 bool has_remote_options =
false;
949 static const std::vector<std::string> kRemoteOptions = {
950 "raise",
"quit",
"open",
"get_rest_endpoint"};
951 for (
const auto &opt : kRemoteOptions) {
952 if (parser.Found(opt)) has_remote_options =
true;
954 if (has_remote_options && !parser.Found(
"remote")) {
955 std::cerr <<
"This option requires --remote\n";
959 for (
size_t paramNr = 0; paramNr < parser.GetParamCount(); ++paramNr)
960 g_params.push_back(parser.GetParam(paramNr).ToStdString());
963 if (!parser.Found(
"remote"))
964 m_parsed_cmdline = ParsedCmdline();
965 else if (parser.Found(
"raise"))
966 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Raise);
967 else if (parser.Found(
"quit"))
968 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Quit);
969 else if (parser.Found(
"get_rest_endpoint"))
970 m_parsed_cmdline = ParsedCmdline(CmdlineAction::GetRestEndpoint);
971 else if (parser.Found(
"open", &optarg))
972 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Open, optarg.ToStdString());
973 else if (parser.GetParamCount() == 1)
975 ParsedCmdline(CmdlineAction::Open, parser.GetParam(0).ToStdString());
976 else if (!has_start_options && !has_remote_options) {
978 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Raise);
988bool MyApp::OnExceptionInMainLoop() {
989 wxLogWarning(_T(
"Caught MainLoopException, continuing..."));
994void MyApp::OnActivateApp(wxActivateEvent &event) {
return; }
996static wxStopWatch init_sw;
999 if (m_exitcode != -2)
return m_exitcode;
1000 return wxAppConsole::OnRun();
1011 if (wxGetEnv(
"WAYLAND_DISPLAY", NULL)) {
1012 setenv(
"GDK_BACKEND",
"x11", 1);
1015 "mesa_glthread",
"false",
1021bool MyApp::OnInit() {
1022 if (!wxApp::OnInit())
return false;
1024 androidEnableBackButton(
false);
1025 androidEnableOptionItems(
false);
1030#if defined(__WXGTK__) && defined(ocpnUSE_GLES) && defined(__ARM_ARCH)
1036 wxBitmap bmp(10, 10, -1);
1038 dc.SelectObject(bmp);
1039 dc.DrawText(_T(
"X"), 0, 0);
1044 g_BasePlatform = g_Platform;
1051 if (m_parsed_cmdline.action == CmdlineAction::Skip) {
1055 std::cerr <<
"No remote opencpn found. Giving up.\n";
1060 std::unique_ptr<LocalClientApi> client;
1062 client = LocalClientApi::GetClient();
1064 WARNING_LOG <<
"Ipc client exception: " << ie.str();
1071 wxMessageBox(_(
"Sorry, an existing instance of OpenCPN may be too busy "
1072 "to respond.\nPlease retry."),
1073 "OpenCPN", wxICON_INFORMATION | wxOK);
1078 auto result = client->HandleCmdline(m_parsed_cmdline.action,
1079 m_parsed_cmdline.arg);
1083 wxLogDebug(
"Error running remote command: %s", result.second.c_str());
1092 if (getenv(
"OPENCPN_FATAL_ERROR") != 0) {
1093 wxLogFatalError(getenv(
"OPENCPN_FATAL_ERROR"));
1098 if (!safe_mode::get_mode()) {
1104 OCPNPlatform::Initialize_1();
1109 MyApp::SetAppDisplayName(
"OpenCPN");
1112 wxDateTime x = wxDateTime::UNow();
1113 long seed = x.GetMillisecond();
1114 seed *= x.GetTicks();
1119 setlocale(LC_NUMERIC,
"C");
1121 g_start_time = wxDateTime::Now();
1123 g_loglast_time = g_start_time;
1124 g_loglast_time.MakeGMT();
1125 g_loglast_time.Subtract(
1126 wxTimeSpan(0, 29, 0, 0));
1128 AnchorPointMinDist = 5.0;
1134 GetMemoryStatus(&g_mem_total, &g_mem_initial);
1138 wxFont temp_font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
1139 wxFONTWEIGHT_NORMAL, FALSE, wxString(_T(
"")),
1140 wxFONTENCODING_SYSTEM);
1141 temp_font.SetDefaultEncoding(wxFONTENCODING_SYSTEM);
1144 if (!g_Platform->InitializeLogFile()) {
1156 wxLogMessage(_T(
"\n\n________\n"));
1158 wxDateTime now = wxDateTime::Now();
1159 LOG_INFO(
"------- OpenCPN version %s restarted at %s -------\n", VERSION_FULL,
1160 now.FormatISODate().mb_str().data());
1161 wxLogLevel level = wxLog::GetLogLevel();
1162 LOG_INFO(
"Using loglevel %s", OcpnLog::level2str(level).c_str());
1164 wxString wxver(wxVERSION_STRING);
1165 wxver.Prepend(_T(
"wxWidgets version: "));
1167 wxPlatformInfo platforminfo = wxPlatformInfo::Get();
1171 os_name = platforminfo.GetOperatingSystemIdName();
1173 os_name = platforminfo.GetOperatingSystemFamilyName();
1176 wxString platform = os_name + _T(
" ") + platforminfo.GetArchName() + _T(
" ") +
1177 platforminfo.GetPortIdName();
1179 wxLogMessage(wxver + _T(
" ") + platform);
1181 ::wxGetOsVersion(&osMajor, &osMinor);
1182 wxString osVersionMsg;
1183 osVersionMsg.Printf(_T(
"OS Version reports as: %d.%d"), osMajor, osMinor);
1184 wxLogMessage(osVersionMsg);
1186 wxLogMessage(_T(
"MemoryStatus: mem_total: %d mb, mem_initial: %d mb"),
1187 g_mem_total / 1024, g_mem_initial / 1024);
1192 if (!detail->osd_names_like.empty())
1193 like0 = detail->osd_names_like[0].c_str();
1194 msgplat.Printf(
"OCPN_OSDetail: %s ; %s ; %s ; %s ; %s",
1195 detail->osd_arch.c_str(), detail->osd_name.c_str(),
1196 detail->osd_version.c_str(), detail->osd_ID.c_str(),
1198 wxLogMessage(msgplat);
1200 wxString imsg = _T(
"SData_Locn is ");
1201 imsg += g_Platform->GetSharedDataDir();
1205 ::wxInitAllImageHandlers();
1209 prepareAndroidStyleSheets();
1213 pInit_Chart_Dir =
new wxString();
1216 g_pGroupArray =
new ChartGroupArray;
1218 imsg = _T(
"PrivateDataDir is ");
1224 pMessageOnceArray =
new wxArrayString;
1230 g_pRouteMan =
new Routeman(RoutePropDlg::GetDlgCtx(),
1231 RoutemanGui::GetDlgCtx(), m_data_monitor);
1235 pSelect->SetSelectPixelRadius(12);
1238 pSelectTC =
new Select();
1240 pSelectTC->SetSelectPixelRadius(25);
1243 pSelectAIS =
new Select();
1244 pSelectAIS->SetSelectPixelRadius(12);
1248 g_pais_query_dialog_active = NULL;
1251 g_hostname = ::wxGetHostName();
1252 if (g_hostname.IsEmpty()) g_hostname = wxGetUserName();
1254 androidGetDeviceInfo();
1255 g_hostname = wxString(
"Android-") + g_android_Device_Model;
1256 g_hostname.Replace(
" ",
"-",
true);
1261 wxString p(
"Portable-");
1262 g_hostname = p + g_hostname;
1267 pLayerList =
new LayerList;
1269 pRouteList =
new RouteList;
1276#ifdef PROBE_PORTS__WITH_HELPER
1277 user_user_id = getuid();
1278 file_user_id = geteuid();
1282 bool b_initial_load =
false;
1284 wxFileName config_test_file_name(g_Platform->GetConfigFileName());
1285 if (config_test_file_name.FileExists())
1286 wxLogMessage(_T(
"Using existing Config_File: ") +
1287 g_Platform->GetConfigFileName());
1290 wxLogMessage(_T(
"Creating new Config_File: ") +
1291 g_Platform->GetConfigFileName());
1293 b_initial_load =
true;
1296 config_test_file_name.DirExists(config_test_file_name.GetPath()))
1297 if (!config_test_file_name.Mkdir(config_test_file_name.GetPath()))
1298 wxLogMessage(_T(
"Cannot create config file directory for ") +
1299 g_Platform->GetConfigFileName());
1304 pConfig = g_Platform->GetConfigObject();
1305 InitBaseConfig(pConfig);
1306 pConfig->LoadMyConfig();
1310 if (b_initial_load) g_Platform->SetDefaultOptions();
1312 g_Platform->applyExpertMode(g_bUIexpert);
1320 g_StyleManager->SetStyle(_T(
"MUI_flat"));
1321 if (!g_StyleManager->IsOK()) {
1322 wxString msg = _(
"Failed to initialize the user interface. ");
1323 msg << _(
"OpenCPN cannot start. ");
1324 msg << _(
"The necessary configuration files were not found. ");
1325 msg << _(
"See the log file at ") << g_Platform->GetLogFileName()
1326 << _(
" for details.") << _T(
"\n\n");
1327 msg << g_Platform->GetSharedDataDir();
1329 wxMessageDialog w(NULL, msg, _(
"Failed to initialize the user interface. "),
1330 wxCANCEL | wxICON_ERROR);
1337 if (style) style->chartStatusWindowTransparent =
true;
1341 pWayPointMan = NULL;
1345 msg.Printf(_T(
"Detected display size (horizontal): %d mm"),
1346 (
int)g_display_size_mm);
1350 if (g_config_display_size_manual &&
1351 g_config_display_size_mm.size() > g_current_monitor &&
1352 g_config_display_size_mm[g_current_monitor] > 0) {
1353 g_display_size_mm = g_config_display_size_mm[g_current_monitor];
1355 msg.Printf(_T(
"Display size (horizontal) config override: %d mm"),
1356 (
int)g_display_size_mm);
1361 g_display_size_mm = wxMax(50, g_display_size_mm);
1364 int SelectPixelRadius = 50;
1366 pSelect->SetSelectPixelRadius(SelectPixelRadius);
1367 pSelectTC->SetSelectPixelRadius(wxMax(25, SelectPixelRadius));
1368 pSelectAIS->SetSelectPixelRadius(SelectPixelRadius);
1372 if (!n_NavMessageShown) {
1379#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
1382 g_Platform->SetLocaleSearchPrefixes();
1384 wxString def_lang_canonical = g_Platform->GetDefaultSystemLocale();
1386 imsg = _T(
"System default Language: ") + def_lang_canonical;
1389 wxString cflmsg = _T(
"Config file language: ") + g_locale;
1390 wxLogMessage(cflmsg);
1392 if (g_locale.IsEmpty()) {
1393 g_locale = def_lang_canonical;
1395 _T(
"Config file language empty, using system default: ") + g_locale;
1396 wxLogMessage(cflmsg);
1400 g_locale = g_Platform->GetAdjustedAppLocale();
1401 cflmsg = _T(
"Adjusted App language: ") + g_locale;
1402 wxLogMessage(cflmsg);
1405 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
1407 imsg = _T(
"Opencpn language set to: ");
1414 if (g_locale == _T(
"fr_FR")) g_b_assume_azerty =
true;
1416 wxLogMessage(_T(
"wxLocale support not available"));
1421 if (g_config_wizard || b_initial_load) {
1423 auto res = wiz.Run();
1434 wxString vs = wxString(
"Version ") + VERSION_FULL +
" Build " + VERSION_DATE;
1435 g_bUpgradeInProcess = (vs != g_config_version_string);
1437 g_Platform->SetUpgradeOptions(vs, g_config_version_string);
1440 if (!g_Platform->GetLargeLogMessage().IsEmpty()) {
1441 wxLogMessage(g_Platform->GetLargeLogMessage());
1446 g_bdisable_opengl =
true;
1450 if (g_bdisable_opengl) g_bopengl =
false;
1452#if defined(__linux__) && !defined(__ANDROID__)
1453 if (g_bSoftwareGL) {
1454 setenv(
"LIBGL_ALWAYS_SOFTWARE",
"1", 1);
1467 if (0 == g_memCacheLimit) g_memCacheLimit = (int)(g_mem_total * 0.5);
1469 wxMin(g_memCacheLimit, 1024 * 1024);
1475 g_memCacheLimit = 0;
1476 if (0 == g_nCacheLimit)
1477 g_nCacheLimit = CACHE_N_LIMIT_DEFAULT;
1482 "chartlist.dat",
"CHRTLIST.DAT");
1486 "mmsitoname.csv",
"MMSINAME.CSV");
1489 if (pInit_Chart_Dir->IsEmpty()) {
1490 wxStandardPaths &std_path = g_Platform->GetStdPaths();
1494 pInit_Chart_Dir->Append(std_path.GetDocumentsDir());
1496 pInit_Chart_Dir->Append(androidGetExtStorageDir());
1500 InitRestListeners();
1503 gDefaultWorldMapLocation =
"gshhs";
1504 gDefaultWorldMapLocation.Prepend(g_Platform->GetSharedDataDir());
1505 gDefaultWorldMapLocation.Append(wxFileName::GetPathSeparator());
1506 if (gWorldMapLocation == wxEmptyString) {
1507 gWorldMapLocation = gDefaultWorldMapLocation;
1512 wxString default_tcdata0 =
1513 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1514 wxFileName::GetPathSeparator() + _T(
"harmonics-dwf-20210110-free.tcd"));
1515 wxString default_tcdata1 =
1516 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1517 wxFileName::GetPathSeparator() + _T(
"HARMONICS_NO_US.IDX"));
1519 if (TideCurrentDataSet.empty()) {
1520 TideCurrentDataSet.push_back(
1521 g_Platform->NormalizePath(default_tcdata0).ToStdString());
1522 TideCurrentDataSet.push_back(
1523 g_Platform->NormalizePath(default_tcdata1).ToStdString());
1528 if (g_sAIS_Alert_Sound_File.IsEmpty()) {
1529 wxString default_sound =
1530 (g_Platform->GetSharedDataDir() + _T(
"sounds") +
1531 wxFileName::GetPathSeparator() + _T(
"2bells.wav"));
1532 g_sAIS_Alert_Sound_File = g_Platform->NormalizePath(default_sound);
1537 g_Platform->Initialize_2();
1541 wxSize new_frame_size(-1, -1);
1543 ::wxClientDisplayRect(&cx, &cy, &cw, &ch);
1545 InitializeUserColors();
1547 auto style = g_StyleManager->GetCurrentStyle();
1548 auto bitmap =
new wxBitmap(style->GetIcon(
"default_pi", 32, 32));
1550 PluginLoader::getInstance()->SetPluginDefaultIcon(bitmap);
1552 wxLogWarning(
"Cannot initiate plugin default jigsaw icon.");
1554 if ((g_nframewin_x > 100) && (g_nframewin_y > 100) && (g_nframewin_x <= cw) &&
1555 (g_nframewin_y <= ch))
1556 new_frame_size.Set(g_nframewin_x, g_nframewin_y);
1558 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1564 if ((g_lastClientRectx != cx) || (g_lastClientRecty != cy) ||
1565 (g_lastClientRectw != cw) || (g_lastClientRecth != ch)) {
1566 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1567 g_bframemax =
false;
1570 g_lastClientRectx = cx;
1571 g_lastClientRecty = cy;
1572 g_lastClientRectw = cw;
1573 g_lastClientRecth = ch;
1576 wxPoint position(0, 0);
1577 wxSize dsize = wxGetDisplaySize();
1580 g_nframewin_posy = wxMax(g_nframewin_posy, 22);
1583 if ((g_nframewin_posx < dsize.x) && (g_nframewin_posy < dsize.y))
1584 position = wxPoint(g_nframewin_posx, g_nframewin_posy);
1589 frame_rect.left = position.x;
1590 frame_rect.top = position.y;
1591 frame_rect.right = position.x + new_frame_size.x;
1592 frame_rect.bottom = position.y + new_frame_size.y;
1596 if (NULL == MonitorFromRect(&frame_rect, MONITOR_DEFAULTTONULL))
1597 position = wxPoint(10, 10);
1602 const wxPoint ptScreen(position.x, position.y);
1603 const int displayIndex = wxDisplay::GetFromPoint(ptScreen);
1605 if (displayIndex == wxNOT_FOUND) position = wxPoint(10, 30);
1608 g_nframewin_posx = position.x;
1609 g_nframewin_posy = position.y;
1612 wxSize asz = getAndroidDisplayDimensions();
1617 if ((cw > 200) && (ch > 200))
1618 new_frame_size.Set(cw, ch);
1620 new_frame_size.Set(800, 400);
1624 long app_style = wxDEFAULT_FRAME_STYLE;
1625 app_style |= wxWANTS_CHARS;
1630 wxString short_version_name = wxString(PACKAGE_VERSION).BeforeFirst(
'+');
1631 wxString myframe_window_title =
1632 wxString(wxT(
"OpenCPN ") + short_version_name);
1635 myframe_window_title += _(
" -- [Portable(-p) executing from ");
1636 myframe_window_title += g_Platform->GetHomeDir();
1637 myframe_window_title += _T(
"]");
1641 fmsg.Printf(_T(
"Creating MyFrame...size(%d, %d) position(%d, %d)"),
1642 new_frame_size.x, new_frame_size.y, position.x, position.y);
1645 gFrame =
new MyFrame(NULL, myframe_window_title, position, new_frame_size,
1646 app_style, m_data_monitor);
1647 wxTheApp->SetTopWindow(gFrame);
1648 m_data_monitor->Reparent(gFrame);
1651 g_Platform->Initialize_3();
1658 g_pauidockart =
new wxAuiDefaultDockArt;
1659 g_pauimgr->SetArtProvider(g_pauidockart);
1660 g_pauimgr->SetDockSizeConstraint(.9, .9);
1665 g_pauimgr->SetManagedWindow(gFrame);
1667 gFrame->CreateCanvasLayout();
1671 gFrame->SetChartUpdatePeriod();
1675 gFrame->GetPrimaryCanvas()->SetFocus();
1677 pthumbwin =
new ThumbWin(gFrame->GetPrimaryCanvas());
1679 gFrame->ApplyGlobalSettings(
false);
1681 gFrame->SetAllToolbarScale();
1687 gFrame->SetAndApplyColorScheme(global_color_scheme);
1689 if (g_bframemax) gFrame->Maximize(
true);
1692 if (g_bresponsive && (gFrame->GetPrimaryCanvas()->GetPixPerMM() > 4.0))
1693 gFrame->Maximize(
true);
1700 ArrayOfCDI ChartDirArray;
1701 pConfig->LoadChartDirArray(ChartDirArray);
1706 if (g_bFirstRun && (ChartDirArray.GetCount() == 0)) {
1709 wxRegKey RegKey(wxString(_T(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\OpenCPN")));
1710 if (RegKey.Exists()) {
1712 _(
"Retrieving initial Chart Directory set from Windows Registry"));
1714 RegKey.QueryValue(wxString(_T(
"ChartDirs")), dirs);
1716 wxStringTokenizer tkz(dirs, _T(
";"));
1717 while (tkz.HasMoreTokens()) {
1718 wxString token = tkz.GetNextToken();
1721 cdi.fullpath = token.Trim();
1722 cdi.magic_number = _T(
"");
1724 ChartDirArray.Add(cdi);
1731 cdi.fullpath = _T(
"charts");
1732 cdi.fullpath.Prepend(g_Platform->GetSharedDataDir());
1733 cdi.magic_number = _T(
"");
1734 ChartDirArray.Add(cdi);
1738 if (ndirs) pConfig->UpdateChartDirs(ChartDirArray);
1748 if (!ChartDirArray.GetCount())
1749 if (::wxFileExists(ChartListFileName)) ::wxRemoveFile(ChartListFileName);
1753 if (g_NeedDBUpdate == 0 &&
1754 !ChartData->
LoadBinary(ChartListFileName, ChartDirArray)) {
1759 if (g_restore_dbindex >= 0) {
1760 if (ChartData->GetChartTableEntries() == 0)
1761 g_restore_dbindex = -1;
1763 else if (g_restore_dbindex > (ChartData->GetChartTableEntries() - 1))
1764 g_restore_dbindex = 0;
1768 ChartData->ApplyGroupArray(g_pGroupArray);
1776 if (g_rebuild_gl_cache && g_bopengl && g_GLOptions.m_bTextureCompression &&
1777 g_GLOptions.m_bTextureCompressionCaching) {
1778 gFrame->ReloadAllVP();
1787 if (g_glTextureManager) g_glTextureManager->BuildCompressedCache();
1797 if ((gps_watchdog_timeout_ticks > 60) || (gps_watchdog_timeout_ticks <= 0))
1798 gps_watchdog_timeout_ticks = (GPS_TIMEOUT_SECONDS * 1000) / TIMER_GFRAME_1;
1801 dogmsg.Printf(_T(
"GPS Watchdog Timeout is: %d sec."),
1802 gps_watchdog_timeout_ticks);
1803 wxLogMessage(dogmsg);
1805 sat_watchdog_timeout_ticks = gps_watchdog_timeout_ticks;
1813 if (g_bTrackCarryOver) g_bDeferredStartTrack =
true;
1815 pAnchorWatchPoint1 = NULL;
1816 pAnchorWatchPoint2 = NULL;
1820 gFrame->DoChartUpdate();
1825 gFrame->ReloadAllVP();
1827 gFrame->Refresh(
false);
1830 gFrame->GetPrimaryCanvas()->Enable();
1831 gFrame->GetPrimaryCanvas()->SetFocus();
1838 if (!g_bdisable_opengl) {
1842 (pgl->GetRendererString().Find(_T(
"UniChrome")) != wxNOT_FOUND)) {
1843 gFrame->m_defer_size = gFrame->GetSize();
1844 gFrame->SetSize(gFrame->m_defer_size.x - 10, gFrame->m_defer_size.y);
1845 g_pauimgr->Update();
1846 gFrame->m_bdefer_resize =
true;
1856 glDeleteTextures(n, texts);
1862 if (g_start_fullscreen) gFrame->ToggleFullScreen();
1867 gFrame->SetSize(getAndroidDisplayDimensions());
1868 androidSetFollowTool(gFrame->GetPrimaryCanvas()->m_bFollow ? 1 : 0, true);
1872 gFrame->GetPrimaryCanvas()->Enable();
1873 gFrame->GetPrimaryCanvas()->SetFocus();
1881 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
1884 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
1887 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
1892 OCPNPlatform::Initialize_4();
1895 androidHideBusyIcon();
1898 wxString::Format(_(
"OpenCPN Initialized in %ld ms."), init_sw.Time()));
1906 if (!n_NavMessageShown || (vs != g_config_version_string) ||
1907 (g_AndroidVersionCode != androidGetVersionCode())) {
1911 if (!ShowNavWarning()) {
1912 qDebug() <<
"Closing due to NavWarning Cancel";
1918 n_NavMessageShown = 1;
1922 g_AndroidVersionCode = androidGetVersionCode();
1923 qDebug() <<
"Persisting Version Code: " << g_AndroidVersionCode;
1928 if (!n_NavMessageShown || (vs != g_config_version_string)) {
1929 if (!ShowNavWarning())
return false;
1930 n_NavMessageShown = 1;
1937 g_bHasHwClock =
true;
1938#if defined(__UNIX__) && !defined(__ANDROID__)
1941 ((stat(
"/dev/rtc", &buffer) == 0) || (stat(
"/dev/rtc0", &buffer) == 0) ||
1942 (stat(
"/dev/misc/rtc", &buffer) == 0));
1945 g_config_version_string = vs;
1948 pConfig->UpdateSettings();
1951 gFrame->InitTimer.Start(5, wxTIMER_CONTINUOUS);
1953 g_pauimgr->Update();
1955 for (
auto *cp : TheConnectionParams()) {
1957 if (cp->GetDSPort().Contains(
"Serial")) {
1958 std::string port(cp->Port.ToStdString());
1966 m_comm_bridge.Initialize();
1968 std::vector<std::string> ipv4_addrs = get_local_ipv4_addresses();
1971 if (ipv4_addrs.size()) {
1972 std::string ipAddr = ipv4_addrs[0];
1975 if (data_dir.Last() != wxFileName::GetPathSeparator())
1976 data_dir.Append(wxFileName::GetPathSeparator());
1978 make_certificate(ipAddr, data_dir.ToStdString());
1980 m_rest_server.
StartServer(fs::path(data_dir.ToStdString()));
1981 StartMDNSService(g_hostname.ToStdString(),
"opencpn-object-control-service",
1987int MyApp::OnExit() {
1988 wxLogMessage(_T(
"opencpn::MyApp starting exit."));
1990 m_usb_watcher.Stop();
1993 wxDateTime lognow = wxDateTime::Now();
1995 wxString day = lognow.FormatISODate();
1996 wxString utc = lognow.FormatISOTime();
1997 wxString navmsg = _T(
"LOGBOOK: ");
2001 navmsg += _T(
" UTC ");
2005 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f "), gLat, gLon);
2009 if (std::isnan(gCog))
2010 cog.Printf(_T(
"COG ----- "));
2012 cog.Printf(_T(
"COG %10.5f "), gCog);
2015 if (std::isnan(gSog))
2016 sog.Printf(_T(
"SOG ----- "));
2018 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
2025 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f"), gLat, gLon);
2028 wxLogMessage(navmsg);
2029 g_loglast_time = lognow;
2031 if (ptcmgr)
delete ptcmgr;
2033 for (
Track *track : g_TrackList) {
2036 g_TrackList.clear();
2044 delete g_SencThreadManager;
2046 if (g_pGroupArray) {
2047 for (
unsigned int igroup = 0; igroup < g_pGroupArray->GetCount();
2049 delete g_pGroupArray->Item(igroup);
2052 g_pGroupArray->Clear();
2053 delete g_pGroupArray;
2056 wxLogMessage(_T(
"opencpn::MyApp exiting cleanly...\n"));
2057 wxLog::FlushActive();
2059 g_Platform->CloseLogFile();
2061 delete pInit_Chart_Dir;
2063 for (
Track *track : g_TrackList) {
2066 g_TrackList.clear();
2069 delete pWayPointMan;
2071 delete pMessageOnceArray;
2073 DeInitializeUserColors();
2077 delete m_pRegistrarMan;
2080 delete g_StyleManager;
2085 if (s_glu_dll_ready) {
2086 FreeLibrary(s_hGLU_DLL);
2095 void RestoreSystemColors(
void);
2096 RestoreSystemColors();
2103#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
2104 if (plocale_def_lang)
delete plocale_def_lang;
2107 FontMgr::Shutdown();
2109 g_Platform->OnExit_2();
2116#ifdef LINUX_CRASHRPT
2117void MyApp::OnFatalException() { g_crashprint.Report(); }
2123void MyCPLErrorHandler(CPLErr eErrClass,
int nError,
const char *pszErrorMsg)
2128 if (eErrClass == CE_Debug)
2129 snprintf(msg, 255,
"CPL: %s", pszErrorMsg);
2130 else if (eErrClass == CE_Warning)
2131 snprintf(msg, 255,
"CPL Warning %d: %s", nError, pszErrorMsg);
2133 snprintf(msg, 255,
"CPL ERROR %d: %s", nError, pszErrorMsg);
2135 wxString str(msg, wxConvUTF8);
Global state for AIS decoder.
Dialog for displaying a list of AIS targets.
Dialog for querying detailed information about an AIS target.
Implements the AboutFrame class with additional functionality.
EventVar reverse_route
Notified with a string GUID when user wants to reverse a route.
EventVar activate_route
Notified with a string GUID when user wants to activate a route.
Represents an active track that is currently being recorded.
Handles the AIS information GUI and sound alerts.
Dialog for managing CM93 chart offsets.
ChartCanvas - Main chart display and interaction component.
Manages the chart database and provides access to chart data.
bool LoadBinary(const wxString &filename, ArrayOfCDI &dir_array_check)
Load the chart database from a binary file.
Primary navigation console display for route and vessel tracking.
Overall logging handler, outputs to screen and log file.
const void Notify()
Notify all listeners, no data supplied.
void ScrubList()
Cleans up stale font entries after a locale change.
static void SeedRandom()
Seed the random generator used by GetUUID().
Common interface for all instance checkers.
virtual bool IsMainInstance()=0
Return true if this process is the primary opencpn instance.
virtual void CleanUp()
Remove all persistent instance state, including possible lock file and defunct opencpn processes.
virtual void OnExit()
Do whatever needed before wxWidget's checks triggers.
virtual void WaitUntilValid()
Wait until this object can be used for example for Dbus connection.
static LocalServerApi & GetInstance()
Dialog for displaying and editing waypoint properties.
void Init(const KeyProvider &kp, std::function< void(ObservedEvt &ev)> action)
Initiate an object yet not listening.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
bool StartServer(const fs::path &certificate_location) override
Start the server thread.
Represents a waypoint or mark within the navigation system.
static std::function< void(unsigned, const unsigned *) delete_gl_textures)
Horrible Hack (tm).
Represents a navigational route in the navigation system.
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Dialog for displaying query results of S57 objects.
Manager for S57 chart SENC creation threads.
Window for displaying chart thumbnails.
Represents a track, which is a series of connected track points.
Listen to hardware events and notifies SystemEvents when new devices are plugged in.
Represents the About dialog for OpenCPN.
OpenGL chart rendering canvas.
Handles crash reporting in wxWidgets applications.
Global variables reflecting command line options and arguments.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
Start/stop mdns service routines.
void check_last_start()
Check if the last start failed, possibly invoke user dialog and set safe mode state.
void clear_check()
Mark last run as successful.
bool CheckDongleAccess(wxWindow *parent)
Runs checks and if required dialogs to make dongle accessible.
bool CheckSerialAccess(wxWindow *parent, const std::string device)
Run checks and possible dialogs to ensure device is accessible.
Access checks for comm devices and dongle.