63#include <wx/apptrait.h>
64#include <wx/arrimpl.cpp>
65#include <wx/artprov.h>
66#include <wx/aui/aui.h>
67#include <wx/clrpicker.h>
74#include <wx/jsonreader.h>
75#include <wx/listctrl.h>
76#include <wx/printdlg.h>
78#include <wx/progdlg.h>
79#include <wx/settings.h>
80#include <wx/stdpaths.h>
81#include <wx/tokenzr.h>
82#include <wx/cmdline.h>
85#include "ocpn_frame.h"
87#include "AboutFrameImpl.h"
89#include "AISTargetAlertDialog.h"
90#include "AISTargetQueryDialog.h"
91#include "ais_info_gui.h"
93#include "CanvasConfig.h"
99#include "config_vars.h"
100#include "ConfigMgr.h"
101#include "DetailSlider.h"
104#include "GoToPositionDialog.h"
105#include "gdal/cpl_csv.h"
106#include "glTexCache.h"
110#include "multiplexer.h"
111#include "nav_object_database.h"
113#include "navutil_base.h"
114#include "OCPN_AUIManager.h"
115#include "OCPNPlatform.h"
118#include "plugin_handler.h"
120#include "routemanagerdialog.h"
122#include "RoutePropDlgImpl.h"
125#include "S57QueryDialog.h"
126#include "safe_mode.h"
128#include "SoundFactory.h"
133#include "TrackPropDlg.h"
134#include "AISTargetListDialog.h"
135#include "comm_n0183_output.h"
136#include "comm_bridge.h"
137#include "certificates.h"
138#include "mDNS_query.h"
145#include "comm_vars.h"
147#include "mDNS_service.h"
150#include "udev_rule_mgr.h"
154#include "glChartCanvas.h"
162#include "garmin_protocol_mgr.h"
163void RedirectIOToConsole();
166#if defined(__WXMSW__) && defined (__MSVC__LEAK)
167#include "Stackwalker.h"
171#include "crashprint.h"
174#ifdef __OCPN__ANDROID__
175#include "androidUTIL.h"
177#include "serial/serial.h"
180static void UpdatePositionCalculatedSogCog();
184wxDEFINE_EVENT(EVT_N2K_129029, wxCommandEvent);
185wxDEFINE_EVENT(EVT_N2K_129026, wxCommandEvent);
187wxDEFINE_EVENT(EVT_N0183_RMC, wxCommandEvent);
188wxDEFINE_EVENT(EVT_N0183_HDT, wxCommandEvent);
189wxDEFINE_EVENT(EVT_N0183_HDG, wxCommandEvent);
190wxDEFINE_EVENT(EVT_N0183_HDM, wxCommandEvent);
191wxDEFINE_EVENT(EVT_N0183_VTG, wxCommandEvent);
192wxDEFINE_EVENT(EVT_N0183_GSV, wxCommandEvent);
193wxDEFINE_EVENT(EVT_N0183_GGA, wxCommandEvent);
194wxDEFINE_EVENT(EVT_N0183_GLL, wxCommandEvent);
195wxDEFINE_EVENT(EVT_N0183_AIVDO, wxCommandEvent);
206WX_DEFINE_OBJARRAY(ArrayOfCDI);
213bool g_bUpgradeInProcess;
218wxString g_compatOsVersion;
222bool g_start_fullscreen;
223bool g_rebuild_gl_cache;
227wxVector<wxString> g_params;
236wxString *pdir_list[20];
237int g_restore_stackindex;
238int g_restore_dbindex;
239double g_ChartNotRenderScaleFactor;
240int g_nDepthUnitDisplay;
242RouteList *pRouteList;
243std::vector<Track*> g_TrackList;
244LayerList *pLayerList;
262double initial_scale_ppm, initial_rotation;
264int g_nbrightness = 100;
266bool bDBUpdateInProgress;
271bool g_bshowToolbar =
true;
272bool g_bexpert =
true;
273bool g_bBasicMenus =
false;
275bool bDrawCurrentValues;
277wxString ChartListFileName;
278wxString AISTargetNameFileName;
279wxString gWorldMapLocation, gDefaultWorldMapLocation;
280wxString *pInit_Chart_Dir;
281wxString g_winPluginDir;
283wxString g_SENCPrefix;
284wxString g_UserPresLibData;
285wxString g_VisibleLayers;
286wxString g_InvisibleLayers;
287wxString g_VisiNameinLayers;
288wxString g_InVisiNameinLayers;
290bool g_bcompression_wait;
291bool g_FlushNavobjChanges;
292int g_FlushNavobjChangesTimeout;
294wxString g_uploadConnection;
301int g_mem_total, g_mem_used, g_mem_initial;
303bool s_bSetSystemTime;
305static unsigned int malloc_max;
307wxDateTime g_start_time;
308wxDateTime g_loglast_time;
309static OcpnSound *_bells_sounds[] = {SoundFactory(), SoundFactory()};
310std::vector<OcpnSound *> bells_sound(_bells_sounds, _bells_sounds + 2);
312OcpnSound *g_anchorwatch_sound = SoundFactory();
313wxString g_anchorwatch_sound_file;
314wxString g_DSC_sound_file;
315wxString g_SART_sound_file;
316wxString g_AIS_sound_file;
320double AnchorPointMinDist;
321bool AnchorAlertOn1, AnchorAlertOn2;
329wxPrintData *g_printData = (wxPrintData *)NULL;
332wxPageSetupData *g_pageSetupData = (wxPageSetupData *)NULL;
335bool g_bShowDepthUnits;
339bool g_bShowActiveRouteHighway;
342bool g_bPlayShipsBells;
343bool g_bFullscreenToolbar;
345bool g_bTransparentToolbar;
346bool g_bTransparentToolbarInOpenGLOK;
347int g_nAutoHideToolbar;
348bool g_bAutoHideToolbar;
350bool g_bPermanentMOBIcon;
351bool g_bTempShowMenuBar;
354int g_iDistanceFormat;
358int g_iNavAidRadarRingsNumberVisible;
359float g_fNavAidRadarRingsStep;
360int g_pNavAidRadarRingsStepUnits;
361int g_iWaypointRangeRingsNumber;
362float g_fWaypointRangeRingsStep;
363int g_iWaypointRangeRingsStepUnits;
364wxColour g_colourWaypointRangeRingsColour;
365bool g_bWayPointPreventDragging;
366bool g_bConfirmObjectDelete;
367wxColour g_colourOwnshipRangeRingsColour;
374ColorScheme global_color_scheme = GLOBAL_COLOR_SCHEME_DAY;
376int Usercolortable_index;
377wxArrayPtrVoid *UserColorTableArray;
378wxArrayPtrVoid *UserColourHashTableArray;
379wxColorHashMap *pcurrent_user_color_hash;
394bool g_bfilter_cogsog;
395int g_COGFilterSec = 1;
398int g_ChartUpdatePeriod;
399int g_SkewCompUpdatePeriod;
401int g_lastClientRectx;
402int g_lastClientRecty;
403int g_lastClientRectw;
404int g_lastClientRecth;
405double g_display_size_mm;
406double g_config_display_size_mm;
407bool g_config_display_size_manual;
408float g_selection_radius_mm = 2.0;
409float g_selection_radius_touch_mm = 10.0;
412int g_ChartScaleFactor;
413float g_ChartScaleFactorExp;
414float g_MarkScaleFactorExp;
415int g_last_ChartScaleFactor;
416int g_ShipScaleFactor;
417float g_ShipScaleFactorExp;
418int g_ENCSoundingScaleFactor;
419int g_ENCTextScaleFactor;
440extern bool s_glu_dll_ready;
441extern HINSTANCE s_hGLU_DLL;
447double g_ownship_predictor_minutes;
448double g_ownship_HDTpredictor_miles;
450bool g_own_ship_sog_cog_calc;
451int g_own_ship_sog_cog_calc_damp_sec;
452wxDateTime last_own_ship_sog_cog_calc_ts;
453double last_own_ship_sog_cog_calc_lat, last_own_ship_sog_cog_calc_lon;
460bool g_bAIS_CPA_Alert;
461bool g_bAIS_CPA_Alert_Audio;
464int g_iSoundDeviceIndex;
466int g_ais_alert_dialog_x, g_ais_alert_dialog_y;
467int g_ais_alert_dialog_sx, g_ais_alert_dialog_sy;
468int g_ais_query_dialog_x, g_ais_query_dialog_y;
470int g_S57_dialog_sx, g_S57_dialog_sy;
478bool g_bAutoAnchorMark;
482wxDateTime g_StartTime;
486long gStart_LMT_Offset;
488wxArrayString *pMessageOnceArray;
493bool g_bUseGLL =
true;
508bool g_bsmoothpanzoom;
510double g_overzoom_emphasis_base;
511bool g_oz_vector_scale;
512double g_plus_minus_zoom_factor;
514int g_nCOMPortCheck = 32;
516bool g_b_legacy_input_filter_behaviour;
523bool g_bAISRolloverShowClass;
524bool g_bAISRolloverShowCOG;
525bool g_bAISRolloverShowCPA;
529bool g_bFullScreenQuilt =
true;
535bool g_bdisable_opengl;
537ChartGroupArray *g_pGroupArray;
541wxArrayString TideCurrentDataSet;
542wxString g_TCData_Dir;
544bool g_boptionsactive;
546bool g_bDeferredInitDone;
547int options_lastPage = 0;
548int options_subpage = 0;
550wxPoint options_lastWindowPos(0, 0);
551wxSize options_lastWindowSize(0, 0);
554bool g_bsimplifiedScalebar;
557wxColour g_border_color_default;
558int g_border_size_default;
559int g_sash_size_default;
560wxColour g_caption_color_default;
561wxColour g_sash_color_default;
562wxColour g_background_color_default;
566bool GetMemoryStatus(
int *mem_total,
int *mem_used);
579double g_MarkLost_Mins;
581double g_RemoveLost_Mins;
583bool g_bSyncCogPredictors;
584double g_ShowCOG_Mins;
585bool g_bAISShowTracks;
586double g_AISShowTracks_Mins;
587double g_AISShowTracks_Limit;
589bool g_bAllowShowScaled;
590double g_ShowMoored_Kts;
591wxString g_sAIS_Alert_Sound_File;
592bool g_bAIS_CPA_Alert_Suppress_Moored;
593bool g_bAIS_ACK_Timeout;
594double g_AckTimeout_Mins;
596bool g_bShowAreaNotices;
598bool g_bDrawAISRealtime;
599double g_AIS_RealtPred_Kts;
601int g_Show_Target_Name_Scale;
604int g_nAIS_activity_timer;
606bool g_bEnableZoomToCursor;
609bool g_bTrackCarryOver;
610bool g_bDeferredStartTrack;
612int g_track_rotate_time;
613int g_track_rotate_time_type;
614bool g_bHighliteTracks;
615int g_route_line_width;
616int g_track_line_width;
617wxColour g_colourTrackLineColour;
618wxString g_default_wp_icon;
619wxString g_default_routepoint_icon;
622double g_TrackIntervalSeconds;
623double g_TrackDeltaDistance;
624int g_nTrackPrecision;
626int g_total_NMEAerror_messages;
628int g_cm93_zoom_factor;
630bool g_bShowDetailSlider;
631int g_detailslider_dialog_x, g_detailslider_dialog_y;
638bool g_b_overzoom_x =
true;
640int g_OwnShipIconType;
641double g_n_ownship_length_meters;
642double g_n_ownship_beam_meters;
643double g_n_gps_antenna_offset_y;
644double g_n_gps_antenna_offset_x;
645int g_n_ownship_min_mm;
647double g_n_arrival_circle_radius;
650bool g_bPreserveScaleOnX;
653about *g_pAboutDlgLegacy;
655#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
656wxLocale *plocale_def_lang;
660wxString g_localeOverride;
661bool g_b_assume_azerty;
672wxStaticBitmap *g_pStatBoxTool;
673bool g_bShowStatusBar;
679wxString g_AisTargetList_perspective;
680int g_AisTargetList_range;
681int g_AisTargetList_sortColumn;
682bool g_bAisTargetList_sortReverse;
683wxString g_AisTargetList_column_spec;
684wxString g_AisTargetList_column_order;
685int g_AisTargetList_count;
686bool g_bAisTargetList_autosort;
691wxAuiDefaultDockArt *g_pauidockart;
693wxString g_toolbarConfig = _T(
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
694wxString g_toolbarConfigSecondary = _T(
"....XX..X........XXXXXXXXXXXX");
699long g_maintoolbar_orient;
700float g_toolbar_scalefactor;
702float g_compass_scalefactor;
704bool g_bShowCompassWin;
706bool g_benable_rotate;
708bool g_bShowTrue =
true;
721double gQueryVar = 361.0;
723char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
725int portaudio_initialized;
727bool g_bAIS_GCPA_Alert_Audio;
728bool g_bAIS_SART_Alert_Audio;
729bool g_bAIS_DSC_Alert_Audio;
730bool g_bAnchor_Alert_Audio;
732char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
735int g_sticky_projection;
737bool g_benableUDPNullHeader;
739int n_NavMessageShown;
740wxString g_config_version_string;
742wxString g_CmdSoundString;
748bool b_inCompressAllCharts;
752int g_chart_zoom_modifier_raster;
753int g_chart_zoom_modifier_vector;
755int g_NMEAAPBPrecision;
757bool g_bAdvanceRouteWaypointOnArrivalOnly;
759bool g_bSpaceDropMark;
761wxArrayString g_locale_catalog_array;
762bool b_reloadForPlugins;
763bool g_btrackContinuous;
765unsigned int g_canvasConfig;
767bool g_bmasterToolbarFull =
true;
769int g_AndroidVersionCode;
774WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
776arrayofCanvasPtr g_canvasArray;
777arrayofCanvasConfigPtr g_canvasConfigArray;
778wxString g_lastAppliedTemplateGUID;
795DEFINE_GUID(GARMIN_DETECT_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81,
796 0x6b, 0xba, 0xe7, 0x22, 0xc0);
800#define _CRTDBG_MAP_ALLOC
803#define DEBUG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__)
808static const long long lNaN = 0xfff8000000000000;
809#define NAN (*(double *)&lNaN)
813void appendOSDirSlash(wxString *pString);
815void InitializeUserColors(
void);
816void DeInitializeUserColors(
void);
817void SetSystemColors(ColorScheme cs);
819static bool LoadAllPlugIns(
bool load_enabled) {
820 g_Platform->ShowBusySpinner();
821 bool b = PluginLoader::getInstance()->LoadAllPlugIns(load_enabled);
822 g_Platform->HideBusySpinner();
829#ifndef __OCPN__ANDROID__
835 bool OnExec(
const wxString &topic,
const wxString &data);
839bool stConnection::OnExec(
const wxString &topic,
const wxString &data) {
841 if (!gFrame)
return false;
844 if (path.IsEmpty()) {
845 gFrame->InvalidateAllGL();
846 gFrame->RefreshAllCanvas(
false);
850 pSet->load_file(path.fn_str());
852 pSet->LoadAllGPXObjects(
853 !pSet->IsOpenCPN(), wpt_dups,
855 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
856 pRouteManagerDialog->UpdateLists();
858 LLBBox box = pSet->GetBBox();
859 if (box.GetValid()) {
860 gFrame->CenterView(gFrame->GetPrimaryCanvas(), box);
871 wxConnectionBase *OnAcceptConnection(
const wxString &topic);
875wxConnectionBase *stServer::OnAcceptConnection(
const wxString &topic) {
876 if (topic.Lower() == wxT(
"opencpn")) {
878 wxWindowList::Node *node = wxTopLevelWindows.GetFirst();
880 wxDialog *dialog = wxDynamicCast(node->GetData(), wxDialog);
881 if (dialog && dialog->IsModal()) {
884 node = node->GetNext();
895 wxConnectionBase *OnMakeConnection() {
return new stConnection; }
904#if defined(__WXGTK__) || defined(__WXQT__)
905#include "bitmaps/opencpn.xpm"
910wxString newPrivateFileName(wxString home_locn,
const char *name,
911 const char *windowsName) {
912 wxString fname = wxString::FromUTF8(name);
913 wxString fwname = wxString::FromUTF8(windowsName);
914 wxString filePathAndName;
916 filePathAndName = g_Platform->GetPrivateDataDir();
917 if (filePathAndName.Last() != wxFileName::GetPathSeparator())
918 filePathAndName.Append(wxFileName::GetPathSeparator());
921 filePathAndName.Append(fwname);
923 filePathAndName.Append(fname);
926 return filePathAndName;
936BEGIN_EVENT_TABLE(
MyApp, wxApp)
937EVT_ACTIVATE_APP(MyApp::OnActivateApp)
940#include <wx/dynlib.h>
942#if wxUSE_CMDLINE_PARSER
943void MyApp::OnInitCmdLine(wxCmdLineParser &parser) {
945 parser.AddSwitch(_T(
"h"), _T(
"help"), _(
"Show usage syntax."),
946 wxCMD_LINE_OPTION_HELP);
947 parser.AddSwitch(_T(
"p"), wxEmptyString, _(
"Run in portable mode."));
948 parser.AddSwitch(_T(
"fullscreen"), wxEmptyString,
949 _(
"Switch to full screen mode on start."));
951 _T(
"no_opengl"), wxEmptyString,
952 _(
"Disable OpenGL video acceleration. This setting will be remembered."));
953 parser.AddSwitch(_T(
"rebuild_gl_raster_cache"), wxEmptyString,
954 _T(
"Rebuild OpenGL raster cache on start."));
956 _T(
"parse_all_enc"), wxEmptyString,
957 _T(
"Convert all S-57 charts to OpenCPN's internal format on start."));
959 _T(
"l"), _T(
"loglevel"),
960 _(
"Amount of logging: error, warning, message, info, debug or trace"));
961 parser.AddOption(_T(
"unit_test_1"), wxEmptyString,
962 _(
"Display a slideshow of <num> charts and then exit. Zero "
963 "or negative <num> specifies no limit."),
964 wxCMD_LINE_VAL_NUMBER);
965 parser.AddSwitch(_T(
"unit_test_2"));
966 parser.AddParam(
"import GPX files", wxCMD_LINE_VAL_STRING,
967 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
968 parser.AddLongSwitch(
"unit_test_2");
969 parser.AddSwitch(
"safe_mode");
973static void ParseLoglevel(wxCmdLineParser &parser) {
974 const char *strLevel = std::getenv(
"OPENCPN_LOGLEVEL");
975 strLevel = strLevel ? strLevel :
"info";
977 if (parser.Found(
"l", &wxLevel)) {
978 strLevel = wxLevel.c_str();
980 wxLogLevel level = OcpnLog::str2level(strLevel);
981 if (level == OcpnLog::LOG_BADLEVEL) {
982 fprintf(stderr,
"Bad loglevel %s, using \"info\"", strLevel);
986 wxLog::SetLogLevel(level);
989bool MyApp::OnCmdLineParsed(wxCmdLineParser &parser) {
994 g_unit_test_2 = parser.Found(_T(
"unit_test_2"));
995 g_bportable = parser.Found(_T(
"p"));
996 g_start_fullscreen = parser.Found(_T(
"fullscreen"));
997 g_bdisable_opengl = parser.Found(_T(
"no_opengl"));
998 g_rebuild_gl_cache = parser.Found(_T(
"rebuild_gl_raster_cache"));
999 g_parse_all_enc = parser.Found(_T(
"parse_all_enc"));
1000 if (parser.Found(_T(
"unit_test_1"), &number)) {
1001 g_unit_test_1 =
static_cast<int>(number);
1002 if (g_unit_test_1 == 0) g_unit_test_1 = -1;
1004 safe_mode::set_mode(parser.Found(
"safe_mode"));
1005 ParseLoglevel(parser);
1007 for (
size_t paramNr = 0; paramNr < parser.GetParamCount(); ++paramNr)
1008 g_params.push_back(parser.GetParam(paramNr));
1018bool MyApp::OnExceptionInMainLoop() {
1019 wxLogWarning(_T(
"Caught MainLoopException, continuing..."));
1024void MyApp::OnActivateApp(wxActivateEvent &event) {
1030 if (!event.GetActive()) {
1035 if (g_bTempShowMenuBar) {
1036 g_bTempShowMenuBar =
false;
1037 if (gFrame) gFrame->ApplyGlobalSettings(
false);
1046static wxStopWatch init_sw;
1052 if (wxGetEnv(
"WAYLAND_DISPLAY", NULL))
1053 setenv(
"GDK_BACKEND",
"x11", 1);
1058bool MyApp::OnInit() {
1059 if (!wxApp::OnInit())
return false;
1060#ifdef __OCPN__ANDROID__
1061 androidEnableBackButton(
false);
1062 androidEnableOptionItems(
false);
1065 GpxDocument::SeedRandom();
1066 safe_mode::set_mode(
false);
1068 last_own_ship_sog_cog_calc_ts = wxInvalidDateTime;
1070#if defined(__WXGTK__) && defined(ocpnUSE_GLES) && defined(__ARM_ARCH)
1076 wxBitmap bmp(10, 10, -1);
1078 dc.SelectObject(bmp);
1079 dc.DrawText(_T(
"X"), 0, 0);
1085 g_BasePlatform = g_Platform;
1087#ifndef __OCPN__ANDROID__
1090 if (!g_bportable && wxDirExists(g_Platform->GetPrivateDataDir())) {
1091 wxChar separator = wxFileName::GetPathSeparator();
1092 wxString service_name =
1093 g_Platform->GetPrivateDataDir() + separator + _T(
"opencpn-ipc");
1095 m_checker =
new wxSingleInstanceChecker(_T(
"_OpenCPN_SILock"),
1096 g_Platform->GetPrivateDataDir());
1097 if (!m_checker->IsAnotherRunning()) {
1099 if (!m_server->Create(service_name)) {
1100 wxLogDebug(wxT(
"Failed to create an IPC service."));
1106 wxString hostName = wxT(
"localhost");
1108 wxConnectionBase *connection =
1109 client->MakeConnection(hostName, service_name, _T(
"OpenCPN"));
1112 if (!g_params.empty()) {
1113 for (
size_t n = 0; n < g_params.size(); n++) {
1114 wxString path = g_params[n];
1115 if (::wxFileExists(path)) {
1116 connection->Execute(path);
1120 connection->Execute(wxT(
""));
1121 connection->Disconnect();
1130 wxString lockFile = wxString(g_Platform->GetPrivateDataDir() +
1131 separator + _T(
"_OpenCPN_SILock"));
1132 if (wxFileExists(lockFile)) wxRemoveFile(lockFile);
1134 wxMessageBox(_(
"Sorry, an existing instance of OpenCPN may be too busy "
1135 "too respond.\nPlease retry."),
1136 wxT(
"OpenCPN"), wxICON_INFORMATION | wxOK);
1144 if (getenv(
"OPENCPN_FATAL_ERROR") != 0) {
1145 wxLogFatalError(getenv(
"OPENCPN_FATAL_ERROR"));
1148 if (!safe_mode::get_mode()) {
1153 OCPNPlatform::Initialize_1();
1155#if wxCHECK_VERSION(3, 0, 0)
1159 MyApp::SetAppDisplayName(
"OpenCPN");
1163 wxDateTime x = wxDateTime::UNow();
1164 long seed = x.GetMillisecond();
1165 seed *= x.GetTicks();
1170 setlocale(LC_NUMERIC,
"C");
1172 g_start_time = wxDateTime::Now();
1174 g_loglast_time = g_start_time;
1175 g_loglast_time.MakeGMT();
1176 g_loglast_time.Subtract(
1177 wxTimeSpan(0, 29, 0, 0));
1179 AnchorPointMinDist = 5.0;
1185 GetMemoryStatus(&g_mem_total, &g_mem_initial);
1189 wxFont temp_font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
1190 wxFONTWEIGHT_NORMAL, FALSE, wxString(_T(
"")),
1191 wxFONTENCODING_SYSTEM);
1192 temp_font.SetDefaultEncoding(wxFONTENCODING_SYSTEM);
1195 if (!g_Platform->InitializeLogFile())
return false;
1206 wxLogMessage(_T(
"\n\n________\n"));
1208 g_vs = wxString(VERSION_FULL).Trim(
true).Trim(
false);
1209 wxDateTime now = wxDateTime::Now();
1210 LOG_INFO(
"------- OpenCPN version %s restarted at %s -------\n", VERSION_FULL,
1211 now.FormatISODate().mb_str().data());
1212 wxLogLevel level = wxLog::GetLogLevel();
1213 LOG_INFO(
"Using loglevel %s", OcpnLog::level2str(level).c_str());
1215 wxString wxver(wxVERSION_STRING);
1216 wxver.Prepend(_T(
"wxWidgets version: "));
1218 wxPlatformInfo platforminfo = wxPlatformInfo::Get();
1221#ifndef __OCPN__ANDROID__
1222 os_name = platforminfo.GetOperatingSystemIdName();
1224 os_name = platforminfo.GetOperatingSystemFamilyName();
1227 wxString platform = os_name + _T(
" ") + platforminfo.GetArchName() + _T(
" ") +
1228 platforminfo.GetPortIdName();
1230 wxLogMessage(wxver + _T(
" ") + platform);
1232 ::wxGetOsVersion(&osMajor, &osMinor);
1233 wxString osVersionMsg;
1234 osVersionMsg.Printf(_T(
"OS Version reports as: %d.%d"), osMajor, osMinor);
1235 wxLogMessage(osVersionMsg);
1237 wxLogMessage(_T(
"MemoryStatus: mem_total: %d mb, mem_initial: %d mb"),
1238 g_mem_total / 1024, g_mem_initial / 1024);
1243 if (!detail->osd_names_like.empty())
1244 like0 = detail->osd_names_like[0].c_str();
1245 msgplat.Printf(
"OCPN_OSDetail: %s ; %s ; %s ; %s ; %s",
1246 detail->osd_arch.c_str(), detail->osd_name.c_str(),
1247 detail->osd_version.c_str(), detail->osd_ID.c_str(),
1249 wxLogMessage(msgplat);
1252 ::wxInitAllImageHandlers();
1254 wxString imsg = _T(
"SData_Locn is ");
1255 imsg += g_Platform->GetSharedDataDir();
1260 prepareAndroidStyleSheets();
1264 pInit_Chart_Dir =
new wxString();
1267 g_pGroupArray =
new ChartGroupArray;
1269 imsg = _T(
"PrivateDataDir is ");
1270 imsg += g_Platform->GetPrivateDataDir();
1275 pMessageOnceArray =
new wxArrayString;
1280 ctx.SetRouteAndUpdate = [&](
Route* r) {
1281 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1282 pRoutePropDialog->SetRouteAndUpdate(r,
true);
1286 if (pRoutePropDialog && pRoutePropDialog->IsShown()) {
1287 if (pRoutePropDialog->GetRoute() == r) {
1288 pRoutePropDialog->SetEnroutePoint(rt);
1292 ctx.Hide = [&](
Route* r) {
1293 if (pRoutePropDialog && (pRoutePropDialog->IsShown()) &&
1294 (r == pRoutePropDialog->GetRoute())) {
1295 pRoutePropDialog->Hide();
1298 auto RouteMgrDlgUpdateListCtrl = [&]() {
1299 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1300 pRouteManagerDialog->UpdateRouteListCtrl();
1303 g_pRouteMan =
new Routeman(ctx, RouteMgrDlgUpdateListCtrl);
1307 pSelect->SetSelectPixelRadius(12);
1310 pSelectTC =
new Select();
1312 pSelectTC->SetSelectPixelRadius(25);
1315 pSelectAIS =
new Select();
1316 pSelectAIS->SetSelectPixelRadius(12);
1320 g_pais_query_dialog_active = NULL;
1323 g_hostname = ::wxGetHostName();
1324 if(g_hostname.IsEmpty())
1325 g_hostname = wxGetUserName();
1329 wxString p(
"Portable-");
1330 g_hostname = p + g_hostname;
1336 pLayerList =
new LayerList;
1338 pRouteList =
new RouteList;
1345#ifdef PROBE_PORTS__WITH_HELPER
1346 user_user_id = getuid();
1347 file_user_id = geteuid();
1351 bool b_initial_load =
false;
1353 wxFileName config_test_file_name(g_Platform->GetConfigFileName());
1354 if (config_test_file_name.FileExists())
1355 wxLogMessage(_T(
"Using existing Config_File: ") +
1356 g_Platform->GetConfigFileName());
1359 wxLogMessage(_T(
"Creating new Config_File: ") +
1360 g_Platform->GetConfigFileName());
1362 b_initial_load =
true;
1365 config_test_file_name.DirExists(config_test_file_name.GetPath()))
1366 if (!config_test_file_name.Mkdir(config_test_file_name.GetPath()))
1367 wxLogMessage(_T(
"Cannot create config file directory for ") +
1368 g_Platform->GetConfigFileName());
1373 pConfig = g_Platform->GetConfigObject();
1374 InitBaseConfig(pConfig);
1375 pConfig->LoadMyConfig();
1379 if (b_initial_load) g_Platform->SetDefaultOptions();
1381 g_Platform->applyExpertMode(g_bUIexpert);
1389 g_StyleManager->SetStyle(_T(
"MUI_flat"));
1390 if (!g_StyleManager->IsOK()) {
1391 wxString msg = _(
"Failed to initialize the user interface. ");
1392 msg << _(
"OpenCPN cannot start. ");
1393 msg << _(
"The necessary configuration files were not found. ");
1394 msg << _(
"See the log file at ") << g_Platform->GetLogFileName()
1395 << _(
" for details.") << _T(
"\n\n");
1396 msg << g_Platform->GetSharedDataDir();
1398 wxMessageDialog w(NULL, msg, _(
"Failed to initialize the user interface. "),
1399 wxCANCEL | wxICON_ERROR);
1406 if (style) style->chartStatusWindowTransparent =
true;
1410 pWayPointMan = NULL;
1412 g_display_size_mm = wxMax(100, g_Platform->GetDisplaySizeMM());
1414 msg.Printf(_T(
"Detected display size (horizontal): %d mm"),
1415 (
int)g_display_size_mm);
1419 if ((g_config_display_size_mm > 0) && (g_config_display_size_manual)) {
1420 g_display_size_mm = g_config_display_size_mm;
1422 msg.Printf(_T(
"Display size (horizontal) config override: %d mm"),
1423 (
int)g_display_size_mm);
1425 g_Platform->SetDisplaySizeMM(g_display_size_mm);
1428 g_display_size_mm = wxMax(80, g_display_size_mm);
1431 int SelectPixelRadius = 50;
1433 pSelect->SetSelectPixelRadius(SelectPixelRadius);
1434 pSelectTC->SetSelectPixelRadius(wxMax(25, SelectPixelRadius));
1435 pSelectAIS->SetSelectPixelRadius(SelectPixelRadius);
1439 if (!n_NavMessageShown) g_bFirstRun =
true;
1444#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
1447 g_Platform->SetLocaleSearchPrefixes();
1449 wxString def_lang_canonical = g_Platform->GetDefaultSystemLocale();
1451 imsg = _T(
"System default Language: ") + def_lang_canonical;
1454 wxString cflmsg = _T(
"Config file language: ") + g_locale;
1455 wxLogMessage(cflmsg);
1458 g_locale = g_Platform->GetAdjustedAppLocale();
1459 cflmsg = _T(
"Adjusted App language: ") + g_locale;
1460 wxLogMessage(cflmsg);
1463 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
1465 imsg = _T(
"Opencpn language set to: ");
1472 if (g_locale == _T(
"fr_FR")) g_b_assume_azerty =
true;
1474 wxLogMessage(_T(
"wxLocale support not available"));
1481 wxString vs = wxString(
"Version ") + VERSION_FULL +
" Build " + VERSION_DATE;
1482 g_bUpgradeInProcess = (vs != g_config_version_string);
1484 g_Platform->SetUpgradeOptions(vs, g_config_version_string);
1487 if (!g_Platform->GetLargeLogMessage().IsEmpty())
1488 wxLogMessage(g_Platform->GetLargeLogMessage());
1494#if !wxCHECK_VERSION( \
1497 if ( !g_bdisable_opengl) {
1498 wxFileName fn(g_Platform->GetExePath());
1499 bool b_test_result = TestGLCanvas(fn.GetPathWithSep());
1502 wxLogMessage(_T(
"OpenGL disabled due to test app failure."));
1504 g_bdisable_opengl = !b_test_result;
1510 g_bdisable_opengl =
true;
1514 if (g_bdisable_opengl) g_bopengl =
false;
1516#if defined(__UNIX__) && !defined(__OCPN__ANDROID__) && !defined(__WXOSX__)
1517 if (g_bSoftwareGL) setenv(
"LIBGL_ALWAYS_SOFTWARE",
"1", 1);
1529 if (0 == g_memCacheLimit) g_memCacheLimit = (int)(g_mem_total * 0.5);
1531 wxMin(g_memCacheLimit, 1024 * 1024);
1537 g_memCacheLimit = 0;
1538 if (0 == g_nCacheLimit)
1539 g_nCacheLimit = CACHE_N_LIMIT_DEFAULT;
1543 ChartListFileName = newPrivateFileName(g_Platform->GetPrivateDataDir(),
1544 "chartlist.dat",
"CHRTLIST.DAT");
1547 AISTargetNameFileName = newPrivateFileName(g_Platform->GetPrivateDataDir(),
1548 "mmsitoname.csv",
"MMSINAME.CSV");
1551 if (pInit_Chart_Dir->IsEmpty()) {
1552 wxStandardPaths &std_path = g_Platform->GetStdPaths();
1555#ifndef __OCPN__ANDROID__
1556 pInit_Chart_Dir->Append(std_path.GetDocumentsDir());
1558 pInit_Chart_Dir->Append(androidGetExtStorageDir());
1563 gDefaultWorldMapLocation =
"gshhs";
1564 gDefaultWorldMapLocation.Prepend(g_Platform->GetSharedDataDir());
1565 gDefaultWorldMapLocation.Append(wxFileName::GetPathSeparator());
1566 if (gWorldMapLocation == wxEmptyString) {
1567 gWorldMapLocation = gDefaultWorldMapLocation;
1572 wxString default_tcdata0 =
1573 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1574 wxFileName::GetPathSeparator() + _T(
"harmonics-dwf-20210110-free.tcd"));
1575 wxString default_tcdata1 =
1576 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1577 wxFileName::GetPathSeparator() + _T(
"HARMONICS_NO_US.IDX"));
1579 if (!TideCurrentDataSet.GetCount()) {
1580 TideCurrentDataSet.Add(g_Platform->NormalizePath(default_tcdata0));
1581 TideCurrentDataSet.Add(g_Platform->NormalizePath(default_tcdata1));
1583 wxString first_tide = TideCurrentDataSet[0];
1584 wxFileName ft(first_tide);
1585 if (!ft.FileExists()) {
1586 TideCurrentDataSet.RemoveAt(0);
1587 TideCurrentDataSet.Insert(g_Platform->NormalizePath(default_tcdata0), 0);
1588 TideCurrentDataSet.Add(g_Platform->NormalizePath(default_tcdata1));
1594 if (g_sAIS_Alert_Sound_File.IsEmpty()) {
1595 wxString default_sound =
1596 (g_Platform->GetSharedDataDir() + _T(
"sounds") +
1597 wxFileName::GetPathSeparator() + _T(
"2bells.wav"));
1598 g_sAIS_Alert_Sound_File = g_Platform->NormalizePath(default_sound);
1604 g_Platform->Initialize_2();
1608 wxSize new_frame_size(-1, -1);
1610 ::wxClientDisplayRect(&cx, &cy, &cw, &ch);
1612 InitializeUserColors();
1614 auto style = g_StyleManager->GetCurrentStyle();
1615 auto bitmap =
new wxBitmap(style->GetIcon(
"default_pi", 32, 32));
1617 PluginLoader::getInstance()->SetPluginDefaultIcon(bitmap);
1619 wxLogWarning(
"Cannot initiate plugin default jigsaw icon.");
1622 if ((g_nframewin_x > 100) && (g_nframewin_y > 100) && (g_nframewin_x <= cw) &&
1623 (g_nframewin_y <= ch))
1624 new_frame_size.Set(g_nframewin_x, g_nframewin_y);
1626 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1632 if ((g_lastClientRectx != cx) || (g_lastClientRecty != cy) ||
1633 (g_lastClientRectw != cw) || (g_lastClientRecth != ch)) {
1634 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1635 g_bframemax =
false;
1638 g_lastClientRectx = cx;
1639 g_lastClientRecty = cy;
1640 g_lastClientRectw = cw;
1641 g_lastClientRecth = ch;
1644 wxPoint position(0, 0);
1645 wxSize dsize = wxGetDisplaySize();
1648 g_nframewin_posy = wxMax(g_nframewin_posy, 22);
1651 if ((g_nframewin_posx < dsize.x) && (g_nframewin_posy < dsize.y))
1652 position = wxPoint(g_nframewin_posx, g_nframewin_posy);
1657 frame_rect.left = position.x;
1658 frame_rect.top = position.y;
1659 frame_rect.right = position.x + new_frame_size.x;
1660 frame_rect.bottom = position.y + new_frame_size.y;
1664 if (NULL == MonitorFromRect(&frame_rect, MONITOR_DEFAULTTONULL))
1665 position = wxPoint(10, 10);
1668#ifdef __OCPN__ANDROID__
1669 wxSize asz = getAndroidDisplayDimensions();
1674 if ((cw > 200) && (ch > 200))
1675 new_frame_size.Set(cw, ch);
1677 new_frame_size.Set(800, 400);
1681 long app_style = wxDEFAULT_FRAME_STYLE;
1682 app_style |= wxWANTS_CHARS;
1685 wxString myframe_window_title = wxString::Format(wxT(
"OpenCPN %s"),
1689 myframe_window_title += _(
" -- [Portable(-p) executing from ");
1690 myframe_window_title += g_Platform->GetHomeDir();
1691 myframe_window_title += _T(
"]");
1695 fmsg.Printf(_T(
"Creating MyFrame...size(%d, %d) position(%d, %d)"),
1696 new_frame_size.x, new_frame_size.y, position.x, position.y);
1699 gFrame =
new MyFrame(NULL, myframe_window_title, position, new_frame_size,
1703 g_Platform->Initialize_3();
1710 g_pauidockart =
new wxAuiDefaultDockArt;
1711 g_pauimgr->SetArtProvider(g_pauidockart);
1712 g_pauimgr->SetDockSizeConstraint(.9, .9);
1716 g_grad_default = g_pauidockart->GetMetric(wxAUI_DOCKART_GRADIENT_TYPE);
1717 g_border_color_default =
1718 g_pauidockart->GetColour(wxAUI_DOCKART_BORDER_COLOUR);
1719 g_border_size_default =
1720 g_pauidockart->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE);
1721 g_sash_size_default = g_pauidockart->GetMetric(wxAUI_DOCKART_SASH_SIZE);
1722 g_caption_color_default =
1723 g_pauidockart->GetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR);
1724 g_sash_color_default = g_pauidockart->GetColour(wxAUI_DOCKART_SASH_COLOUR);
1725 g_background_color_default =
1726 g_pauidockart->GetColour(wxAUI_DOCKART_BACKGROUND_COLOUR);
1729 g_pauimgr->SetManagedWindow(gFrame);
1731 gFrame->CreateCanvasLayout();
1735 gFrame->SetChartUpdatePeriod();
1739 gFrame->GetPrimaryCanvas()->SetFocus();
1741 pthumbwin =
new ThumbWin(gFrame->GetPrimaryCanvas());
1743 gFrame->ApplyGlobalSettings(
false);
1745 gFrame->SetAllToolbarScale();
1751 gFrame->SetAndApplyColorScheme(global_color_scheme);
1753 if (g_bframemax) gFrame->Maximize(
true);
1755#ifdef __OCPN__ANDROID__
1756 if (g_bresponsive && (gFrame->GetPrimaryCanvas()->GetPixPerMM() > 4.0))
1757 gFrame->Maximize(
true);
1764 ArrayOfCDI ChartDirArray;
1765 pConfig->LoadChartDirArray(ChartDirArray);
1770 if (g_bFirstRun && (ChartDirArray.GetCount() == 0)) {
1773 wxRegKey RegKey(wxString(_T(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\OpenCPN")));
1774 if (RegKey.Exists()) {
1776 _(
"Retrieving initial Chart Directory set from Windows Registry"));
1778 RegKey.QueryValue(wxString(_T(
"ChartDirs")), dirs);
1780 wxStringTokenizer tkz(dirs, _T(
";"));
1781 while (tkz.HasMoreTokens()) {
1782 wxString token = tkz.GetNextToken();
1785 cdi.fullpath = token.Trim();
1786 cdi.magic_number = _T(
"");
1788 ChartDirArray.Add(cdi);
1795 cdi.fullpath = _T(
"charts");
1796 cdi.fullpath.Prepend(g_Platform->GetSharedDataDir());
1797 cdi.magic_number = _T(
"");
1798 ChartDirArray.Add(cdi);
1802 if (ndirs) pConfig->UpdateChartDirs(ChartDirArray);
1812 if (!ChartDirArray.GetCount())
1813 if (::wxFileExists(ChartListFileName)) ::wxRemoveFile(ChartListFileName);
1817 if (!ChartData->LoadBinary(ChartListFileName, ChartDirArray)) {
1818 g_bNeedDBUpdate =
true;
1822 if (g_restore_dbindex >= 0) {
1823 if (ChartData->GetChartTableEntries() == 0)
1824 g_restore_dbindex = -1;
1826 else if (g_restore_dbindex > (ChartData->GetChartTableEntries() - 1))
1827 g_restore_dbindex = 0;
1831 ChartData->ApplyGroupArray(g_pGroupArray);
1839 if (g_rebuild_gl_cache && g_bopengl && g_GLOptions.m_bTextureCompression &&
1840 g_GLOptions.m_bTextureCompressionCaching) {
1841 gFrame->ReloadAllVP();
1850 if (g_glTextureManager) g_glTextureManager->BuildCompressedCache();
1860 if ((gps_watchdog_timeout_ticks > 60) || (gps_watchdog_timeout_ticks <= 0))
1861 gps_watchdog_timeout_ticks = (GPS_TIMEOUT_SECONDS * 1000) / TIMER_GFRAME_1;
1864 dogmsg.Printf(_T(
"GPS Watchdog Timeout is: %d sec."),
1865 gps_watchdog_timeout_ticks);
1866 wxLogMessage(dogmsg);
1868 sat_watchdog_timeout_ticks = gps_watchdog_timeout_ticks;
1876 if (g_bTrackCarryOver) g_bDeferredStartTrack =
true;
1878 pAnchorWatchPoint1 = NULL;
1879 pAnchorWatchPoint2 = NULL;
1883 gFrame->DoChartUpdate();
1888 gFrame->ReloadAllVP();
1890 gFrame->Refresh(
false);
1893 gFrame->GetPrimaryCanvas()->Enable();
1894 gFrame->GetPrimaryCanvas()->SetFocus();
1901 if (!g_bdisable_opengl) {
1905 (pgl->GetRendererString().Find(_T(
"UniChrome")) != wxNOT_FOUND)) {
1906 gFrame->m_defer_size = gFrame->GetSize();
1907 gFrame->SetSize(gFrame->m_defer_size.x - 10, gFrame->m_defer_size.y);
1908 g_pauimgr->Update();
1909 gFrame->m_bdefer_resize =
true;
1914 if (g_start_fullscreen) gFrame->ToggleFullScreen();
1916#ifdef __OCPN__ANDROID__
1919 gFrame->SetSize(getAndroidDisplayDimensions());
1920 androidSetFollowTool(gFrame->GetPrimaryCanvas()->m_bFollow ? 1 : 0,
true);
1924 gFrame->GetPrimaryCanvas()->Enable();
1925 gFrame->GetPrimaryCanvas()->SetFocus();
1933 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
1936 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
1941 OCPNPlatform::Initialize_4();
1943#ifdef __OCPN__ANDROID__
1944 androidHideBusyIcon();
1947 wxString::Format(_(
"OpenCPN Initialized in %ld ms."), init_sw.Time()));
1951#ifdef __OCPN__ANDROID__
1955 if (!n_NavMessageShown || (vs != g_config_version_string) ||
1956 (g_AndroidVersionCode != androidGetVersionCode())) {
1968 n_NavMessageShown = 1;
1972 g_AndroidVersionCode = androidGetVersionCode();
1973 qDebug() <<
"Persisting Version Code: " << g_AndroidVersionCode;
1978 if (!n_NavMessageShown || (vs != g_config_version_string)) {
1981 n_NavMessageShown = 1;
1987 g_bHasHwClock =
true;
1988#if defined(__UNIX__) && !defined(__OCPN__ANDROID__)
1991 ((stat(
"/dev/rtc", &buffer) == 0) || (stat(
"/dev/rtc0", &buffer) == 0) ||
1992 (stat(
"/dev/misc/rtc", &buffer) == 0));
1995 g_config_version_string = vs;
1998 pConfig->UpdateSettings();
2001 gFrame->InitTimer.Start(5, wxTIMER_CONTINUOUS);
2003 g_pauimgr->Update();
2005#if defined(__linux__) && !defined(__OCPN__ANDROID__)
2006 for (
size_t i = 0; i < TheConnectionParams()->Count(); i++) {
2009 if (cp->GetDSPort().Contains(_T(
"Serial"))) {
2010 std::string port(cp->Port.ToStdString());
2011 CheckSerialAccess(gFrame, port);
2015 CheckDongleAccess(gFrame);
2019 m_comm_bridge.Initialize();
2021 std::vector<std::string> ipv4_addrs = get_local_ipv4_addresses();
2024 if (ipv4_addrs.size()) {
2025 std::string ipAddr = ipv4_addrs[0];
2027 wxString data_dir = g_Platform->GetPrivateDataDir();
2028 if (data_dir.Last() != wxFileName::GetPathSeparator())
2029 data_dir.Append(wxFileName::GetPathSeparator());
2031 make_certificate(ipAddr, data_dir.ToStdString());
2033 m_RESTserver.StartServer(data_dir.ToStdString());
2035 StartMDNSService(g_hostname.ToStdString(),
"opencpn-object-control-service", 8000);
2041int MyApp::OnExit() {
2042 wxLogMessage(_T(
"opencpn::MyApp starting exit."));
2046 wxDateTime lognow = wxDateTime::Now();
2048 wxString day = lognow.FormatISODate();
2049 wxString utc = lognow.FormatISOTime();
2050 wxString navmsg = _T(
"LOGBOOK: ");
2054 navmsg += _T(
" UTC ");
2058 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f "), gLat, gLon);
2062 if (std::isnan(gCog))
2063 cog.Printf(_T(
"COG ----- "));
2065 cog.Printf(_T(
"COG %10.5f "), gCog);
2068 if (std::isnan(gSog))
2069 sog.Printf(_T(
"SOG ----- "));
2071 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
2078 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f"), gLat, gLon);
2081 wxLogMessage(navmsg);
2082 g_loglast_time = lognow;
2084 if (ptcmgr)
delete ptcmgr;
2093 if (g_pGroupArray) {
2094 for (
unsigned int igroup = 0; igroup < g_pGroupArray->GetCount();
2096 delete g_pGroupArray->Item(igroup);
2099 g_pGroupArray->Clear();
2100 delete g_pGroupArray;
2103 wxLogMessage(_T(
"opencpn::MyApp exiting cleanly...\n"));
2104 wxLog::FlushActive();
2106 g_Platform->CloseLogFile();
2108 delete pInit_Chart_Dir;
2110 for (
Track* track : g_TrackList) {
2113 g_TrackList.clear();
2116 delete pWayPointMan;
2118 delete pMessageOnceArray;
2120 DeInitializeUserColors();
2124 delete m_pRegistrarMan;
2127 delete g_StyleManager;
2132 if (s_glu_dll_ready) FreeLibrary(s_hGLU_DLL);
2141void RestoreSystemColors(
void);
2142 RestoreSystemColors();
2149#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
2150 delete plocale_def_lang;
2153 FontMgr::Shutdown();
2157 g_Platform->OnExit_2();
2163#ifdef LINUX_CRASHRPT
2164void MyApp::OnFatalException() { g_crashprint.Report(); }
2167Track* MyApp::TrackOff(
void) {
2169 return gFrame->TrackOff();
2174#include <wx/power.h>
2189void MyCPLErrorHandler(CPLErr eErrClass,
int nError,
const char *pszErrorMsg)
2194 if (eErrClass == CE_Debug)
2195 snprintf(msg, 255,
"CPL: %s", pszErrorMsg);
2196 else if (eErrClass == CE_Warning)
2197 snprintf(msg, 255,
"CPL Warning %d: %s", nError, pszErrorMsg);
2199 snprintf(msg, 255,
"CPL ERROR %d: %s", nError, pszErrorMsg);
2201 wxString str(msg, wxConvUTF8);
s57RegistrarMgr Definition This is a class holding the ctor and dtor for the global registrar
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.