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 "NMEALogWindow.h"
146#include "observable.h"
148#include "OCPN_AUIManager.h"
149#include "ocpn_frame.h"
150#include "OCPNPlatform.h"
152#include "rest_server_gui.h"
153#include "route_ctx_factory.h"
154#include "routemanagerdialog.h"
155#include "routeman_gui.h"
156#include "RoutePropDlgImpl.h"
159#include "S57QueryDialog.h"
160#include "safe_mode_gui.h"
161#include "SoundFactory.h"
165#include "TrackPropDlg.h"
169#include "glChartCanvas.h"
173#include "model/macutils.h"
177#include "model/garmin_protocol_mgr.h"
178void RedirectIOToConsole();
181#if defined(__WXMSW__) && defined(__MSVC__LEAK)
182#include "Stackwalker.h"
186#include "crashprint.h"
190#include "androidUTIL.h"
192#include "serial/serial.h"
196const char *
const kUsage =
199 opencpn [-p] [-f] [-G] [-g] [-P] [-l <str>] [-u <num>] [-U] [-s] [GPX file ...]
200 opencpn --remote [-R] | -q] | -e] |-o <str>]
202Options for starting opencpn
204 -c, --configdir=<dirpath> Use alternative configuration directory.
205 -p, --portable Run in portable mode.
206 -f, --fullscreen Switch to full screen mode on start.
207 -G, --no_opengl Disable OpenGL video acceleration. This setting will
209 -g, --rebuild_gl_raster_cache Rebuild OpenGL raster cache on start.
210 -D, --rebuild_chart_db Rescan chart directories and rebuild the chart database
211 -P, --parse_all_enc Convert all S-57 charts to OpenCPN's internal format on start.
212 -l, --loglevel=<str> Amount of logging: error, warning, message, info, debug or trace
213 -u, --unit_test_1=<num> Display a slideshow of <num> charts and then exit.
214 Zero or negative <num> specifies no limit.
216 -s, --safe_mode Run without plugins, opengl and other "dangerous" stuff
217 -W, --config_wizard Start with initial configuration wizard
219Options manipulating already started opencpn
220 -r, --remote Execute commands on already running instance
221 -R, --raise Make running OpenCPN visible if hidden
222 -q, --quit Terminate already running opencpn
223 -e, --get_rest_endpoint Print rest server endpoint and exit.
224 -o, --open=<GPX file> Open file in running opencpn
227 GPX file GPX-formatted file with waypoints or routes.
231wxDEFINE_EVENT(EVT_N2K_129029, wxCommandEvent);
232wxDEFINE_EVENT(EVT_N2K_129026, wxCommandEvent);
234wxDEFINE_EVENT(EVT_N0183_RMC, wxCommandEvent);
235wxDEFINE_EVENT(EVT_N0183_HDT, wxCommandEvent);
236wxDEFINE_EVENT(EVT_N0183_HDG, wxCommandEvent);
237wxDEFINE_EVENT(EVT_N0183_HDM, wxCommandEvent);
238wxDEFINE_EVENT(EVT_N0183_VTG, wxCommandEvent);
239wxDEFINE_EVENT(EVT_N0183_GSV, wxCommandEvent);
240wxDEFINE_EVENT(EVT_N0183_GGA, wxCommandEvent);
241wxDEFINE_EVENT(EVT_N0183_GLL, wxCommandEvent);
242wxDEFINE_EVENT(EVT_N0183_AIVDO, wxCommandEvent);
252WX_DEFINE_OBJARRAY(ArrayOfCDI);
257bool g_bUpgradeInProcess;
269int g_restore_stackindex;
270int g_restore_dbindex;
271double g_ChartNotRenderScaleFactor;
273LayerList *pLayerList;
285int g_nbrightness = 100;
287bool bDBUpdateInProgress;
292bool g_bshowToolbar =
true;
293bool g_bexpert =
true;
294bool g_bBasicMenus =
false;
296bool bDrawCurrentValues;
298wxString ChartListFileName;
299wxString gWorldMapLocation, gDefaultWorldMapLocation;
300wxString gWorldShapefileLocation;
301wxString *pInit_Chart_Dir;
303wxString g_SENCPrefix;
304wxString g_UserPresLibData;
305wxString g_VisibleLayers;
306wxString g_InvisibleLayers;
307wxString g_VisiNameinLayers;
308wxString g_InVisiNameinLayers;
310bool g_bcompression_wait;
311bool g_FlushNavobjChanges;
312int g_FlushNavobjChangesTimeout;
314wxString g_uploadConnection;
321int g_mem_total, g_mem_initial;
323bool s_bSetSystemTime;
325static unsigned int malloc_max;
327wxDateTime g_start_time;
328wxDateTime g_loglast_time;
329static OcpnSound *_bells_sounds[] = {SoundFactory(), SoundFactory()};
330std::vector<OcpnSound *> bells_sound(_bells_sounds, _bells_sounds + 2);
332OcpnSound *g_anchorwatch_sound = SoundFactory();
334double AnchorPointMinDist;
335bool AnchorAlertOn1, AnchorAlertOn2;
343wxPrintData *g_printData = (wxPrintData *)NULL;
346wxPageSetupData *g_pageSetupData = (wxPageSetupData *)NULL;
349bool g_bShowDepthUnits;
353bool g_bShowActiveRouteHighway;
356bool g_bPlayShipsBells;
357bool g_bFullscreenToolbar;
359bool g_bTransparentToolbar;
360bool g_bTransparentToolbarInOpenGLOK;
361int g_nAutoHideToolbar;
362bool g_bAutoHideToolbar;
364bool g_bPermanentMOBIcon;
365bool g_bTempShowMenuBar;
367int g_iNavAidRadarRingsNumberVisible;
368bool g_bNavAidRadarRingsShown;
369float g_fNavAidRadarRingsStep;
370int g_pNavAidRadarRingsStepUnits;
371bool g_bWayPointPreventDragging;
372bool g_bConfirmObjectDelete;
373wxColour g_colourOwnshipRangeRingsColour;
377ColorScheme global_color_scheme = GLOBAL_COLOR_SCHEME_DAY;
379wxArrayPtrVoid *UserColourHashTableArray;
380wxColorHashMap *pcurrent_user_color_hash;
389int g_ChartUpdatePeriod;
390int g_SkewCompUpdatePeriod;
392int g_lastClientRectx;
393int g_lastClientRecty;
394int g_lastClientRectw;
395int g_lastClientRecth;
399double g_display_size_mm;
400std::vector<size_t> g_config_display_size_mm;
401bool g_config_display_size_manual;
404int g_ChartScaleFactor;
405float g_MarkScaleFactorExp;
406int g_last_ChartScaleFactor;
407int g_ShipScaleFactor;
408float g_ShipScaleFactorExp;
409int g_ENCSoundingScaleFactor;
410int g_ENCTextScaleFactor;
416s57RegistrarMgr *m_pRegistrarMan;
421#include "model/macutils.h"
430extern bool s_glu_dll_ready;
431extern HINSTANCE s_hGLU_DLL;
437double g_ownship_predictor_minutes;
438double g_ownship_HDTpredictor_miles;
439int g_cog_predictor_style;
440wxString g_cog_predictor_color;
441int g_cog_predictor_endmarker;
442int g_ownship_HDTpredictor_style;
443wxString g_ownship_HDTpredictor_color;
444int g_ownship_HDTpredictor_endmarker;
445int g_ownship_HDTpredictor_width;
447bool g_own_ship_sog_cog_calc;
448int g_own_ship_sog_cog_calc_damp_sec;
453int g_iSoundDeviceIndex;
455int g_S57_dialog_sx, g_S57_dialog_sy;
463bool g_bAutoAnchorMark;
466long gStart_LMT_Offset;
468wxArrayString *pMessageOnceArray;
470bool g_bUseGLL =
true;
501bool g_bsmoothpanzoom;
503bool g_bSmoothRecenter =
true;
505double g_overzoom_emphasis_base;
506bool g_oz_vector_scale;
507double g_plus_minus_zoom_factor;
510bool g_b_legacy_input_filter_behaviour;
517bool g_bFullScreenQuilt =
true;
521ChartGroupArray *g_pGroupArray;
525std::vector<std::string> TideCurrentDataSet;
526wxString g_TCData_Dir;
529bool g_bDeferredInitDone;
530int options_lastPage = 0;
531int options_subpage = 0;
533wxPoint options_lastWindowPos(0, 0);
534wxSize options_lastWindowSize(0, 0);
537bool g_bsimplifiedScalebar;
541bool GetMemoryStatus(
int *mem_total,
int *mem_used);
544int g_nAIS_activity_timer;
546bool g_bEnableZoomToCursor;
549bool g_bDeferredStartTrack;
550bool g_bHighliteTracks;
551wxColour g_colourTrackLineColour;
552wxString g_default_wp_icon;
555double g_TrackIntervalSeconds;
557int g_cm93_zoom_factor;
559bool g_bShowDetailSlider;
560int g_detailslider_dialog_x, g_detailslider_dialog_y;
567bool g_b_overzoom_x =
true;
569int g_OwnShipIconType;
570double g_n_ownship_length_meters;
571double g_n_ownship_beam_meters;
572double g_n_gps_antenna_offset_y;
573double g_n_gps_antenna_offset_x;
574int g_n_ownship_min_mm;
579bool g_bPreserveScaleOnX;
582about *g_pAboutDlgLegacy;
584#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
585wxLocale *plocale_def_lang = 0;
597wxString g_localeOverride;
598bool g_b_assume_azerty;
604bool g_bShowStatusBar;
610int g_AisTargetList_count;
611bool g_bAisTargetList_autosort;
616wxAuiDefaultDockArt *g_pauidockart;
618wxString g_toolbarConfig = _T(
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
623long g_maintoolbar_orient;
624float g_toolbar_scalefactor;
626float g_compass_scalefactor;
628bool g_bShowCompassWin;
630bool g_benable_rotate;
638double gQueryVar = 361.0;
640char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
642int portaudio_initialized;
644char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
647int g_sticky_projection;
649int n_NavMessageShown;
650wxString g_config_version_string;
652wxString g_CmdSoundString;
670bool b_inCompressAllCharts;
674int g_chart_zoom_modifier_raster;
675int g_chart_zoom_modifier_vector;
677bool g_bAdvanceRouteWaypointOnArrivalOnly;
679bool g_bSpaceDropMark;
681wxArrayString g_locale_catalog_array;
682bool b_reloadForPlugins;
683bool g_btrackContinuous;
685unsigned int g_canvasConfig;
687bool g_bmasterToolbarFull =
true;
689int g_AndroidVersionCode;
694WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
696arrayofCanvasPtr g_canvasArray;
697wxString g_lastAppliedTemplateGUID;
703bool g_disable_main_toolbar;
716DEFINE_GUID(GARMIN_DETECT_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81,
717 0x6b, 0xba, 0xe7, 0x22, 0xc0);
721#include <wx/msw/msvcrt.h>
725static const long long lNaN = 0xfff8000000000000;
726#define NAN (*(double *)&lNaN)
730void appendOSDirSlash(wxString *pString);
732void InitializeUserColors(
void);
733void DeInitializeUserColors(
void);
734void SetSystemColors(ColorScheme cs);
736static bool LoadAllPlugIns(
bool load_enabled) {
737 g_Platform->ShowBusySpinner();
738 bool b = PluginLoader::getInstance()->
LoadAllPlugIns(load_enabled);
739 g_Platform->HideBusySpinner();
747#if defined(__WXGTK__) || defined(__WXQT__)
748#include "bitmaps/opencpn.xpm"
751wxString newPrivateFileName(wxString,
const char *name,
752 [[maybe_unused]]
const char *windowsName) {
753 wxString fname = wxString::FromUTF8(name);
754 wxString filePathAndName;
757 if (filePathAndName.Last() != wxFileName::GetPathSeparator())
758 filePathAndName.Append(wxFileName::GetPathSeparator());
761 wxString fwname = wxString::FromUTF8(windowsName);
762 filePathAndName.Append(fwname);
764 filePathAndName.Append(fname);
767 return filePathAndName;
776BEGIN_EVENT_TABLE(
MyApp, wxApp)
777EVT_ACTIVATE_APP(MyApp::OnActivateApp)
780static
void ActivateRoute(const std::
string &guid) {
781 Route *route = g_pRouteMan->FindRouteByGUID(guid);
783 wxLogMessage(
"Cannot activate guid: no such route");
786 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
791 if (wxNOT_FOUND == route->m_RouteNameString.Find(
"MOB")) {
792 point = g_pRouteMan->FindBestActivatePoint(route, gLat, gLon, gCog, gSog);
794 point = route->GetPoint(2);
796 g_pRouteMan->ActivateRoute(route, point);
798 route->m_bRtIsSelected =
false;
801static void ReverseRoute(
const std::string &guid) {
802 Route *route = g_pRouteMan->FindRouteByGUID(guid);
804 wxLogMessage(
"Cannot activate guid: no such route");
811void MyApp::InitRestListeners() {
812 auto activate_route = [&](wxCommandEvent ev) {
813 auto guid = ev.GetString().ToStdString();
817 auto reverse_route = [&](wxCommandEvent ev) {
818 auto guid = ev.GetString().ToStdString();
824bool MyApp::OpenFile(
const std::string &path) {
826 auto result = nav_objects.load_file(path.c_str());
828 std::string s(_(
"Cannot load route or waypoint file: "));
829 s += std::string(
"\"") + path +
"\"";
830 wxMessageBox(s,
"OpenCPN", wxICON_WARNING | wxOK);
836 nav_objects.LoadAllGPXObjects(!nav_objects.IsOpenCPN(), wpt_dups,
true);
838 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
839 pRouteManagerDialog->UpdateLists();
840 LLBBox box = nav_objects.GetBBox();
841 if (box.GetValid()) {
842 gFrame->CenterView(gFrame->GetPrimaryCanvas(), box);
848void MyApp::OnInitCmdLine(wxCmdLineParser &parser) {
851 parser.AddSwitch(
"h",
"help",
"", wxCMD_LINE_OPTION_HELP);
852 parser.AddSwitch(
"p",
"portable");
853 parser.AddOption(
"c",
"configdir",
"", wxCMD_LINE_VAL_STRING,
854 wxCMD_LINE_PARAM_OPTIONAL);
855 parser.AddSwitch(
"f",
"fullscreen");
856 parser.AddSwitch(
"G",
"no_opengl");
857 parser.AddSwitch(
"W",
"config_wizard");
858 parser.AddSwitch(
"g",
"rebuild_gl_raster_cache");
859 parser.AddSwitch(
"D",
"rebuild_chart_db");
860 parser.AddSwitch(
"P",
"parse_all_enc");
861 parser.AddOption(
"l",
"loglevel");
862 parser.AddOption(
"u",
"unit_test_1",
"", wxCMD_LINE_VAL_NUMBER);
863 parser.AddSwitch(
"U",
"unit_test_2");
864 parser.AddParam(
"import GPX files", wxCMD_LINE_VAL_STRING,
865 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
866 parser.AddSwitch(
"s",
"safe_mode");
867 parser.AddSwitch(
"r",
"remote");
868 parser.AddSwitch(
"R",
"raise");
869 parser.AddSwitch(
"q",
"quit");
870 parser.AddSwitch(
"e",
"get_rest_endpoint");
871 parser.AddOption(
"o",
"open",
"", wxCMD_LINE_VAL_STRING,
872 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
878static void ParseLoglevel(wxCmdLineParser &parser) {
879 wxLog::SetLogLevel(wxLOG_Message);
882static void ParseLoglevel(wxCmdLineParser &parser) {
883 const char *strLevel = std::getenv(
"OPENCPN_LOGLEVEL");
884 strLevel = strLevel ? strLevel :
"info";
886 if (parser.Found(
"l", &wxLevel)) {
887 strLevel = wxLevel.c_str();
889 wxLogLevel level = OcpnLog::str2level(strLevel);
890 if (level == OcpnLog::LOG_BADLEVEL) {
891 fprintf(stderr,
"Bad loglevel %s, using \"info\"", strLevel);
894 wxLog::SetLogLevel(level);
899bool MyApp::OnCmdLineHelp(wxCmdLineParser &parser) {
906bool MyApp::OnCmdLineParsed(wxCmdLineParser &parser) {
911 g_unit_test_2 = parser.Found(
"unit_test_2");
912 g_bportable = parser.Found(
"p");
913 g_start_fullscreen = parser.Found(
"fullscreen");
914 g_bdisable_opengl = parser.Found(
"no_opengl");
915 g_rebuild_gl_cache = parser.Found(
"rebuild_gl_raster_cache");
916 g_NeedDBUpdate = parser.Found(
"rebuild_chart_db") ? 2 : 0;
917 g_parse_all_enc = parser.Found(
"parse_all_enc");
918 g_config_wizard = parser.Found(
"config_wizard");
919 if (parser.Found(
"unit_test_1", &number)) {
920 g_unit_test_1 =
static_cast<int>(number);
921 if (g_unit_test_1 == 0) g_unit_test_1 = -1;
923 safe_mode::set_mode(parser.Found(
"safe_mode"));
924 ParseLoglevel(parser);
926 if (parser.Found(
"configdir", &wxstr)) {
927 g_configdir = wxstr.ToStdString();
928 fs::path path(g_configdir);
929 if (!fs::exists(path) || !fs::is_directory(path)) {
930 std::cerr << g_configdir <<
" is not an existing directory.\n";
935 bool has_start_options =
false;
936 static const std::vector<std::string> kStartOptions = {
941 "rebuild_gl_raster_cache",
947 for (
const auto &opt : kStartOptions) {
948 if (parser.Found(opt)) has_start_options =
true;
950 if (has_start_options && parser.Found(
"remote")) {
951 std::cerr <<
"this option is not compatible with --remote\n";
955 bool has_remote_options =
false;
956 static const std::vector<std::string> kRemoteOptions = {
957 "raise",
"quit",
"open",
"get_rest_endpoint"};
958 for (
const auto &opt : kRemoteOptions) {
959 if (parser.Found(opt)) has_remote_options =
true;
961 if (has_remote_options && !parser.Found(
"remote")) {
962 std::cerr <<
"This option requires --remote\n";
966 for (
size_t paramNr = 0; paramNr < parser.GetParamCount(); ++paramNr)
967 g_params.push_back(parser.GetParam(paramNr).ToStdString());
970 if (!parser.Found(
"remote"))
971 m_parsed_cmdline = ParsedCmdline();
972 else if (parser.Found(
"raise"))
973 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Raise);
974 else if (parser.Found(
"quit"))
975 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Quit);
976 else if (parser.Found(
"get_rest_endpoint"))
977 m_parsed_cmdline = ParsedCmdline(CmdlineAction::GetRestEndpoint);
978 else if (parser.Found(
"open", &optarg))
979 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Open, optarg.ToStdString());
980 else if (parser.GetParamCount() == 1)
982 ParsedCmdline(CmdlineAction::Open, parser.GetParam(0).ToStdString());
983 else if (!has_start_options && !has_remote_options) {
985 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Raise);
995bool MyApp::OnExceptionInMainLoop() {
996 wxLogWarning(_T(
"Caught MainLoopException, continuing..."));
1001void MyApp::OnActivateApp(wxActivateEvent &event) {
return; }
1003static wxStopWatch init_sw;
1006 if (m_exitcode != -2)
return m_exitcode;
1007 return wxAppConsole::OnRun();
1018 if (wxGetEnv(
"WAYLAND_DISPLAY", NULL)) {
1019 setenv(
"GDK_BACKEND",
"x11", 1);
1022 "mesa_glthread",
"false",
1028bool MyApp::OnInit() {
1029 if (!wxApp::OnInit())
return false;
1031 androidEnableBackButton(
false);
1032 androidEnableOptionItems(
false);
1035 GpxDocument::SeedRandom();
1037#if defined(__WXGTK__) && defined(ocpnUSE_GLES) && defined(__ARM_ARCH)
1043 wxBitmap bmp(10, 10, -1);
1045 dc.SelectObject(bmp);
1046 dc.DrawText(_T(
"X"), 0, 0);
1051 g_BasePlatform = g_Platform;
1058 if (m_parsed_cmdline.action == CmdlineAction::Skip) {
1062 std::cerr <<
"No remote opencpn found. Giving up.\n";
1067 std::unique_ptr<LocalClientApi> client;
1069 client = LocalClientApi::GetClient();
1071 WARNING_LOG <<
"Ipc client exception: " << ie.str();
1078 wxMessageBox(_(
"Sorry, an existing instance of OpenCPN may be too busy "
1079 "to respond.\nPlease retry."),
1080 "OpenCPN", wxICON_INFORMATION | wxOK);
1085 auto result = client->HandleCmdline(m_parsed_cmdline.action,
1086 m_parsed_cmdline.arg);
1090 wxLogDebug(
"Error running remote command: %s", result.second.c_str());
1099 if (getenv(
"OPENCPN_FATAL_ERROR") != 0) {
1100 wxLogFatalError(getenv(
"OPENCPN_FATAL_ERROR"));
1105 if (!safe_mode::get_mode()) {
1111 OCPNPlatform::Initialize_1();
1116 MyApp::SetAppDisplayName(
"OpenCPN");
1119 wxDateTime x = wxDateTime::UNow();
1120 long seed = x.GetMillisecond();
1121 seed *= x.GetTicks();
1126 setlocale(LC_NUMERIC,
"C");
1128 g_start_time = wxDateTime::Now();
1130 g_loglast_time = g_start_time;
1131 g_loglast_time.MakeGMT();
1132 g_loglast_time.Subtract(
1133 wxTimeSpan(0, 29, 0, 0));
1135 AnchorPointMinDist = 5.0;
1141 GetMemoryStatus(&g_mem_total, &g_mem_initial);
1145 wxFont temp_font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
1146 wxFONTWEIGHT_NORMAL, FALSE, wxString(_T(
"")),
1147 wxFONTENCODING_SYSTEM);
1148 temp_font.SetDefaultEncoding(wxFONTENCODING_SYSTEM);
1151 if (!g_Platform->InitializeLogFile()) {
1164 wxLogMessage(_T(
"\n\n________\n"));
1166 wxDateTime now = wxDateTime::Now();
1167 LOG_INFO(
"------- OpenCPN version %s restarted at %s -------\n", VERSION_FULL,
1168 now.FormatISODate().mb_str().data());
1169 wxLogLevel level = wxLog::GetLogLevel();
1170 LOG_INFO(
"Using loglevel %s", OcpnLog::level2str(level).c_str());
1172 wxString wxver(wxVERSION_STRING);
1173 wxver.Prepend(_T(
"wxWidgets version: "));
1175 wxPlatformInfo platforminfo = wxPlatformInfo::Get();
1179 os_name = platforminfo.GetOperatingSystemIdName();
1181 os_name = platforminfo.GetOperatingSystemFamilyName();
1184 wxString platform = os_name + _T(
" ") + platforminfo.GetArchName() + _T(
" ") +
1185 platforminfo.GetPortIdName();
1187 wxLogMessage(wxver + _T(
" ") + platform);
1189 ::wxGetOsVersion(&osMajor, &osMinor);
1190 wxString osVersionMsg;
1191 osVersionMsg.Printf(_T(
"OS Version reports as: %d.%d"), osMajor, osMinor);
1192 wxLogMessage(osVersionMsg);
1194 wxLogMessage(_T(
"MemoryStatus: mem_total: %d mb, mem_initial: %d mb"),
1195 g_mem_total / 1024, g_mem_initial / 1024);
1200 if (!detail->osd_names_like.empty())
1201 like0 = detail->osd_names_like[0].c_str();
1202 msgplat.Printf(
"OCPN_OSDetail: %s ; %s ; %s ; %s ; %s",
1203 detail->osd_arch.c_str(), detail->osd_name.c_str(),
1204 detail->osd_version.c_str(), detail->osd_ID.c_str(),
1206 wxLogMessage(msgplat);
1208 wxString imsg = _T(
"SData_Locn is ");
1209 imsg += g_Platform->GetSharedDataDir();
1213 ::wxInitAllImageHandlers();
1217 prepareAndroidStyleSheets();
1221 pInit_Chart_Dir =
new wxString();
1224 g_pGroupArray =
new ChartGroupArray;
1226 imsg = _T(
"PrivateDataDir is ");
1232 pMessageOnceArray =
new wxArrayString;
1237 new Routeman(RoutePropDlg::GetDlgCtx(), RoutemanGui::GetDlgCtx(),
1238 NMEALogWindow::GetInstance());
1242 pSelect->SetSelectPixelRadius(12);
1245 pSelectTC =
new Select();
1247 pSelectTC->SetSelectPixelRadius(25);
1250 pSelectAIS =
new Select();
1251 pSelectAIS->SetSelectPixelRadius(12);
1255 g_pais_query_dialog_active = NULL;
1258 g_hostname = ::wxGetHostName();
1259 if (g_hostname.IsEmpty()) g_hostname = wxGetUserName();
1261 androidGetDeviceInfo();
1262 g_hostname = wxString(
"Android-") + g_android_Device_Model;
1263 g_hostname.Replace(
" ",
"-",
true);
1268 wxString p(
"Portable-");
1269 g_hostname = p + g_hostname;
1274 pLayerList =
new LayerList;
1276 pRouteList =
new RouteList;
1283#ifdef PROBE_PORTS__WITH_HELPER
1284 user_user_id = getuid();
1285 file_user_id = geteuid();
1289 bool b_initial_load =
false;
1291 wxFileName config_test_file_name(g_Platform->GetConfigFileName());
1292 if (config_test_file_name.FileExists())
1293 wxLogMessage(_T(
"Using existing Config_File: ") +
1294 g_Platform->GetConfigFileName());
1297 wxLogMessage(_T(
"Creating new Config_File: ") +
1298 g_Platform->GetConfigFileName());
1300 b_initial_load =
true;
1303 config_test_file_name.DirExists(config_test_file_name.GetPath()))
1304 if (!config_test_file_name.Mkdir(config_test_file_name.GetPath()))
1305 wxLogMessage(_T(
"Cannot create config file directory for ") +
1306 g_Platform->GetConfigFileName());
1311 pConfig = g_Platform->GetConfigObject();
1312 InitBaseConfig(pConfig);
1313 pConfig->LoadMyConfig();
1317 if (b_initial_load) g_Platform->SetDefaultOptions();
1319 g_Platform->applyExpertMode(g_bUIexpert);
1327 g_StyleManager->SetStyle(_T(
"MUI_flat"));
1328 if (!g_StyleManager->IsOK()) {
1329 wxString msg = _(
"Failed to initialize the user interface. ");
1330 msg << _(
"OpenCPN cannot start. ");
1331 msg << _(
"The necessary configuration files were not found. ");
1332 msg << _(
"See the log file at ") << g_Platform->GetLogFileName()
1333 << _(
" for details.") << _T(
"\n\n");
1334 msg << g_Platform->GetSharedDataDir();
1336 wxMessageDialog w(NULL, msg, _(
"Failed to initialize the user interface. "),
1337 wxCANCEL | wxICON_ERROR);
1344 if (style) style->chartStatusWindowTransparent =
true;
1348 pWayPointMan = NULL;
1352 msg.Printf(_T(
"Detected display size (horizontal): %d mm"),
1353 (
int)g_display_size_mm);
1357 if (g_config_display_size_manual &&
1358 g_config_display_size_mm.size() > g_current_monitor &&
1359 g_config_display_size_mm[g_current_monitor] > 0) {
1360 g_display_size_mm = g_config_display_size_mm[g_current_monitor];
1362 msg.Printf(_T(
"Display size (horizontal) config override: %d mm"),
1363 (
int)g_display_size_mm);
1368 g_display_size_mm = wxMax(50, g_display_size_mm);
1371 int SelectPixelRadius = 50;
1373 pSelect->SetSelectPixelRadius(SelectPixelRadius);
1374 pSelectTC->SetSelectPixelRadius(wxMax(25, SelectPixelRadius));
1375 pSelectAIS->SetSelectPixelRadius(SelectPixelRadius);
1379 if (!n_NavMessageShown) {
1386#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
1389 g_Platform->SetLocaleSearchPrefixes();
1391 wxString def_lang_canonical = g_Platform->GetDefaultSystemLocale();
1393 imsg = _T(
"System default Language: ") + def_lang_canonical;
1396 wxString cflmsg = _T(
"Config file language: ") + g_locale;
1397 wxLogMessage(cflmsg);
1399 if (g_locale.IsEmpty()) {
1400 g_locale = def_lang_canonical;
1402 _T(
"Config file language empty, using system default: ") + g_locale;
1403 wxLogMessage(cflmsg);
1407 g_locale = g_Platform->GetAdjustedAppLocale();
1408 cflmsg = _T(
"Adjusted App language: ") + g_locale;
1409 wxLogMessage(cflmsg);
1412 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
1414 imsg = _T(
"Opencpn language set to: ");
1421 if (g_locale == _T(
"fr_FR")) g_b_assume_azerty =
true;
1423 wxLogMessage(_T(
"wxLocale support not available"));
1428 if (g_config_wizard || b_initial_load) {
1430 auto res = wiz.Run();
1441 wxString vs = wxString(
"Version ") + VERSION_FULL +
" Build " + VERSION_DATE;
1442 g_bUpgradeInProcess = (vs != g_config_version_string);
1444 g_Platform->SetUpgradeOptions(vs, g_config_version_string);
1447 if (!g_Platform->GetLargeLogMessage().IsEmpty()) {
1448 wxLogMessage(g_Platform->GetLargeLogMessage());
1453 g_bdisable_opengl =
true;
1457 if (g_bdisable_opengl) g_bopengl =
false;
1459#if defined(__linux__) && !defined(__ANDROID__)
1460 if (g_bSoftwareGL) {
1461 setenv(
"LIBGL_ALWAYS_SOFTWARE",
"1", 1);
1474 if (0 == g_memCacheLimit) g_memCacheLimit = (int)(g_mem_total * 0.5);
1476 wxMin(g_memCacheLimit, 1024 * 1024);
1482 g_memCacheLimit = 0;
1483 if (0 == g_nCacheLimit)
1484 g_nCacheLimit = CACHE_N_LIMIT_DEFAULT;
1489 "chartlist.dat",
"CHRTLIST.DAT");
1493 "mmsitoname.csv",
"MMSINAME.CSV");
1496 if (pInit_Chart_Dir->IsEmpty()) {
1497 wxStandardPaths &std_path = g_Platform->GetStdPaths();
1501 pInit_Chart_Dir->Append(std_path.GetDocumentsDir());
1503 pInit_Chart_Dir->Append(androidGetExtStorageDir());
1507 InitRestListeners();
1510 gDefaultWorldMapLocation =
"gshhs";
1511 gDefaultWorldMapLocation.Prepend(g_Platform->GetSharedDataDir());
1512 gDefaultWorldMapLocation.Append(wxFileName::GetPathSeparator());
1513 if (gWorldMapLocation == wxEmptyString) {
1514 gWorldMapLocation = gDefaultWorldMapLocation;
1519 wxString default_tcdata0 =
1520 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1521 wxFileName::GetPathSeparator() + _T(
"harmonics-dwf-20210110-free.tcd"));
1522 wxString default_tcdata1 =
1523 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1524 wxFileName::GetPathSeparator() + _T(
"HARMONICS_NO_US.IDX"));
1526 if (TideCurrentDataSet.empty()) {
1527 TideCurrentDataSet.push_back(
1528 g_Platform->NormalizePath(default_tcdata0).ToStdString());
1529 TideCurrentDataSet.push_back(
1530 g_Platform->NormalizePath(default_tcdata1).ToStdString());
1535 if (g_sAIS_Alert_Sound_File.IsEmpty()) {
1536 wxString default_sound =
1537 (g_Platform->GetSharedDataDir() + _T(
"sounds") +
1538 wxFileName::GetPathSeparator() + _T(
"2bells.wav"));
1539 g_sAIS_Alert_Sound_File = g_Platform->NormalizePath(default_sound);
1544 g_Platform->Initialize_2();
1548 wxSize new_frame_size(-1, -1);
1550 ::wxClientDisplayRect(&cx, &cy, &cw, &ch);
1552 InitializeUserColors();
1554 auto style = g_StyleManager->GetCurrentStyle();
1555 auto bitmap =
new wxBitmap(style->GetIcon(
"default_pi", 32, 32));
1557 PluginLoader::getInstance()->SetPluginDefaultIcon(bitmap);
1559 wxLogWarning(
"Cannot initiate plugin default jigsaw icon.");
1561 if ((g_nframewin_x > 100) && (g_nframewin_y > 100) && (g_nframewin_x <= cw) &&
1562 (g_nframewin_y <= ch))
1563 new_frame_size.Set(g_nframewin_x, g_nframewin_y);
1565 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1571 if ((g_lastClientRectx != cx) || (g_lastClientRecty != cy) ||
1572 (g_lastClientRectw != cw) || (g_lastClientRecth != ch)) {
1573 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1574 g_bframemax =
false;
1577 g_lastClientRectx = cx;
1578 g_lastClientRecty = cy;
1579 g_lastClientRectw = cw;
1580 g_lastClientRecth = ch;
1583 wxPoint position(0, 0);
1584 wxSize dsize = wxGetDisplaySize();
1587 g_nframewin_posy = wxMax(g_nframewin_posy, 22);
1590 if ((g_nframewin_posx < dsize.x) && (g_nframewin_posy < dsize.y))
1591 position = wxPoint(g_nframewin_posx, g_nframewin_posy);
1596 frame_rect.left = position.x;
1597 frame_rect.top = position.y;
1598 frame_rect.right = position.x + new_frame_size.x;
1599 frame_rect.bottom = position.y + new_frame_size.y;
1603 if (NULL == MonitorFromRect(&frame_rect, MONITOR_DEFAULTTONULL))
1604 position = wxPoint(10, 10);
1609 const wxPoint ptScreen(position.x, position.y);
1610 const int displayIndex = wxDisplay::GetFromPoint(ptScreen);
1612 if (displayIndex == wxNOT_FOUND) position = wxPoint(10, 30);
1615 g_nframewin_posx = position.x;
1616 g_nframewin_posy = position.y;
1619 wxSize asz = getAndroidDisplayDimensions();
1624 if ((cw > 200) && (ch > 200))
1625 new_frame_size.Set(cw, ch);
1627 new_frame_size.Set(800, 400);
1631 long app_style = wxDEFAULT_FRAME_STYLE;
1632 app_style |= wxWANTS_CHARS;
1637 wxString short_version_name = wxString(PACKAGE_VERSION).BeforeFirst(
'+');
1638 wxString myframe_window_title =
1639 wxString(wxT(
"OpenCPN ") + short_version_name);
1642 myframe_window_title += _(
" -- [Portable(-p) executing from ");
1643 myframe_window_title += g_Platform->GetHomeDir();
1644 myframe_window_title += _T(
"]");
1648 fmsg.Printf(_T(
"Creating MyFrame...size(%d, %d) position(%d, %d)"),
1649 new_frame_size.x, new_frame_size.y, position.x, position.y);
1652 gFrame =
new MyFrame(NULL, myframe_window_title, position, new_frame_size,
1656 g_Platform->Initialize_3();
1663 g_pauidockart =
new wxAuiDefaultDockArt;
1664 g_pauimgr->SetArtProvider(g_pauidockart);
1665 g_pauimgr->SetDockSizeConstraint(.9, .9);
1670 g_pauimgr->SetManagedWindow(gFrame);
1672 gFrame->CreateCanvasLayout();
1676 gFrame->SetChartUpdatePeriod();
1680 gFrame->GetPrimaryCanvas()->SetFocus();
1682 pthumbwin =
new ThumbWin(gFrame->GetPrimaryCanvas());
1684 gFrame->ApplyGlobalSettings(
false);
1686 gFrame->SetAllToolbarScale();
1692 gFrame->SetAndApplyColorScheme(global_color_scheme);
1694 if (g_bframemax) gFrame->Maximize(
true);
1697 if (g_bresponsive && (gFrame->GetPrimaryCanvas()->GetPixPerMM() > 4.0))
1698 gFrame->Maximize(
true);
1705 ArrayOfCDI ChartDirArray;
1706 pConfig->LoadChartDirArray(ChartDirArray);
1711 if (g_bFirstRun && (ChartDirArray.GetCount() == 0)) {
1714 wxRegKey RegKey(wxString(_T(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\OpenCPN")));
1715 if (RegKey.Exists()) {
1717 _(
"Retrieving initial Chart Directory set from Windows Registry"));
1719 RegKey.QueryValue(wxString(_T(
"ChartDirs")), dirs);
1721 wxStringTokenizer tkz(dirs, _T(
";"));
1722 while (tkz.HasMoreTokens()) {
1723 wxString token = tkz.GetNextToken();
1726 cdi.fullpath = token.Trim();
1727 cdi.magic_number = _T(
"");
1729 ChartDirArray.Add(cdi);
1736 cdi.fullpath = _T(
"charts");
1737 cdi.fullpath.Prepend(g_Platform->GetSharedDataDir());
1738 cdi.magic_number = _T(
"");
1739 ChartDirArray.Add(cdi);
1743 if (ndirs) pConfig->UpdateChartDirs(ChartDirArray);
1753 if (!ChartDirArray.GetCount())
1754 if (::wxFileExists(ChartListFileName)) ::wxRemoveFile(ChartListFileName);
1758 if (g_NeedDBUpdate == 0 &&
1759 !ChartData->
LoadBinary(ChartListFileName, ChartDirArray)) {
1764 if (g_restore_dbindex >= 0) {
1765 if (ChartData->GetChartTableEntries() == 0)
1766 g_restore_dbindex = -1;
1768 else if (g_restore_dbindex > (ChartData->GetChartTableEntries() - 1))
1769 g_restore_dbindex = 0;
1773 ChartData->ApplyGroupArray(g_pGroupArray);
1781 if (g_rebuild_gl_cache && g_bopengl && g_GLOptions.m_bTextureCompression &&
1782 g_GLOptions.m_bTextureCompressionCaching) {
1783 gFrame->ReloadAllVP();
1792 if (g_glTextureManager) g_glTextureManager->BuildCompressedCache();
1802 if ((gps_watchdog_timeout_ticks > 60) || (gps_watchdog_timeout_ticks <= 0))
1803 gps_watchdog_timeout_ticks = (GPS_TIMEOUT_SECONDS * 1000) / TIMER_GFRAME_1;
1806 dogmsg.Printf(_T(
"GPS Watchdog Timeout is: %d sec."),
1807 gps_watchdog_timeout_ticks);
1808 wxLogMessage(dogmsg);
1810 sat_watchdog_timeout_ticks = gps_watchdog_timeout_ticks;
1818 if (g_bTrackCarryOver) g_bDeferredStartTrack =
true;
1820 pAnchorWatchPoint1 = NULL;
1821 pAnchorWatchPoint2 = NULL;
1825 gFrame->DoChartUpdate();
1830 gFrame->ReloadAllVP();
1832 gFrame->Refresh(
false);
1835 gFrame->GetPrimaryCanvas()->Enable();
1836 gFrame->GetPrimaryCanvas()->SetFocus();
1843 if (!g_bdisable_opengl) {
1847 (pgl->GetRendererString().Find(_T(
"UniChrome")) != wxNOT_FOUND)) {
1848 gFrame->m_defer_size = gFrame->GetSize();
1849 gFrame->SetSize(gFrame->m_defer_size.x - 10, gFrame->m_defer_size.y);
1850 g_pauimgr->Update();
1851 gFrame->m_bdefer_resize =
true;
1861 glDeleteTextures(n, texts);
1867 if (g_start_fullscreen) gFrame->ToggleFullScreen();
1872 gFrame->SetSize(getAndroidDisplayDimensions());
1873 androidSetFollowTool(gFrame->GetPrimaryCanvas()->m_bFollow ? 1 : 0, true);
1877 gFrame->GetPrimaryCanvas()->Enable();
1878 gFrame->GetPrimaryCanvas()->SetFocus();
1886 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
1889 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
1892 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
1897 OCPNPlatform::Initialize_4();
1900 androidHideBusyIcon();
1903 wxString::Format(_(
"OpenCPN Initialized in %ld ms."), init_sw.Time()));
1911 if (!n_NavMessageShown || (vs != g_config_version_string) ||
1912 (g_AndroidVersionCode != androidGetVersionCode())) {
1916 if (!ShowNavWarning()) {
1917 qDebug() <<
"Closing due to NavWarning Cancel";
1923 n_NavMessageShown = 1;
1927 g_AndroidVersionCode = androidGetVersionCode();
1928 qDebug() <<
"Persisting Version Code: " << g_AndroidVersionCode;
1933 if (!n_NavMessageShown || (vs != g_config_version_string)) {
1934 if (!ShowNavWarning())
return false;
1935 n_NavMessageShown = 1;
1942 g_bHasHwClock =
true;
1943#if defined(__UNIX__) && !defined(__ANDROID__)
1946 ((stat(
"/dev/rtc", &buffer) == 0) || (stat(
"/dev/rtc0", &buffer) == 0) ||
1947 (stat(
"/dev/misc/rtc", &buffer) == 0));
1950 g_config_version_string = vs;
1953 pConfig->UpdateSettings();
1956 gFrame->InitTimer.Start(5, wxTIMER_CONTINUOUS);
1958 g_pauimgr->Update();
1960 for (
auto *cp : TheConnectionParams()) {
1962 if (cp->GetDSPort().Contains(
"Serial")) {
1963 std::string port(cp->Port.ToStdString());
1971 m_comm_bridge.Initialize();
1973 std::vector<std::string> ipv4_addrs = get_local_ipv4_addresses();
1976 if (ipv4_addrs.size()) {
1977 std::string ipAddr = ipv4_addrs[0];
1980 if (data_dir.Last() != wxFileName::GetPathSeparator())
1981 data_dir.Append(wxFileName::GetPathSeparator());
1983 make_certificate(ipAddr, data_dir.ToStdString());
1985 m_rest_server.
StartServer(fs::path(data_dir.ToStdString()));
1986 StartMDNSService(g_hostname.ToStdString(),
"opencpn-object-control-service",
1992int MyApp::OnExit() {
1993 wxLogMessage(_T(
"opencpn::MyApp starting exit."));
1995 m_usb_watcher.Stop();
1998 wxDateTime lognow = wxDateTime::Now();
2000 wxString day = lognow.FormatISODate();
2001 wxString utc = lognow.FormatISOTime();
2002 wxString navmsg = _T(
"LOGBOOK: ");
2006 navmsg += _T(
" UTC ");
2010 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f "), gLat, gLon);
2014 if (std::isnan(gCog))
2015 cog.Printf(_T(
"COG ----- "));
2017 cog.Printf(_T(
"COG %10.5f "), gCog);
2020 if (std::isnan(gSog))
2021 sog.Printf(_T(
"SOG ----- "));
2023 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
2030 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f"), gLat, gLon);
2033 wxLogMessage(navmsg);
2034 g_loglast_time = lognow;
2036 if (ptcmgr)
delete ptcmgr;
2038 for (
Track *track : g_TrackList) {
2041 g_TrackList.clear();
2049 delete g_SencThreadManager;
2051 if (g_pGroupArray) {
2052 for (
unsigned int igroup = 0; igroup < g_pGroupArray->GetCount();
2054 delete g_pGroupArray->Item(igroup);
2057 g_pGroupArray->Clear();
2058 delete g_pGroupArray;
2061 wxLogMessage(_T(
"opencpn::MyApp exiting cleanly...\n"));
2062 wxLog::FlushActive();
2064 g_Platform->CloseLogFile();
2066 delete pInit_Chart_Dir;
2068 for (
Track *track : g_TrackList) {
2071 g_TrackList.clear();
2074 delete pWayPointMan;
2076 delete pMessageOnceArray;
2078 DeInitializeUserColors();
2082 delete m_pRegistrarMan;
2085 delete g_StyleManager;
2090 if (s_glu_dll_ready) {
2091 FreeLibrary(s_hGLU_DLL);
2100 void RestoreSystemColors(
void);
2101 RestoreSystemColors();
2108#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
2109 if (plocale_def_lang)
delete plocale_def_lang;
2112 FontMgr::Shutdown();
2114 g_Platform->OnExit_2();
2121#ifdef LINUX_CRASHRPT
2122void MyApp::OnFatalException() { g_crashprint.Report(); }
2128void MyCPLErrorHandler(CPLErr eErrClass,
int nError,
const char *pszErrorMsg)
2133 if (eErrClass == CE_Debug)
2134 snprintf(msg, 255,
"CPL: %s", pszErrorMsg);
2135 else if (eErrClass == CE_Warning)
2136 snprintf(msg, 255,
"CPL Warning %d: %s", nError, pszErrorMsg);
2138 snprintf(msg, 255,
"CPL ERROR %d: %s", nError, pszErrorMsg);
2140 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.
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.
const void Notify()
Notify all listeners, no data supplied.
void ScrubList()
Cleans up stale font entries after a locale change.
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.
static std::function< void(unsigned, const unsigned *)> delete_gl_textures
Horrible Hack (tm).
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
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.