├── .circleci └── config.yml ├── .clang-format ├── .cmake-format.yaml ├── .editorconfig ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── appveyor.yml ├── bld.bat ├── build-deps ├── macos-cache-stamp └── macos-deps ├── build-local-package-example.sh ├── buildosx └── InstallOSX │ ├── pkg_background.jpg │ └── plugin.pkgproj.in ├── ci ├── circleci-build-android-arm64.sh ├── circleci-build-android-armhf.sh ├── circleci-build-debian.sh ├── circleci-build-fedora.sh ├── circleci-build-flatpak.sh ├── circleci-build-jammy.sh ├── circleci-build-macos-universal.sh ├── circleci-build-macos.sh ├── circleci-build-mingw.sh ├── circleci-build-msvc.bat ├── circleci-build-ubuntu-docker.sh ├── cloudsmith-upload.sh ├── control ├── extras │ ├── README.txt │ ├── circleci-build-flatpak_extra_libs.txt │ └── extra_libs.txt ├── opencpn-deps.spec └── opencpn-fedora.spec ├── cmake ├── FindGTK3.cmake ├── MacosWxwidgets.cmake ├── PluginConfigure.cmake ├── PluginInstall.cmake ├── PluginLocalization.cmake ├── PluginPackage.cmake ├── PluginSetup.cmake ├── android-aarch64-toolchain.cmake ├── android-armhf-toolchain.cmake ├── fix-macos-libs.sh ├── gpl.txt ├── in-files │ ├── NSIS.template.in │ ├── PluginCPackOptions.cmake.in │ ├── cloudsmith-upload.sh.in │ ├── flatpak_args.in │ ├── flatpak_extra_modules.in │ ├── flatpak_options.in │ ├── org.opencpn.OpenCPN.Plugin.yaml.in │ ├── pkg_version.sh.in │ ├── plugin.xml.in │ ├── readme.txt │ ├── version.h.in │ └── wxWTranslateCatalog.h.in └── readme.txt ├── data ├── boat-blue.svg ├── boat-cyan.svg ├── boat-green.svg ├── boat-grey.svg ├── boat-red.svg ├── boat-single.-whitesvg.svg ├── boat-white.svg ├── boat-yellow.svg ├── pypilot-old.svg ├── pypilot.svg ├── pypilot_panel.png ├── pypilot_panel.svg ├── pypilot_rollover.svg └── pypilot_toggled.svg ├── libs └── wxservdisc │ ├── AUTHORS │ ├── CMakeLists.txt │ ├── COPYING │ ├── NEWS │ ├── README.md │ └── src │ ├── 1035.c │ ├── 1035.h │ ├── CMakeLists.txt │ ├── Makefile.am │ ├── README.mdnsd │ ├── TODO.mdnsd │ ├── mdnsd.c │ ├── mdnsd.h │ ├── wxServDisc.cpp │ └── wxServDisc.h ├── manual ├── .gitignore ├── antora.yml ├── modules │ └── ROOT │ │ ├── images │ │ ├── pypilot-menus.png │ │ ├── pypilot_icon.png │ │ └── pypilot_plugin_screenshot.png │ │ └── pages │ │ └── index.adoc └── site.yml ├── mingw ├── fedora │ ├── README.md │ ├── opencpn-deps.spec │ └── toolchain.cmake └── readme.txt ├── msvc └── win_deps.bat ├── po ├── POTFILES.in ├── POTFILES.in.test ├── ar_SA.po ├── bg_BG.po ├── ca_ES.po ├── cs_CZ.po ├── da_DK.po ├── de_DE.po ├── el_GR.po ├── en_GB.po ├── es_ES.po ├── et_EE.po ├── fi_FI.po ├── fil_PH.po ├── fr_FR.po ├── gl_ES.po ├── he_IL.po ├── hi_IN.po ├── hu_HU.po ├── id_ID.po ├── is_IS.po ├── it_IT.po ├── ja_JP.po ├── ko_KR.po ├── mr_IN.po ├── nb_NO.po ├── nl_NL.po ├── pl_PL.po ├── pt_BR.po ├── pt_PT.po ├── pypilot_pi.pot ├── ro_RO.po ├── ru_RU.po ├── sv_SE.po ├── th_TH.po ├── tr_TR.po ├── trans-po.py ├── translate.sh ├── vi_VN.po ├── zh_CN.po └── zh_TW.po ├── pypilot.fbp ├── run-circleci-local.txt ├── src ├── CalibrationDialog.cpp ├── CalibrationDialog.h ├── CalibrationPlot-sean.cpp ├── CalibrationPlot.cpp ├── CalibrationPlot.h ├── ConfigurationDialog.cpp ├── ConfigurationDialog.h ├── GainsDialog.cpp ├── GainsDialog.h ├── SettingsDialog.cpp ├── SettingsDialog.h ├── StatisticsDialog.cpp ├── StatisticsDialog.h ├── icons.cpp ├── icons.h ├── msvcdefs.h ├── pypilotClientDialog.cpp ├── pypilotClientDialog.h ├── pypilotDialog.cpp ├── pypilotDialog.h ├── pypilotUI.cpp ├── pypilotUI.h ├── pypilot_client.cpp ├── pypilot_client.h ├── pypilot_pi.cpp ├── pypilot_pi.h └── wxWTranslateCatalog.h └── update_submodule_branch.sh /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: Google 4 | # AccessModifierOffset: -1 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveMacros: false 7 | AlignConsecutiveAssignments: false 8 | AlignConsecutiveBitFields: false 9 | AlignConsecutiveDeclarations: false 10 | AlignEscapedNewlines: Left 11 | AlignOperands: Align 12 | AlignTrailingComments: true 13 | AllowAllArgumentsOnNextLine: true 14 | AllowAllConstructorInitializersOnNextLine: true 15 | AllowAllParametersOfDeclarationOnNextLine: true 16 | AllowShortEnumsOnASingleLine: true 17 | AllowShortBlocksOnASingleLine: Never 18 | AllowShortCaseLabelsOnASingleLine: false 19 | AllowShortFunctionsOnASingleLine: All 20 | AllowShortLambdasOnASingleLine: All 21 | AllowShortIfStatementsOnASingleLine: WithoutElse 22 | AllowShortLoopsOnASingleLine: true 23 | AlwaysBreakAfterDefinitionReturnType: None 24 | AlwaysBreakAfterReturnType: None 25 | AlwaysBreakBeforeMultilineStrings: true 26 | AlwaysBreakTemplateDeclarations: Yes 27 | BinPackArguments: true 28 | BinPackParameters: true 29 | BraceWrapping: 30 | AfterCaseLabel: false 31 | AfterClass: false 32 | AfterControlStatement: MultiLine 33 | AfterEnum: false 34 | AfterFunction: false 35 | AfterNamespace: false 36 | AfterObjCDeclaration: false 37 | AfterStruct: false 38 | AfterUnion: false 39 | AfterExternBlock: false 40 | BeforeCatch: false 41 | BeforeElse: false 42 | BeforeLambdaBody: false 43 | BeforeWhile: false 44 | IndentBraces: false 45 | SplitEmptyFunction: true 46 | SplitEmptyRecord: true 47 | SplitEmptyNamespace: true 48 | BreakBeforeBinaryOperators: None 49 | BreakBeforeBraces: Attach 50 | BreakBeforeInheritanceComma: false 51 | BreakInheritanceList: BeforeColon 52 | BreakBeforeTernaryOperators: true 53 | BreakConstructorInitializersBeforeComma: false 54 | BreakConstructorInitializers: BeforeColon 55 | BreakAfterJavaFieldAnnotations: false 56 | BreakStringLiterals: true 57 | ColumnLimit: 80 58 | CommentPragmas: '^ IWYU pragma:' 59 | CompactNamespaces: false 60 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 61 | ConstructorInitializerIndentWidth: 4 62 | ContinuationIndentWidth: 4 63 | Cpp11BracedListStyle: true 64 | DeriveLineEnding: true 65 | DerivePointerAlignment: false 66 | DisableFormat: false 67 | ExperimentalAutoDetectBinPacking: false 68 | FixNamespaceComments: true 69 | ForEachMacros: 70 | - foreach 71 | - Q_FOREACH 72 | - BOOST_FOREACH 73 | IncludeBlocks: Regroup 74 | IncludeCategories: 75 | - Regex: '^' 76 | Priority: 2 77 | SortPriority: 0 78 | - Regex: '^<.*\.h>' 79 | Priority: 1 80 | SortPriority: 0 81 | - Regex: '^<.*' 82 | Priority: 2 83 | SortPriority: 0 84 | - Regex: '.*' 85 | Priority: 3 86 | SortPriority: 0 87 | IncludeIsMainRegex: '([-_](test|unittest))?$' 88 | IncludeIsMainSourceRegex: '' 89 | IndentCaseLabels: true 90 | IndentCaseBlocks: false 91 | IndentGotoLabels: true 92 | IndentPPDirectives: None 93 | IndentExternBlock: AfterExternBlock 94 | IndentWidth: 2 95 | IndentWrappedFunctionNames: false 96 | InsertTrailingCommas: None 97 | JavaScriptQuotes: Leave 98 | JavaScriptWrapImports: true 99 | KeepEmptyLinesAtTheStartOfBlocks: false 100 | MacroBlockBegin: '' 101 | MacroBlockEnd: '' 102 | MaxEmptyLinesToKeep: 1 103 | NamespaceIndentation: None 104 | ObjCBinPackProtocolList: Never 105 | ObjCBlockIndentWidth: 2 106 | ObjCBreakBeforeNestedBlockParam: true 107 | ObjCSpaceAfterProperty: false 108 | ObjCSpaceBeforeProtocolList: true 109 | PenaltyBreakAssignment: 2 110 | PenaltyBreakBeforeFirstCallParameter: 1 111 | PenaltyBreakComment: 300 112 | PenaltyBreakFirstLessLess: 120 113 | PenaltyBreakString: 1000 114 | PenaltyBreakTemplateDeclaration: 10 115 | PenaltyExcessCharacter: 1000000 116 | PenaltyReturnTypeOnItsOwnLine: 200 117 | PointerAlignment: Left 118 | RawStringFormats: 119 | - Language: Cpp 120 | Delimiters: 121 | - cc 122 | - CC 123 | - cpp 124 | - Cpp 125 | - CPP 126 | - 'c++' 127 | - 'C++' 128 | CanonicalDelimiter: '' 129 | BasedOnStyle: google 130 | - Language: TextProto 131 | Delimiters: 132 | - pb 133 | - PB 134 | - proto 135 | - PROTO 136 | EnclosingFunctions: 137 | - EqualsProto 138 | - EquivToProto 139 | - PARSE_PARTIAL_TEXT_PROTO 140 | - PARSE_TEST_PROTO 141 | - PARSE_TEXT_PROTO 142 | - ParseTextOrDie 143 | - ParseTextProtoOrDie 144 | - ParseTestProto 145 | - ParsePartialTestProto 146 | CanonicalDelimiter: '' 147 | BasedOnStyle: google 148 | ReflowComments: true 149 | SortIncludes: false 150 | SortUsingDeclarations: true 151 | SpaceAfterCStyleCast: false 152 | SpaceAfterLogicalNot: false 153 | SpaceAfterTemplateKeyword: true 154 | SpaceBeforeAssignmentOperators: true 155 | SpaceBeforeCpp11BracedList: false 156 | SpaceBeforeCtorInitializerColon: true 157 | SpaceBeforeInheritanceColon: true 158 | SpaceBeforeParens: ControlStatements 159 | SpaceBeforeRangeBasedForLoopColon: true 160 | SpaceInEmptyBlock: false 161 | SpaceInEmptyParentheses: false 162 | SpacesBeforeTrailingComments: 2 163 | SpacesInAngles: false 164 | SpacesInConditionalStatement: false 165 | SpacesInContainerLiterals: true 166 | SpacesInCStyleCastParentheses: false 167 | SpacesInParentheses: false 168 | SpacesInSquareBrackets: false 169 | SpaceBeforeSquareBrackets: false 170 | Standard: Auto 171 | StatementMacros: 172 | - Q_UNUSED 173 | - QT_REQUIRE_VERSION 174 | TabWidth: 8 175 | UseCRLF: false 176 | UseTab: Never 177 | WhitespaceSensitiveMacros: 178 | - STRINGIZE 179 | - PP_STRINGIZE 180 | - BOOST_PP_STRINGIZE 181 | ... 182 | 183 | -------------------------------------------------------------------------------- /.cmake-format.yaml: -------------------------------------------------------------------------------- 1 | additional_commands: 2 | foo: 3 | flags: 4 | - BAR 5 | - BAZ 6 | kwargs: 7 | DEPENDS: '*' 8 | HEADERS: '*' 9 | SOURCES: '*' 10 | algorithm_order: 11 | - 0 12 | - 1 13 | - 2 14 | - 3 15 | always_wrap: [] 16 | bullet_char: '-' 17 | command_case: lower 18 | dangle_parens: true 19 | emit_byteorder_mark: false 20 | enable_markup: true 21 | enum_char: . 22 | #fence_pattern: ^\s*([`~]{3}[`~]*)(.*)$ 23 | first_comment_is_literal: false 24 | keyword_case: unchanged 25 | line_ending: unix 26 | line_width: 80 27 | literal_comment_pattern: null 28 | max_subargs_per_line: 3 29 | per_command: {} 30 | #ruler_pattern: ^\s*[^\w\s]{3}.*[^\w\s]{3}$ 31 | separate_ctrl_name_with_space: true 32 | separate_fn_name_with_space: false 33 | tab_size: 2 34 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # For information on this file see: https://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | 9 | [*.{xml}] 10 | charset = utf-8 11 | 12 | [*.{cmake,cpp,h,sh,in,yml,xsd}] 13 | charset = latin1 14 | indent_style = space 15 | indent_size = 4 16 | trim_trailing_whitespace = true 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | cmake-build* 2 | build/* 3 | .idea* 4 | .directory 5 | po/POTFILES.in.test 6 | temp 7 | tmp 8 | master.zip 9 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "opencpn-libs"] 2 | path = opencpn-libs 3 | url = https://github.com/OpenCPN/opencpn-libs.git 4 | branch = main 5 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | clone_folder: c:\project\ocpn_project 2 | shallow_clone: false 3 | clone_depth: 10 4 | 5 | 6 | platform: 7 | # - x64 8 | # - Win32 9 | 10 | configuration: Release 11 | test: OFF 12 | 13 | environment: 14 | OCPN_TARGET: MSVC 15 | 16 | # use enviornment matrix with job_name to allow build of one or more environments 17 | matrix: 18 | - job_name: Visual Studio 2017 19 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 20 | 21 | ## This can be built in Circleci and is currently the FE2 default 22 | ## 23 | # - job_name: Visual Studio 2022 24 | # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 25 | 26 | 27 | matrix: 28 | # allow either job to fail and the other to complete 29 | fast_finish: false 30 | 31 | init: 32 | - appveyor version 33 | 34 | for: 35 | - 36 | matrix: 37 | only: 38 | - job_name: Visual Studio 2017 39 | install: 40 | - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat" 41 | - set WX_VER= 42 | - set WXWIN=c:\wxWidgets-3.1.2 43 | - set wxWidgets_ROOT_DIR=%WXWIN% 44 | - set wxWidgets_LIB_DIR=%WXWIN%\lib\vc_dll 45 | - set cmake_parms=-T v141_xp 46 | - SET PATH=%PATH%;%WXWIN%;%wxWidgets_LIB_DIR%;C:\Program Files (x86)\Poedit\Gettexttools\bin 47 | 48 | # install dependencies: 49 | - choco install poedit 50 | - choco install git 51 | 52 | - ps: Start-FileDownload https://download.opencpn.org/s/54HsBDLNzRZLL6i/download -FileName nsis-3.04-setup.exe 53 | - cmd: nsis-3.04-setup.exe /S 54 | 55 | # Download and unzip wxwidgets 56 | - ps: Start-FileDownload https://download.opencpn.org/s/E2p4nLDzeqx4SdX/download -FileName wxWidgets-3.1.2.7z 57 | - cmd: 7z x wxWidgets-3.1.2.7z -o%WXWIN% > null 58 | 59 | - 60 | matrix: 61 | only: 62 | - job_name: Visual Studio 2022 63 | install: 64 | - call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars32.bat" 65 | - set WX_VER=32 66 | - set WXWIN=C:\wxWidgets-3.2.1 67 | - set wxWidgets_ROOT_DIR=%WXWIN% 68 | - set wxWidgets_LIB_DIR=%WXWIN%\lib\vc_dll 69 | - set cmake_parms=-A Win32 70 | - SET PATH=%PATH%;%WXWIN%;%wxWidgets_LIB_DIR%;C:\Program Files\Poedit\Gettexttools\bin 71 | 72 | # install dependencies: 73 | - choco install poedit 74 | - choco install git 75 | - choco install wget 76 | 77 | # Download and unzip wxwidgets 78 | - wget -nv https://github.com/wxWidgets/wxWidgets/releases/download/v3.2.1/wxMSW-3.2.1_vc14x_Dev.7z 79 | - wget -nv https://github.com/wxWidgets/wxWidgets/releases/download/v3.2.1/wxWidgets-3.2.1-headers.7z 80 | - 7z x -o%WXWIN% wxMSW-3.2.1_vc14x_Dev.7z 81 | - 7z x -o%WXWIN% wxWidgets-3.2.1-headers.7z 82 | 83 | before_build: 84 | - cd c:\project\ocpn_project 85 | - git submodule update --init opencpn-libs 86 | - ps: Start-FileDownload https://downloads.sourceforge.net/project/opencpnplugins/opencpn_packaging_data/PVW32Con.exe 87 | - rm -rf build && mkdir build && cd build 88 | - ps: Start-FileDownload https://sourceforge.net/projects/opencpnplugins/files/opencpn.lib 89 | - ps: Start-FileDownload https://download.opencpn.org/s/oibxM3kzfzKcSc3/download -FileName OpenCPN_buildwin-4.99a.7z 90 | - cmd: 7z x -y OpenCPN_buildwin-4.99a.7z -oc:\project\ocpn_project\buildwin 91 | - cmake %cmake_parms% .. 92 | 93 | build_script: 94 | - cmake --build . --target package --config Release 95 | - python -m ensurepip 96 | - python -m pip install -q setuptools 97 | - python -m pip install -q cloudsmith-cli 98 | - bash ../build/cloudsmith-upload.sh 99 | 100 | artifacts: 101 | - path: 'build\*.exe' 102 | name: installer 103 | -------------------------------------------------------------------------------- /bld.bat: -------------------------------------------------------------------------------- 1 | REM FE2 Testplugin 2 | 3 | 4 | REM Requires wxWidgets setup 5 | REM C:\Users\fcgle\source\wxWidgets-3.1.2 6 | REM C:\Users\fcgle\source\wxWidgets-3.2.2 7 | REM Visual Studio 15 2017 installed 8 | REM Visual Studio 17 2022 installed 9 | REM -------------------------------------- 10 | REM For Opencpn 5.8 and wxWidgets-3.2.2 using Visual Studio 15 2017 11 | REM -------------------------------------- 12 | REM Used for local builds and testing. 13 | REM Create an empty "[plugin]/build" directory 14 | REM Use MSVC Command Prompt from [plugin]root directory ".\bld.bat" 15 | REM Find the errors in the build\output.txt file 16 | REM Then use bash prompt to run cloudsmith-upload.sh command "BASH ./bld.bat" 17 | REM This adds the metadata file to the tarball gz file. 18 | REM Set local environment using wxWidgets-3.2.2 19 | set "wxDIR=%WXWIN%" 20 | set "wxWidgets_ROOT_DIR=%WXWIN%" 21 | set "wxWidgets_LIB_DIR=%WXWIN%\lib\vc14x_dll" 22 | set "WXWIN=C:\Users\fcgle\source\wxWidgets-3.2.2" 23 | REM For Opencpn 5.8 and wxWidgets-3.2.2 24 | cd build 25 | cmake -T v143 -A Win32 -DOCPN_TARGET=MSVC .. 26 | cmake --build . --target package --config relwithdebinfo >output.txt 27 | bash ./cloudsmith-upload.sh 28 | 29 | REM -------------------------------------- 30 | REM For Opencpn 5.6.2 and wxWidgets-3.1.2 release 31 | REM -------------------------------------- 32 | REM Using built C:\Users\fcgle\source\wxWidgets-3.1.2 and local settings 33 | REM set "wxDIR=%WXWIN%" 34 | REM set "wxWidgets_ROOT_DIR=%WXWIN%" 35 | REM set "wxWidgets_LIB_DIR=%WXWIN%\lib\vc14x_dll" 36 | REM set "WXWIN=C:\Users\fcgle\source\wxWidgets-3.1.2" 37 | REM cd build 38 | REM cmake -T v141_xp -DOCPN_TARGET=MSVC .. 39 | REM cmake --build . --target package --config release >output.txt 40 | REM bash ./cloudsmith-upload.sh 41 | 42 | REM -------------------------------------- 43 | REM For Opencpn 5.8 and wxWidgets-3.2.2 using Visual Studio 15 2017 44 | REM -------------------------------------- 45 | REM Using built C:\Users\fcgle\source\wxWidgets-3.2.2 and local settings 46 | REM set "wxDIR=%WXWIN%" 47 | REM set "wxWidgets_LIB_DIR=%WXWIN%\lib\vc14x_dll" 48 | REM set "WXWIN=C:\Users\fcgle\source\wxWidgets-3.2.2" 49 | REM cd build 50 | REM cmake -T v141_xp -G -DOCPN_TARGET=MSVC "Visual Studio 15 2017" 51 | REM -DCMAKE_BUILD_TYPE=RelWithDebInfo .. 52 | REM cmake --build . --target tarball --config RelWithDebInfo >output.txt 53 | REM bash ./cloudsmith-upload.sh 54 | 55 | REM -------------------------------------- 56 | REM For Opencpn 5.8.2 and wxWidgets-3.2.2 using Visual Studio 12 2022 57 | REM TransmitterDAN full Build in repos2 which executes win_deps.bat 58 | REM -------------------------------------- 59 | REM .\buildwin\win_deps.bat 60 | REM cd build 61 | REM cmake -T v143 -A Win32 -DOCPN_TARGET=MSVC "Visual Studio 17 2022" ^ 62 | REM -DCMAKE_BUILD_TYPE=RelWithDebInfo .. 63 | REM cmake --build . --target tarball --config RelWithDebInfo >output.txt 64 | 65 | REM Setup for wxWidgets 3.2.2 66 | REM wxWidgets_INCLUDE_DIRS %WXWIN%\include 67 | REM wxWidgets_LIB_DIR %WXWIN%\lib\vc_dll 68 | REM wxWidgets_LIBRARIES %WXWIN%\lib\vc_dll 69 | REM wxWidgets_ROOT_DIR %WXWIN% 70 | REM WXWIN C:\Users\fcgle\source\repos2\OpenCPN\cache\buildwxWidgets\ 71 | 72 | REM -------------------------------------- 73 | REM configdev58.bat by Rick for local builds. 74 | REM -------------------------------------- 75 | REM Can use "call configdev58.bat" in another batch file to set up local wxWidgets environment 76 | REM set "wxDIR=C:\Users\fcgle\source\repos2\OpenCPN\buildwin\..\cache\buildwxWidgets" 77 | REM set "wxWidgets_ROOT_DIR=C:\Users\fcgle\source\repos2\OpenCPN\buildwin\..\cache\buildwxWidgets" 78 | REM set "wxWidgets_LIB_DIR=C:\Users\fcgle\source\repos2\OpenCPN\buildwin\..\cache\buildwxWidgets\lib\vc_dll" 79 | -------------------------------------------------------------------------------- /build-deps/macos-cache-stamp: -------------------------------------------------------------------------------- 1 | # Any change in this file will cause the macos cache to be invalidated 2 | # i. e., that the homebrew dependencies are downloaded and wxwidgets 3 | # rebuilt. For example, change the stock 'v1' to 'v2' 4 | v1 5 | -------------------------------------------------------------------------------- /build-deps/macos-deps: -------------------------------------------------------------------------------- 1 | # brew packages installed in macos ci build 2 | cmake 3 | gettext 4 | libexif 5 | python 6 | wget 7 | openssl@3 8 | -------------------------------------------------------------------------------- /build-local-package-example.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This file should be run from the local build directory you want to use 3 | # This file is a modification of the 'circleci local' build process, so it will complain the circleci-output directory is not found. 4 | # If you want to do a 'circleci local' build use the 'run-circleci-local.txt' file as the example to follow. 5 | # 6 | # Change the exports to meet the build requirements, i.e. the values in the config.yml file relevant to the particular job 7 | export OCPN_TARGET=bookworm 8 | export BUILD_GTK3=true 9 | export WX_VER=32 10 | export LOCAL_DEPLOY=true 11 | # this removes old xml files from the build directory 12 | rm *.xml 13 | # the actual configuration, build and installable package creation 14 | cmake -DCMAKE_BUILD_TYPE=Debug .. 15 | make -j2 16 | make package 17 | chmod a+x cloudsmith-upload.sh 18 | ./cloudsmith-upload.sh 19 | 20 | -------------------------------------------------------------------------------- /buildosx/InstallOSX/pkg_background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypilot/pypilot_pi/cf25bb4e8167462fdc2882334c95dc9dee47ef4c/buildosx/InstallOSX/pkg_background.jpg -------------------------------------------------------------------------------- /ci/circleci-build-android-arm64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | 3 | # 4 | # Build the Android artifacts inside the circleci linux container 5 | # 6 | 7 | 8 | set -xe 9 | 10 | pwd 11 | 12 | git submodule update --init opencpn-libs 13 | 14 | ls -la 15 | 16 | # FOR LOCAL BUILD - have a local version to avoid big download each run - need to stage it but not commit it. DO NOT COMMIT AND PUSH master.zip 17 | if [ "${CIRCLECI_LOCAL,,}" = "true" ]; then 18 | if [[ -d ~/circleci-cache ]]; then 19 | if [[ -f ~/circleci-cache/apt-proxy ]]; then 20 | cat ~/circleci-cache/apt-proxy | sudo tee -a /etc/apt/apt.conf.d/00aptproxy 21 | cat /etc/apt/apt.conf.d/00aptproxy 22 | fi 23 | if [[ ! -f ~/circleci-cache/master.zip ]]; then 24 | sudo wget https://github.com/bdbcat/OCPNAndroidCommon/archive/master.zip -O ~/circleci-cache/master.zip 25 | fi 26 | MASTER_LOC=~/circleci-cache 27 | #unzip -qq -o /home/circleci/circleci-cache/master.zip 28 | fi 29 | else 30 | MASTER_LOC=$(pwd) 31 | wget https://github.com/bdbcat/OCPNAndroidCommon/archive/master.zip 32 | #unzip -qq -o master.zip 33 | fi 34 | echo "unzipping $MASTER_LOC/master.zip" 35 | 36 | unzip -qq -o $MASTER_LOC/master.zip 37 | 38 | sudo apt-get -q update 39 | sudo apt-get -y install git cmake gettext unzip 40 | 41 | # Install extra build libs 42 | ME=$(echo ${0##*/} | sed 's/\.sh//g') 43 | EXTRA_LIBS=./ci/extras/extra_libs.txt 44 | if test -f "$EXTRA_LIBS"; then 45 | while read line; do 46 | sudo apt-get install $line 47 | done < $EXTRA_LIBS 48 | fi 49 | EXTRA_LIBS=./ci/extras/${ME}_extra_libs.txt 50 | if test -f "$EXTRA_LIBS"; then 51 | while read line; do 52 | sudo apt-get install $line 53 | done < $EXTRA_LIBS 54 | fi 55 | 56 | pwd 57 | ls -la 58 | 59 | mkdir -p build 60 | cd build 61 | 62 | rm -f CMakeCache.txt 63 | 64 | # Install python to get a recent version of cmake 65 | sudo apt install python3-pip 66 | python3 -m pip install --user --force-reinstall -q pip setuptools 67 | sudo apt remove python3-six python3-colorama python3-urllib3 68 | export LC_ALL=C.UTF-8 LANG=C.UTF-8 69 | python3 -m pip install --user -q cmake -vv 70 | 71 | last_ndk=$(ls -d /home/circleci/android-sdk/ndk/* | tail -1) 72 | test -d /opt/android || sudo mkdir -p /opt/android 73 | sudo ln -sf $last_ndk /opt/android/ndk 74 | 75 | if [ ! -z "$(BUILD_TYPE)" ]; then 76 | tag=$(git tag --contains HEAD) 77 | current_branch=$(git branch --show-current) 78 | if [ -n "$tag" ] || [ "$current_branch" = "master" ]; then 79 | BUILD_TYPE=Release 80 | else 81 | BUILD_TYPE=Debug 82 | fi 83 | fi 84 | 85 | cmake -DCMAKE_TOOLCHAIN_FILE=cmake/android-aarch64-toolchain.cmake \ 86 | -D_wx_selected_config=androideabi-qt-arm64 \ 87 | -DwxQt_Build=build_android_release_64_static_O3 \ 88 | -DQt_Build=build_arm64/qtbase \ 89 | -DOCPN_Android_Common=OCPNAndroidCommon-master \ 90 | -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ 91 | .. 92 | 93 | make VERBOSE=1 94 | 95 | make package 96 | -------------------------------------------------------------------------------- /ci/circleci-build-android-armhf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | 3 | # 4 | # Build the Android artifacts inside the circleci linux container 5 | # 6 | 7 | set -xe 8 | 9 | pwd 10 | 11 | git submodule update --init opencpn-libs 12 | 13 | ls -la 14 | 15 | #sudo apt-get -q update 16 | #sudo apt-get -y install git cmake gettext unzip 17 | 18 | # Get the OCPN Android build support package. 19 | # FOR LOCAL BUILD - have a local version to avoid big download each run - need to stage it but not commit it. DO NOT COMMIT AND PUSH master.zip 20 | if [ "${CIRCLECI_LOCAL,,}" = "true" ]; then 21 | if [[ -d ~/circleci-cache ]]; then 22 | if [[ -f ~/circleci-cache/apt-proxy ]]; then 23 | cat ~/circleci-cache/apt-proxy | sudo tee -a /etc/apt/apt.conf.d/00aptproxy 24 | cat /etc/apt/apt.conf.d/00aptproxy 25 | fi 26 | if [[ ! -f ~/circleci-cache/master.zip ]]; then 27 | sudo wget https://github.com/bdbcat/OCPNAndroidCommon/archive/master.zip -O ~/circleci-cache/master.zip 28 | fi 29 | MASTER_LOC=~/circleci-cache 30 | #unzip -qq -o /home/circleci/circleci-cache/master.zip 31 | fi 32 | else 33 | MASTER_LOC=$(pwd) 34 | wget https://github.com/bdbcat/OCPNAndroidCommon/archive/master.zip 35 | #unzip -qq -o master.zip 36 | fi 37 | echo "unzipping $MASTER_LOC/master.zip" 38 | 39 | unzip -qq -o $MASTER_LOC/master.zip 40 | 41 | sudo apt-get -q update 42 | sudo apt-get -y install git cmake gettext unzip 43 | # Install extra build libs 44 | ME=$(echo ${0##*/} | sed 's/\.sh//g') 45 | EXTRA_LIBS=./ci/extras/extra_libs.txt 46 | if test -f "$EXTRA_LIBS"; then 47 | while read line; do 48 | sudo apt-get install $line 49 | done < $EXTRA_LIBS 50 | fi 51 | EXTRA_LIBS=./ci/extras/${ME}_extra_libs.txt 52 | if test -f "$EXTRA_LIBS"; then 53 | while read line; do 54 | sudo apt-get install $line 55 | done < $EXTRA_LIBS 56 | fi 57 | 58 | # Install extra build libs 59 | ME=$(echo ${0##*/} | sed 's/\.sh//g') 60 | EXTRA_LIBS=./ci/extras/extra_libs.txt 61 | if test -f "$EXTRA_LIBS"; then 62 | while read line; do 63 | sudo apt-get install $line 64 | done < $EXTRA_LIBS 65 | fi 66 | EXTRA_LIBS=./ci/extras/${ME}_extra_libs.txt 67 | if test -f "$EXTRA_LIBS"; then 68 | while read line; do 69 | sudo apt-get install $line 70 | done < $EXTRA_LIBS 71 | fi 72 | 73 | pwd 74 | ls -la 75 | 76 | mkdir -p build 77 | cd build 78 | 79 | rm -f CMakeCache.txt 80 | 81 | # Install python to get a recent version of cmake 82 | sudo apt install python3-pip 83 | python3 -m pip install --user --force-reinstall -q pip setuptools 84 | sudo apt remove python3-six python3-colorama python3-urllib3 85 | export LC_ALL=C.UTF-8 LANG=C.UTF-8 86 | python3 -m pip install --user -q cmake -vv 87 | 88 | last_ndk=$(ls -d /home/circleci/android-sdk/ndk/* | tail -1) 89 | test -d /opt/android || sudo mkdir -p /opt/android 90 | sudo ln -sf $last_ndk /opt/android/ndk 91 | 92 | if [ ! -z "$(BUILD_TYPE)" ]; then 93 | tag=$(git tag --contains HEAD) 94 | current_branch=$(git branch --show-current) 95 | if [ -n "$tag" ] || [ "$current_branch" = "master" ]; then 96 | BUILD_TYPE=Release 97 | else 98 | BUILD_TYPE=Debug 99 | fi 100 | fi 101 | 102 | cmake -DCMAKE_TOOLCHAIN_FILE=cmake/android-armhf-toolchain.cmake \ 103 | -D_wx_selected_config=androideabi-qt-armhf \ 104 | -DwxQt_Build=build_android_release_19_static_O3 \ 105 | -DQt_Build=build_arm32_19_O3/qtbase \ 106 | -DOCPN_Android_Common=OCPNAndroidCommon-master \ 107 | -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ 108 | .. 109 | 110 | make VERBOSE=1 111 | 112 | make package 113 | -------------------------------------------------------------------------------- /ci/circleci-build-debian.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # Build the Debian artifacts 5 | # 6 | set -xe 7 | 8 | if [ "${CIRCLECI_LOCAL,,}" = "true" ]; then 9 | if [[ -d ~/circleci-cache ]]; then 10 | if [[ -f ~/circleci-cache/apt-proxy ]]; then 11 | cat ~/circleci-cache/apt-proxy | sudo tee -a /etc/apt/apt.conf.d/00aptproxy 12 | cat /etc/apt/apt.conf.d/00aptproxy 13 | fi 14 | fi 15 | fi 16 | 17 | sudo apt-get -qq update 18 | sudo apt-get install devscripts equivs 19 | 20 | # Install extra build libs 21 | ME=$(echo ${0##*/} | sed 's/\.sh//g') 22 | EXTRA_LIBS=./ci/extras/extra_libs.txt 23 | if test -f "$EXTRA_LIBS"; then 24 | while read -r line; do 25 | sudo apt-get install $line 26 | done < "$EXTRA_LIBS" 27 | fi 28 | EXTRA_LIBS=./ci/extras/${ME}_extra_libs.txt 29 | if test -f "$EXTRA_LIBS"; then 30 | while read -r line; do 31 | sudo apt-get install $line 32 | done < "$EXTRA_LIBS" 33 | fi 34 | 35 | pwd 36 | 37 | git submodule update --init opencpn-libs 38 | 39 | sudo mk-build-deps --install ./ci/control 40 | 41 | sudo apt-get --allow-unauthenticated install ./*all.deb || : 42 | sudo apt-get --allow-unauthenticated install -f 43 | rm -f ./*all.deb 44 | 45 | 46 | if [ -n "$BUILD_GTK3" ] && [ "$BUILD_GTK3" = "TRUE" ]; then 47 | sudo update-alternatives --set wx-config /usr/lib/*-linux-*/wx/config/gtk3-unicode-3.0 48 | fi 49 | 50 | rm -rf build && mkdir build && cd build 51 | 52 | tag=$(git tag --contains HEAD) 53 | current_branch=$(git branch --show-current) 54 | 55 | if [ -n "$tag" ] || [ "$current_branch" = "master" ]; then 56 | cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local .. 57 | else 58 | cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/usr/local .. 59 | fi 60 | 61 | make -j2 62 | make package 63 | ls -l 64 | -------------------------------------------------------------------------------- /ci/circleci-build-fedora.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | 3 | # 4 | # Build the mingw artifacts inside the Fedora container 5 | # 6 | set -xe 7 | 8 | su -c "dnf install -y sudo dnf-plugins-core" 9 | sudo dnf builddep -y ci/opencpn-fedora.spec 10 | rm -rf build; mkdir build; cd build 11 | cmake .. 12 | make -j2 13 | make package 14 | -------------------------------------------------------------------------------- /ci/circleci-build-flatpak.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # Build the flatpak artifacts. Uses docker to run Fedora on 5 | # in full-fledged VM; the actual build is done in the Fedora 6 | # container. 7 | # 8 | # flatpak-builder can be run in a docker image. However, this 9 | # must then be run in privileged mode, which means it we need 10 | # a full VM to run it. 11 | # 12 | 13 | # bailout on errors and echo commands. 14 | set -xe 15 | 16 | if [ "${CIRCLECI_LOCAL,,}" = "true" ]; then 17 | if [[ -d ~/circleci-cache ]]; then 18 | if [[ -f ~/circleci-cache/apt-proxy ]]; then 19 | cat ~/circleci-cache/apt-proxy | sudo tee -a /etc/apt/apt.conf.d/00aptproxy 20 | cat /etc/apt/apt.conf.d/00aptproxy 21 | fi 22 | fi 23 | fi 24 | 25 | sudo apt-get -q -y --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages update 26 | 27 | #PLUGIN=bsb4 28 | 29 | sudo apt --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install flatpak flatpak-builder 30 | 31 | # Install extra build libs 32 | ME=$(echo ${0##*/} | sed 's/\.sh//g') 33 | EXTRA_LIBS=./ci/extras/extra_libs.txt 34 | if test -f "$EXTRA_LIBS"; then 35 | sudo apt update 36 | while read line; do 37 | sudo apt-get install $line 38 | done < $EXTRA_LIBS 39 | fi 40 | EXTRA_LIBS=./ci/extras/${ME}_extra_libs.txt 41 | if test -f "$EXTRA_LIBS"; then 42 | sudo apt update 43 | while read line; do 44 | sudo apt-get install $line 45 | done < $EXTRA_LIBS 46 | fi 47 | 48 | git config --global protocol.file.allow always 49 | git submodule update --init opencpn-libs 50 | 51 | if [ -n "$CI" ]; then 52 | sudo apt update 53 | 54 | # Avoid using outdated TLS certificates, see #210. 55 | sudo apt install --reinstall ca-certificates 56 | 57 | # Use updated flatpak workaround 58 | # sudo add-apt-repository -y ppa:alexlarsson/flatpak 59 | # sudo apt update 60 | 61 | # Handle possible outdated key for google packages, see #486 62 | wget -q -O - https://cli-assets.heroku.com/apt/release.key \ 63 | | sudo apt-key add - 64 | wget -q -O - https://dl.google.com/linux/linux_signing_key.pub \ 65 | | sudo apt-key add - 66 | 67 | 68 | # Install flatpak and flatpak-builder - obsoleted by flathub 69 | sudo apt install flatpak flatpak-builder 70 | 71 | fi 72 | 73 | flatpak remote-add --user --if-not-exists \ 74 | flathub https://dl.flathub.org/repo/flathub.flatpakrepo 75 | 76 | 77 | if [ "$FLATPAK_BRANCH" = "beta" ]; then 78 | flatpak install --user -y flathub org.freedesktop.Sdk//$SDK_VER >/dev/null 79 | flatpak remote-add --user --if-not-exists flathub-beta \ 80 | https://dl.flathub.org/beta-repo/flathub-beta.flatpakrepo 81 | flatpak install --user -y flathub-beta \ 82 | org.opencpn.OpenCPN >/dev/null 83 | else 84 | flatpak install --user -y flathub org.freedesktop.Sdk//$SDK_VER >/dev/null 85 | flatpak remote-add --user --if-not-exists flathub \ 86 | https://dl.flathub.org/repo/flathub.flatpakrepo 87 | flatpak install --user -y flathub \ 88 | org.opencpn.OpenCPN >/dev/null 89 | FLATPAK_BRANCH='stable' 90 | fi 91 | 92 | rm -rf build && mkdir build && cd build 93 | if [ -n "$WX_VER" ]; then 94 | SET_WX_VER="-DWX_VER=$WX_VER" 95 | else 96 | SET_WX_VER="" 97 | fi 98 | 99 | if [ "$FLATPAK_BRANCH" = '' ]; then 100 | cmake -DOCPN_TARGET=$OCPN_TARGET -DOCPN_FLATPAK_CONFIG=ON -DSDK_VER=$SDK_VER -DFLATPAK_BRANCH='beta' $SET_WX_VER .. 101 | else 102 | cmake -DOCPN_TARGET=$OCPN_TARGET -DOCPN_FLATPAK_CONFIG=ON -DSDK_VER=$SDK_VER -DFLATPAK_BRANCH=$FLATPAK_BRANCH $SET_WX_VER .. 103 | fi 104 | 105 | make flatpak-build 106 | make flatpak-pkg 107 | -------------------------------------------------------------------------------- /ci/circleci-build-jammy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # Build the Debian artifacts 5 | # 6 | set -xe 7 | 8 | if [ "${CIRCLECI_LOCAL,,}" = "true" ]; then 9 | if [[ -d ~/circleci-cache ]]; then 10 | if [[ -f ~/circleci-cache/apt-proxy ]]; then 11 | cat ~/circleci-cache/apt-proxy | sudo tee -a /etc/apt/apt.conf.d/00aptproxy 12 | cat /etc/apt/apt.conf.d/00aptproxy 13 | fi 14 | fi 15 | fi 16 | 17 | sudo apt-get -qq update 18 | sudo apt-get install devscripts equivs 19 | 20 | rm -rf build && mkdir build && cd build 21 | 22 | # Install extra build libs 23 | ME=$(echo ${0##*/} | sed 's/\.sh//g') 24 | EXTRA_LIBS=./ci/extras/extra_libs.txt 25 | if test -f "$EXTRA_LIBS"; then 26 | while read line; do 27 | sudo apt-get install $line 28 | done < $EXTRA_LIBS 29 | fi 30 | EXTRA_LIBS=./ci/extras/${ME}_extra_libs.txt 31 | if test -f "$EXTRA_LIBS"; then 32 | while read line; do 33 | sudo apt-get install $line 34 | done < $EXTRA_LIBS 35 | fi 36 | 37 | pwd 38 | sudo mk-build-deps --install ../ci/control 39 | 40 | sudo apt-get --allow-unauthenticated install ./*all.deb || : 41 | sudo apt-get --allow-unauthenticated install -f 42 | rm -f ./*all.deb 43 | 44 | sudo apt-get install libwxgtk3.2-dev 45 | 46 | if [ -n "$BUILD_GTK3" ] && [ "$BUILD_GTK3" = "TRUE" ]; then 47 | sudo update-alternatives --set wx-config /usr/lib/*-linux-*/wx/config/gtk3-unicode-3.0 48 | fi 49 | 50 | tag=$(git tag --contains HEAD) 51 | current_branch=$(git branch --show-current) 52 | 53 | if [ -n "$tag" ] || [ "$current_branch" = "master" ]; then 54 | cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local .. 55 | else 56 | cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/usr/local .. 57 | fi 58 | 59 | make -j2 60 | make package 61 | ls -l 62 | -------------------------------------------------------------------------------- /ci/circleci-build-macos-universal.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | # Build the MacOS artifacts 5 | 6 | 7 | # Copyright (c) 2021 Alec Leamas 8 | # 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 3 of the License, or 12 | # (at your option) any later version. 13 | 14 | set -x 15 | 16 | # Load local environment if it exists i. e., this is a local build 17 | if [ -f ~/.config/local-build.rc ]; then source ~/.config/local-build.rc; fi 18 | 19 | git submodule update --init opencpn-libs 20 | 21 | # If applicable, restore /usr/local from cache. 22 | if [[ -n "$CI" && -f /tmp/local.cache.tar ]]; then 23 | sudo rm -rf /usr/local/* 24 | sudo tar -C /usr -xf /tmp/local.cache.tar 25 | fi 26 | 27 | # Set up build directory 28 | rm -rf build && mkdir build 29 | 30 | # Create a log file. 31 | exec > >(tee build/build.log) 2>&1 32 | 33 | export MACOSX_DEPLOYMENT_TARGET=10.10 34 | 35 | # Return latest version of $1, optionally using option $2 36 | pkg_version() { brew list --versions $2 $1 | tail -1 | awk '{print $2}'; } 37 | 38 | # 39 | # Check if the cache is with us. If not, re-install brew. 40 | brew list --versions libexif || brew update-reset 41 | 42 | # Install packaged dependencies 43 | for pkg in cmake gettext libarchive libexif python3 wget openssl@3; do 44 | brew list --versions $pkg || brew install $pkg || brew install $pkg || : 45 | brew link --overwrite $pkg || brew install $pkg 46 | done 47 | 48 | #Install python virtual environment 49 | /usr/bin/python3 -m venv $HOME/cs-venv 50 | 51 | #Install prebuilt dependencies 52 | wget -q https://dl.cloudsmith.io/public/nohal/opencpn-plugins/raw/files/macos_deps_universal.tar.xz \ 53 | -O /tmp/macos_deps_universal.tar.xz 54 | sudo tar -C /usr/local -xJf /tmp/macos_deps_universal.tar.xz 55 | 56 | export OPENSSL_ROOT_DIR='/usr/local' 57 | 58 | # Build and package 59 | cd build 60 | cmake \ 61 | "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-Release}" \ 62 | -DCMAKE_INSTALL_PREFIX= \ 63 | -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} \ 64 | -DOCPN_TARGET_TUPLE="darwin-wx32;10;universal" \ 65 | -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \ 66 | .. 67 | 68 | if [[ -z "$CI" ]]; then 69 | echo '$CI not found in environment, assuming local setup' 70 | echo "Complete build using 'cd build; make tarball' or so." 71 | exit 0 72 | fi 73 | 74 | # nor-reproducible error on first invocation, seemingly tarball-conf-stamp 75 | # is not created as required. 76 | #make VERBOSE=1 tarball || make VERBOSE=1 tarball 77 | make 78 | make install 79 | make package 80 | make package 81 | 82 | # Create the cached /usr/local archive 83 | if [ -n "$CI" ]; then 84 | tar -C /usr -cf /tmp/local.cache.tar local 85 | fi 86 | -------------------------------------------------------------------------------- /ci/circleci-build-macos.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # Build the MacOS artifacts 5 | # 6 | 7 | set -xe 8 | 9 | set -o pipefail 10 | # Check if the cache is with us. If not, re-install brew. 11 | brew list --versions libexif || brew update-reset 12 | 13 | for pkg in cairo cmake gettext libarchive libexif python3 wget; do 14 | brew list --versions $pkg || brew install $pkg || brew install $pkg || : 15 | brew link --overwrite $pkg || brew install $pkg 16 | done 17 | 18 | if [ -n "${WX_VER}" ] && [ "${WX_VER}" -eq "32" ]; then 19 | echo "Building for WXVERSION 32"; 20 | WX_URL=https://download.opencpn.org/s/Djqm4SXzYjF8nBw/download 21 | WX_DOWNLOAD=/tmp/wx321_opencpn50_macos1010.tar.xz 22 | WX_EXECUTABLE=/tmp/wx321_opencpn50_macos1010/bin/wx-config 23 | WX_CONFIG="--prefix=/tmp/wx321_opencpn50_macos1010" 24 | MACOSX_DEPLOYMENT_TARGET=10.10 25 | else 26 | echo "Building for WXVERSION 315"; 27 | WX_URL=https://download.opencpn.org/s/MCiRiq4fJcKD56r/download 28 | WX_DOWNLOAD=/tmp/wx315_opencpn50_macos1010.tar.xz 29 | WX_EXECUTABLE=/tmp/wx315_opencpn50_macos1010/bin/wx-config 30 | WX_CONFIG="--prefix=/tmp/wx315_opencpn50_macos1010" 31 | MACOSX_DEPLOYMENT_TARGET=10.10 32 | fi 33 | 34 | #Install python virtual environment 35 | /usr/bin/python3 -m venv $HOME/cs-venv 36 | 37 | # Download required binaries using wget, since curl causes an issue with Xcode 13.1 and some specific certificates. 38 | # Inspect the response code to see if the file is downloaded properly. 39 | # If the download failed or file does not exist, then exit with an error. 40 | # For local purposes: only download if it has not been downloaded already. That does not harm building on CircleCI. 41 | if [ ! -f "$WX_DOWNLOAD" ]; then 42 | echo "Downloading $WX_DOWNLOAD"; 43 | SERVER_RESPONSE=$(wget --server-response -O $WX_DOWNLOAD $WX_URL 2>&1 | grep "HTTP"/ | awk '{print $2}') 44 | if [ $SERVER_RESPONSE -ne 200 ]; then 45 | echo "Fatal error: could not download $WX_DOWNLOAD. Server response: $SERVER_RESPONSE." 46 | exit 0 47 | fi 48 | fi 49 | if [ -f "$WX_DOWNLOAD" ]; then 50 | echo "$WX_DOWNLOAD exists" 51 | else 52 | echo "Fatal error: $WX_DOWNLOAD does not exist"; 53 | exit 0 54 | fi 55 | 56 | # Unpack the binaries to /tmp 57 | tar xJf $WX_DOWNLOAD -C /tmp 58 | 59 | # Extend PATH, only when necesary 60 | INCLUDE_DIR_GETTEXT="/usr/local/opt/gettext/bin:" 61 | 62 | if [[ ":$PATH:" != *$INCLUDE_DIR_GETTEXT* ]]; then 63 | echo "Your path is missing $INCLUDE_DIR_GETTEXT. Trying to add it automatically:" 64 | export PATH=$INCLUDE_DIR_GETTEXT$PATH 65 | echo 'export PATH="'$INCLUDE_DIR_GETTEXT'$PATH"' >> ~/.bash_profile 66 | else 67 | echo "Path includes $INCLUDE_DIR_GETTEXT" 68 | fi 69 | 70 | export MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET 71 | 72 | # MacOS .pkg installer is deprecated in OCPN 5.6.2+ 73 | # use brew to get Packages.pkg 74 | #if brew list --cask --versions packages; then 75 | # version=$(brew list --cask --versions packages) 76 | # version="${version/"packages "/}" 77 | # sudo installer \ 78 | # -pkg /usr/local/Caskroom/packages/$version/packages/Packages.pkg \ 79 | # -target / 80 | #else 81 | # brew install --cask packages 82 | #fi 83 | 84 | git submodule update --init opencpn-libs 85 | 86 | rm -rf build && mkdir build && cd build 87 | cmake \ 88 | -DwxWidgets_CONFIG_EXECUTABLE=$WX_EXECUTABLE \ 89 | -DwxWidgets_CONFIG_OPTIONS=$WX_CONFIG \ 90 | -DCMAKE_INSTALL_PREFIX=app/files \ 91 | -DBUILD_TYPE_PACKAGE:STRING=tarball \ 92 | -DCMAKE_OSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET \ 93 | "/" \ 94 | .. 95 | make 96 | make install 97 | make package 98 | 99 | -------------------------------------------------------------------------------- /ci/circleci-build-mingw.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | 3 | # 4 | # Build the mingw artifacts inside the Fedora container 5 | # 6 | 7 | set -xe 8 | 9 | su -c "dnf install -y sudo dnf-plugins-core" 10 | sudo dnf builddep -y mingw/fedora/opencpn-deps.spec 11 | rm -rf build; mkdir build; cd build 12 | cmake -DCMAKE_TOOLCHAIN_FILE=../mingw/fedora/toolchain.cmake .. 13 | make -j2 14 | make package 15 | -------------------------------------------------------------------------------- /ci/circleci-build-msvc.bat: -------------------------------------------------------------------------------- 1 | :: 2 | :: Build the msvc artifacts 3 | :: 4 | 5 | set "SCRIPTDIR=%~dp0" 6 | set "GIT_HOME=C:\Program Files\Git" 7 | if "%CONFIGURATION%" == "" set "CONFIGURATION=RelWithDebInfo" 8 | 9 | set wx_vers="wx%WX_VER%" 10 | echo Building %wx_vers% 11 | echo Building with %MSVC_VERSION% 12 | 13 | PATH %SCRIPTDIR%.local\bin;%PATH% 14 | echo SCRIPTDIR: %SCRIPTDIR% 15 | dir %SCRIPTDIR% 16 | dir %SCRIPTDIR%.. 17 | dir %SCRIPTDIR%..\msvc 18 | call %SCRIPTDIR%..\msvc\win_deps.bat %wx_vers% 19 | path %SCRIPTDIR%.local\bin;%PATH%;"C:\Program Files\CMake\bin" 20 | call "%SCRIPTDIR%..\cache\wx-config.bat" 21 | set PATH=%EXTRA_PATH%;%PATH% 22 | echo EXTRA_PATH: %EXTRA_PATH% 23 | echo USING wxWidgets_LIB_DIR: %wxWidgets_LIB_DIR% 24 | echo USING wxWidgets_ROOT_DIR: %wxWidgets_ROOT_DIR% 25 | echo USING OCPN_TARGET_TUPLE: %TARGET_TUPLE% 26 | 27 | nmake /? >nul 2>&1 28 | if errorlevel 1 ( 29 | set "VS_HOME=C:\Program Files\Microsoft Visual Studio\2022" 30 | call "%VS_HOME%\Community\VC\Auxiliary\Build\vcvars32.bat" 31 | ) 32 | 33 | git submodule update --init opencpn-libs 34 | 35 | dir 36 | 37 | if exist build (rmdir /s /q build) 38 | mkdir build && cd build 39 | dir 40 | 41 | wget https://sourceforge.net/projects/opencpnplugins/files/opencpn.lib 42 | wget https://download.opencpn.org/s/oibxM3kzfzKcSc3/download/OpenCPN_buildwin-4.99a.7z 43 | 7z x -y OpenCPN_buildwin-4.99a.7z -o..\buildwin 44 | wget https://download.opencpn.org/s/54HsBDLNzRZLL6i/download/nsis-3.04-setup.exe 45 | nsis-3.04-setup.exe /S 46 | 47 | echo Check if poedit has been installed 48 | poedit -version 49 | echo Done check 50 | 51 | echo Create build environment 52 | 53 | if "%MSVC_VERSION%" == "2019" ( 54 | cmake -T v141_xp -G "Visual Studio 16 2019" ^ 55 | -DCMAKE_GENERATOR_PLATFORM=Win32 ^ 56 | -DCMAKE_BUILD_TYPE=%CONFIGURATION% ^ 57 | -DwxWidgets_LIB_DIR=%wxWidgets_LIB_DIR% ^ 58 | -DwxWidgets_ROOT_DIR=%wxWidgets_ROOT_DIR% ^ 59 | .. 60 | ) else ( 61 | cmake -A Win32 -G "Visual Studio 17 2022" ^ 62 | -DCMAKE_GENERATOR_PLATFORM=Win32 ^ 63 | -DCMAKE_BUILD_TYPE=%CONFIGURATION% ^ 64 | -DwxWidgets_LIB_DIR=%wxWidgets_LIB_DIR% ^ 65 | -DwxWidgets_ROOT_DIR=%wxWidgets_ROOT_DIR% ^ 66 | .. 67 | ) 68 | 69 | 70 | cd 71 | dir 72 | 73 | echo Build for windows 74 | 75 | :cmake --build . --target tarball --config %CONFIGURATION% 76 | cmake --build . --target package --config %CONFIGURATION% 77 | -------------------------------------------------------------------------------- /ci/circleci-build-ubuntu-docker.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # Build for Raspbian and debian in a docker container 5 | # 6 | 7 | cd ~/project 8 | 9 | git submodule update --init opencpn-libs 10 | 11 | ls -la ~/project 12 | 13 | # bailout on errors and echo commands. 14 | set -x 15 | sudo apt-get -y --allow-unauthenticated update 16 | 17 | DOCKER_SOCK="unix:///var/run/docker.sock" 18 | 19 | echo "DOCKER_OPTS=\"-H tcp://127.0.0.1:2375 -H $DOCKER_SOCK -s devicemapper\"" | sudo tee /etc/default/docker > /dev/null 20 | sudo service docker restart 21 | sleep 5; 22 | 23 | if [ "$BUILD_ENV" = "raspbian" ]; then 24 | docker run --rm --privileged multiarch/qemu-user-static:register --reset 25 | else 26 | docker run --rm --privileged multiarch/qemu-user-static --reset -p yes 27 | fi 28 | 29 | docker run --privileged -d -ti -e "container=docker" \ 30 | -e "CIRCLECI=$CIRCLECI" \ 31 | -e "CIRCLE_BRANCH=$CIRCLE_BRANCH" \ 32 | -e "CIRCLE_TAG=$CIRCLE_TAG" \ 33 | -e "CIRCLE_PROJECT_USERNAME=$CIRCLE_PROJECT_USERNAME" \ 34 | -e "CIRCLE_PROJECT_REPONAME=$CIRCLE_PROJECT_REPONAME" \ 35 | -e "GIT_REPOSITORY_SERVER=$GIT_REPOSITORY_SERVER" \ 36 | -e "OCPN_TARGET=$OCPN_TARGET" \ 37 | -e "BUILD_GTK3=$BUILD_GTK3" \ 38 | -e "WX_VER=$WX_VER" \ 39 | -e "BUILD_ENV=$BUILD_ENV" \ 40 | -e "TZ=$TZ" \ 41 | -e "DEBIAN_FRONTEND=$DEBIAN_FRONTEND" \ 42 | -v $(pwd):/ci-source:rw -v ~/source_top:/source_top $DOCKER_IMAGE /bin/bash 43 | 44 | DOCKER_CONTAINER_ID=$(docker ps | grep $DOCKER_IMAGE | awk '{print $1}') 45 | 46 | echo "Target build: $OCPN_TARGET" 47 | # Construct and run build script 48 | rm -f build.sh 49 | 50 | if [ "$BUILD_ENV" = "raspbian" ]; then 51 | if [ "$OCPN_TARGET" = "buster-armhf" ]; then 52 | cat >> build.sh << "EOF01" 53 | # cmake 3.16 has a bug that stops the build to use an older version 54 | install_packages cmake=3.13.4-1 cmake-data=3.13.4-1 55 | EOF01 56 | else 57 | cat >> build.sh << "EOF02" 58 | install_packages cmake cmake-data 59 | EOF02 60 | fi 61 | if [ "$OCPN_TARGET" = "bullseye-armhf" ]; then 62 | cat >> build.sh << "EOF03" 63 | curl http://mirrordirector.raspbian.org/raspbian.public.key | apt-key add - 64 | curl http://archive.raspbian.org/raspbian.public.key | apt-key add - 65 | sudo apt -q --allow-unauthenticated update 66 | sudo apt --allow-unauthenticated install devscripts equivs wget git lsb-release 67 | sudo mk-build-deps -ir ci-source/ci/control 68 | sudo apt-get --allow-unauthenticated install -f 69 | EOF03 70 | else 71 | cat >> build.sh << "EOF04" 72 | install_packages git build-essential devscripts equivs gettext wx-common libgtk2.0-dev libwxbase3.0-dev libwxgtk3.0-dev libbz2-dev libcurl4-openssl-dev libexpat1-dev libcairo2-dev libarchive-dev liblzma-dev libexif-dev lsb-release 73 | EOF04 74 | fi 75 | else 76 | if [ "$OCPN_TARGET" = "focal-arm64" ] || 77 | [ "$OCPN_TARGET" = "focal-armhf" ] || 78 | [ "$OCPN_TARGET" = "bullseye-armhf" ] || 79 | [ "$OCPN_TARGET" = "bullseye-arm64" ] || 80 | [ "$OCPN_TARGET" = "bookworm-armhf" ] || 81 | [ "$OCPN_TARGET" = "bookworm-arm64" ] || 82 | [ "$OCPN_TARGET" = "bookworm" ] || 83 | [ "$OCPN_TARGET" = "buster-armhf" ]; then 84 | cat >> build.sh << "EOF05" 85 | echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections 86 | apt-get -qq --allow-unauthenticated update && DEBIAN_FRONTEND='noninteractive' TZ='America/New_York' apt-get -y --no-install-recommends --allow-change-held-packages install tzdata 87 | apt-get -y --fix-missing install --allow-change-held-packages --allow-unauthenticated \ 88 | software-properties-common devscripts equivs wget git build-essential gettext wx-common libgtk2.0-dev libbz2-dev libcurl4-openssl-dev libexpat1-dev libcairo2-dev libarchive-dev liblzma-dev libexif-dev lsb-release openssl libssl-dev 89 | EOF05 90 | if [ "$OCPN_TARGET" = "buster-armhf" ] || 91 | [ "$OCPN_TARGET" = "bullseye-arm64" ]; then 92 | echo "BUILD_GTK3: $BUILD_GTK3" 93 | if [ ! -n "$BUILD_GTK3" ] || [ "$BUILD_GTK3" = "false" ]; then 94 | echo "Building for GTK2" 95 | cat >> build.sh << "EOF06" 96 | apt-get -y --no-install-recommends --fix-missing --allow-change-held-packages --allow-unauthenticated install libwxgtk3.0-dev 97 | EOF06 98 | else 99 | echo "Building for GTK3" 100 | cat >> build.sh << "EOF07" 101 | apt-get -y --no-install-recommends --fix-missing --allow-change-held-packages --allow-unauthenticated install libwxgtk3.0-gtk3-dev 102 | EOF07 103 | fi 104 | fi 105 | echo "WX_VER: $WX_VER" 106 | if [ ! -n "$WX_VER" ] || [ "$WX_VER" = "30" ]; then 107 | echo "Building for WX30" 108 | cat >> build.sh << "EOF08" 109 | apt-get -y --no-install-recommends --fix-missing --allow-change-held-packages --allow-unauthenticated install libwxbase3.0-dev 110 | EOF08 111 | elif [ "$WX_VER" = "32" ]; then 112 | echo "Building for WX32" 113 | if [ "$OCPN_TARGET" = "bullseye-armhf" ] || [ "$OCPN_TARGET" = "bullseye-arm64" ]; then 114 | cat >> build.sh << "EOF09" 115 | echo "deb [trusted=yes] https://ppa.launchpadcontent.net/opencpn/opencpn/ubuntu jammy main" | tee -a /etc/apt/sources.list 116 | echo "deb-src [trusted=yes] https://ppa.launchpadcontent.net/opencpn/opencpn/ubuntu jammy main" | tee -a /etc/apt/sources.list 117 | apt-get -y --allow-unauthenticated update 118 | EOF09 119 | fi 120 | cat >> build.sh << "EOF10" 121 | apt-get -y --fix-missing --allow-change-held-packages --allow-unauthenticated install libwxgtk3.2-dev 122 | EOF10 123 | fi 124 | if [ "$OCPN_TARGET" = "focal-armhf" ]; then 125 | cat >> build.sh << "EOF11" 126 | CMAKE_VERSION=3.20.5-0kitware1ubuntu20.04.1 127 | wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc --no-check-certificate 2>/dev/null | apt-key add - 128 | apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' 129 | apt-get --allow-unauthenticated update 130 | apt --allow-unauthenticated install cmake=$CMAKE_VERSION cmake-data=$CMAKE_VERSION 131 | EOF11 132 | else 133 | cat >> build.sh << "EOF12" 134 | apt install -y --allow-unauthenticated cmake 135 | EOF12 136 | fi 137 | else 138 | cat > build.sh << "EOF13" 139 | apt-get -qq --allow-unauthenticated update 140 | apt-get -y --no-install-recommends --allow-change-held-packages --allow-unauthenticated install \ 141 | git cmake build-essential gettext wx-common libgtk2.0-dev libwxbase3.0-dev libwxgtk3.0-dev libbz2-dev libcurl4-openssl-dev libexpat1-dev libcairo2-dev libarchive-dev liblzma-dev libexif-dev lsb-release 142 | EOF13 143 | fi 144 | fi 145 | 146 | # Install extra build libs 147 | ME=$(echo ${0##*/} | sed 's/\.sh//g') 148 | EXTRA_LIBS=./ci/extras/extra_libs.txt 149 | if test -f "$EXTRA_LIBS"; then 150 | while read line; do 151 | sudo apt-get install $line 152 | done < $EXTRA_LIBS 153 | fi 154 | EXTRA_LIBS=./ci/extras/${ME}_extra_libs.txt 155 | if test -f "$EXTRA_LIBS"; then 156 | while read line; do 157 | sudo apt-get install $line 158 | done < $EXTRA_LIBS 159 | fi 160 | 161 | cat build.sh 162 | 163 | if type nproc &> /dev/null 164 | then 165 | BUILD_FLAGS="-j"$(nproc) 166 | fi 167 | 168 | docker exec -ti \ 169 | $DOCKER_CONTAINER_ID /bin/bash -xec "bash -xe ci-source/build.sh; rm -rf ci-source/build; mkdir ci-source/build; cd ci-source/build; cmake ..; make $BUILD_FLAGS; make package; chmod -R a+rw ../build;" 170 | 171 | echo "Stopping" 172 | docker ps -a 173 | docker stop $DOCKER_CONTAINER_ID 174 | docker rm -v $DOCKER_CONTAINER_ID 175 | 176 | -------------------------------------------------------------------------------- /ci/cloudsmith-upload.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # Run created cloudsmith upload script 5 | # 6 | 7 | CURRENT_DIR=$(pwd) 8 | ls 9 | ls build 10 | bash $CURRENT_DIR/build/cloudsmith-upload.sh 11 | -------------------------------------------------------------------------------- /ci/control: -------------------------------------------------------------------------------- 1 | Source: opencpn 2 | Build-Depends: debhelper (>= 9), 3 | cmake3 | cmake (>> 3.5.0), 4 | curl, 5 | libarchive-dev, 6 | libbz2-dev, 7 | libcairo2-dev, 8 | libcurl4-openssl-dev, 9 | libelf-dev, 10 | libexif-dev, 11 | libgdk-pixbuf2.0-dev, 12 | liblz4-dev, 13 | liblzma-dev, 14 | libpango1.0-dev, 15 | libsqlite3-dev, 16 | libtinyxml-dev, 17 | libunarr-dev | base-files (<< 11), 18 | libgtk2.0-dev, 19 | libgtk-3-dev, 20 | libwxsvg-dev | base-files (<< 11), 21 | base-files (>=12) | libwxgtk3.0-dev | libwxgtk3.0-gtk3-dev, 22 | base-files (>=12) | libwxgtk3.0-0v5 | libwxgtk3.0-gtk3-0v5, 23 | base-files (>=12) | libwxgtk-webview3.0-dev | libwxgtk-webview3.0-gtk3-dev, 24 | base-files (<< 12) | libwxgtk3.2-dev (>= 3.2.2), 25 | base-files (<< 12) | libwxgtk-webview3.2-dev (>= 3.2.2), 26 | portaudio19-dev, 27 | python3-pip, 28 | python3-setuptools 29 | 30 | Standards-Version: 4.3.0 31 | Homepage: https://opencpn.org 32 | 33 | Description: Packages needed to build opencpn on debian. 34 | The Build-Depends field can be used to install dependencies 35 | using something like: 36 | . 37 | . sudo apt install devscripts equivs 38 | . sudo mk-build-deps --install ci/control 39 | . 40 | These packages are available in trusty+. The base-files 41 | fallback is for optional packages available in later releases. 42 | -------------------------------------------------------------------------------- /ci/extras/README.txt: -------------------------------------------------------------------------------- 1 | This directory can contain 0, 1, or more files that can be used to install extra libraries/programs 2 | that need to be installed to ensure the build will be sucessful. There are three basic file names: 3 | extra_libs.txt 4 | {script name}_extra_libs.txt 5 | {CIRCLE_JOB}_extra.libs.txt 6 | 7 | The first will be executed by all scripts, the second will only be executed by a specific script. 8 | The second form will look like: 9 | circleci-build-debian_extra_libs.txt 10 | where 'circleci-build-debian' is the script name with the '.sh' removed. 11 | The third form will look like: 12 | build-jammy_extra_libs.txt 13 | where 'build-jammy' is the circleci job. 14 | 15 | -------------------------------------------------------------------------------- /ci/extras/circleci-build-flatpak_extra_libs.txt: -------------------------------------------------------------------------------- 1 | libcurl4-openssl-dev 2 | -------------------------------------------------------------------------------- /ci/extras/extra_libs.txt: -------------------------------------------------------------------------------- 1 | equivs 2 | -------------------------------------------------------------------------------- /ci/opencpn-deps.spec: -------------------------------------------------------------------------------- 1 | Name: opencpn-deps 2 | Version: 0.1 3 | Release: 1%{?dist} 4 | Summary: Empty package with opencpn build dependencies 5 | 6 | License: MIT 7 | URL: https://github.com/leamas/opencpn 8 | 9 | BuildRequires: cmake 10 | BuildRequires: gettext 11 | BuildRequires: make 12 | BuildRequires: mingw-binutils-generic 13 | BuildRequires: mingw-filesystem-base 14 | BuildRequires: mingw32-binutils 15 | BuildRequires: mingw32-bzip2 16 | BuildRequires: mingw32-cairo 17 | BuildRequires: mingw32-curl 18 | BuildRequires: mingw32-expat 19 | BuildRequires: mingw32-filesystem 20 | BuildRequires: mingw32-fontconfig 21 | BuildRequires: mingw32-freetype 22 | BuildRequires: mingw32-gcc 23 | BuildRequires: mingw32-gcc-c++ 24 | BuildRequires: mingw32-cpp 25 | BuildRequires: mingw32-gettext 26 | BuildRequires: mingw32-headers 27 | BuildRequires: mingw32-glib2 28 | BuildRequires: mingw32-gtk2 29 | BuildRequires: mingw32-libarchive 30 | BuildRequires: mingw32-libexif 31 | BuildRequires: mingw32-libffi 32 | BuildRequires: mingw32-libpng 33 | BuildRequires: mingw32-libtiff 34 | BuildRequires: mingw32-libxml2 35 | BuildRequires: mingw32-nsiswrapper 36 | BuildRequires: mingw32-openssl 37 | BuildRequires: mingw32-pcre 38 | BuildRequires: mingw32-pixman 39 | BuildRequires: mingw32-sqlite 40 | BuildRequires: mingw32-win-iconv 41 | BuildRequires: mingw32-wxWidgets3 >= 3.0.2 42 | BuildRequires: mingw32-xz-libs 43 | 44 | %description 45 | 46 | Empty package used to catch build dependencies for opencpn using 47 | the mingw tools to create a Windows 32-bit executable 48 | 49 | Use dnf builddep opencpn-deps.spec to install the dependencies. 50 | 51 | %prep 52 | 53 | 54 | %build 55 | 56 | 57 | %install 58 | 59 | 60 | %files 61 | %doc COPYING 62 | 63 | 64 | %changelog 65 | * Fri Mar 15 2020 - 0.1 66 | - Initial release 67 | -------------------------------------------------------------------------------- /ci/opencpn-fedora.spec: -------------------------------------------------------------------------------- 1 | Name: opencpn 2 | Summary: Chartplotter and GPS navigation software 3 | Version: 5.0.0 4 | Release: 4.1%{?dist} 5 | License: GPLv2+ 6 | 7 | BuildRequires: bzip2-devel 8 | BuildRequires: cmake 9 | BuildRequires: curl 10 | BuildRequires: desktop-file-utils 11 | BuildRequires: elfutils-libelf-devel 12 | BuildRequires: expat-devel 13 | BuildRequires: gcc-c++ 14 | BuildRequires: gettext 15 | BuildRequires: libcurl-devel 16 | BuildRequires: mesa-libGL-devel 17 | BuildRequires: mesa-libGLU-devel 18 | BuildRequires: portaudio-devel 19 | BuildRequires: redhat-lsb-core 20 | BuildRequires: tar 21 | BuildRequires: tinyxml-devel 22 | BuildRequires: compat-wxGTK3-gtk2-devel 23 | BuildRequires: xz-devel 24 | BuildRequires: xz-lzma-compat 25 | 26 | %description 27 | Empty package to catch build dependecies for OpenCPN 28 | 29 | %prep 30 | 31 | %build 32 | 33 | %install 34 | 35 | %changelog 36 | * Sun Apr 28 2019 Alec Leamas - 4.8.0-4.1 37 | - rebuilt 38 | -------------------------------------------------------------------------------- /cmake/FindGTK3.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find GTK+ 3 Once done, this will define 2 | # 3 | # GTK3_FOUND - system has GTK+ 3. GTK3_INCLUDE_DIRS - the GTK+ 3. include 4 | # directories GTK3_LIBRARIES - link these to use GTK+ 3. 5 | # 6 | # Copyright (C) 2012 Raphael Kubo da Costa Copyright (C) 7 | # 2013 Igalia S.L. 8 | # 9 | # Redistribution and use in source and binary forms, with or without 10 | # modification, are permitted provided that the following conditions are met: 1. 11 | # Redistributions of source code must retain the above copyright notice, this 12 | # list of conditions and the following disclaimer. 2. Redistributions in binary 13 | # form must reproduce the above copyright notice, this list of conditions and 14 | # the following disclaimer in the documentation and/or other materials provided 15 | # with the distribution. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS 18 | # IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | set(FindGTK3_SAVE_CMLOC ${CMLOC}) 29 | set(CMLOC "FindGTK3: ") 30 | 31 | message(STATUS "${CMLOC}Finding package PkgConfig") 32 | find_package(PkgConfig) 33 | pkg_check_modules(GTK3 gtk+-3.0) 34 | set(VERSION_OK TRUE) 35 | if (GTK3_VERSION) 36 | message(STATUS "${CMLOC}Found GTK3_VERSION") 37 | if (GTK3_FIND_VERSION_EXACT) 38 | message(STATUS "${CMLOC}Find exact version of GTK3") 39 | if (NOT ("${GTK3_FIND_VERSION}" VERSION_EQUAL "${GTK3_VERSION}")) 40 | set(VERSION_OK FALSE) 41 | message( 42 | STATUS 43 | "${CMLOC}GTK3 exact version not found: GTK3_FIND_VERSION: ${GTK3_FIND_VERSION} != GTK3_VERSION: ${GTK3_VERSION}" 44 | ) 45 | endif () 46 | else () 47 | if ("${GTK3_VERSION}" VERSION_LESS "${GTK3_FIND_VERSION}") 48 | set(VERSION_OK FALSE) 49 | message( 50 | STATUS 51 | "${CMLOC}GTK3 exact version not found: GTK3_VERSION: ${GTK3_VERSION} < GTK3_FIND_VERSION: ${GTK3_FIND_VERSION}" 52 | ) 53 | endif () 54 | endif () 55 | elseif () 56 | message(STATUS "${CMLOC}GTK3 not found") 57 | endif () 58 | include(FindPackageHandleStandardArgs) 59 | find_package_handle_standard_args( 60 | GTK3 DEFAULT_MSG GTK3_INCLUDE_DIRS GTK3_LIBRARIES VERSION_OK 61 | ) 62 | message(STATUS "${CMLOC}Finished FindGTK3") 63 | 64 | set(CMLOC ${FindGTK3_SAVE_CMLOC}) 65 | -------------------------------------------------------------------------------- /cmake/MacosWxwidgets.cmake: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Summary: If required, rebuild wxwidgets for macos from source. 3 | # License: GPLv3+ 4 | # Copyright (c) 2022 Alec Leamas 5 | # ~~~ 6 | 7 | # This program is free software; you can redistribute it and/or modify it under 8 | # the terms of the GNU General Public License as published by the Free Software 9 | # Foundation; either version 3 of the License, or (at your option) any later 10 | # version. 11 | 12 | cmake_minimum_required(VERSION 3.20.0) 13 | 14 | set(wx_repo https://github.com/wxWidgets/wxWidgets.git) 15 | set(wx_tag v3.2.2.1) 16 | 17 | option(IGNORE_SYSTEM_WX "Never use system wxWidgets installation" FALSE) 18 | 19 | # Check if we have done the wxWidgets build already 20 | # 21 | if (DEFINED wx_config) 22 | return() 23 | endif () 24 | 25 | # Check if there is a usable wxwidgets anyway 26 | # 27 | set(cache_dir ${PROJECT_SOURCE_DIR}/cache) 28 | 29 | if (IGNORE_SYSTEM_WX) 30 | set(WX_CONFIG_PROG ${cache_dir}/lib/wx/config/osx_cocoa-unicode-3.2) 31 | else () 32 | find_program( 33 | WX_CONFIG_PROG 34 | NAMES wx-config osx_cocoa-unicode-3.2 35 | HINTS ${PROJECT_SOURCE_DIR}/cache/lib/wx/config /usr/local/lib/wx/config 36 | ) 37 | endif () 38 | if (WX_CONFIG_PROG) 39 | execute_process( 40 | COMMAND ${WX_CONFIG_PROG} --version 41 | RESULT_VARIABLE wx_status 42 | OUTPUT_VARIABLE wx_version 43 | ERROR_FILE /dev/null COMMAND_ECHO STDOUT 44 | OUTPUT_STRIP_TRAILING_WHITESPACE 45 | ) 46 | else () 47 | set(wx_status 1) 48 | endif () 49 | 50 | if (${wx_status} EQUAL 0) 51 | set(wx_config 52 | ${WX_CONFIG_PROG} 53 | CACHE FILEPATH "" 54 | ) 55 | set(ENV{WX_CONFIG} ${WX_CONFIG_PROG}) 56 | if (${wx_version} VERSION_GREATER_EQUAL 3.2) 57 | return() 58 | endif () 59 | endif () 60 | 61 | if (NOT EXISTS ${cache_dir}) 62 | file(MAKE_DIRECTORY ${cache_dir}) 63 | endif () 64 | 65 | # Download sources and get the source directory 66 | # 67 | include(FetchContent) 68 | fetchcontent_declare( 69 | wxwidgets 70 | GIT_REPOSITORY ${wx_repo} 71 | GIT_TAG ${wx_tag} 72 | ) 73 | fetchcontent_populate(wxwidgets) 74 | fetchcontent_getproperties(wxwidgets SOURCE_DIR wxwidgets_src_dir) 75 | 76 | execute_process( 77 | COMMAND git submodule update --init 3rdparty/pcre 78 | WORKING_DIRECTORY ${wxwidgets_src_dir} 79 | ) 80 | execute_process( 81 | COMMAND 82 | ./configure --with-cxx=11 --with-macosx-version-min=10.10 --enable-unicode 83 | --with-osx-cocoa --enable-aui --disable-debug --with-opengl 84 | --enable-macosx_arch=arm64,x86_64 --enable-universal_binary=arm64,x86_64 85 | --without-subdirs --prefix=${cache_dir} 86 | WORKING_DIRECTORY ${wxwidgets_src_dir} 87 | ) 88 | math(_nproc ${OCPN_NPROC} * 2) # Assuming two threads/cpu 89 | execute_process(COMMAND make -j${_nproc} WORKING_DIRECTORY ${wxwidgets_src_dir}) 90 | execute_process( 91 | COMMAND sudo make install WORKING_DIRECTORY ${wxwidgets_src_dir} 92 | ) 93 | 94 | set(wx_config ${cache_dir}/lib/wx/config/osx_cocoa-unicode-3.2) 95 | if (NOT EXISTS ${wx_config}) 96 | message(FATAL_ERROR "Cannot locate wx-config tool at ${wx_config}") 97 | endif () 98 | set(ENV{WX_CONFIG} ${wx_config}) 99 | -------------------------------------------------------------------------------- /cmake/PluginInstall.cmake: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------------------------- 2 | # Author: Pavel Kalian (Based on the work of Sean D'Epagnier) Copyright: 3 | # 2014 License: GPLv3+ 4 | # --------------------------------------------------------------------------- 5 | 6 | set(SAVE_CMLOC ${CMLOC}) 7 | set(CMLOC "PluginInstall: ") 8 | 9 | if (OCPN_FLATPAK_CONFIG) 10 | return() 11 | endif (OCPN_FLATPAK_CONFIG) 12 | 13 | if (NOT APPLE) 14 | target_link_libraries(${PACKAGE_NAME} ${wxWidgets_LIBRARIES} ${EXTRA_LIBS}) 15 | endif (NOT APPLE) 16 | 17 | if (WIN32) 18 | if (MSVC) 19 | # TARGET_LINK_LIBRARIES(${PACKAGE_NAME} gdiplus.lib glu32.lib) 20 | target_link_libraries(${PACKAGE_NAME} ${OPENGL_LIBRARIES}) 21 | # add_subdirectory(libs/ocpn-api) target_link_libraries(${PACKAGE_NAME} 22 | # ocpn::api) message(STATUS "${CMLOC}Added ocpn-api for MSVC") 23 | endif (MSVC) 24 | 25 | if (MINGW) 26 | # assuming wxwidgets is compiled with unicode, this is needed for mingw 27 | # headers 28 | add_definitions(" -DUNICODE") 29 | target_link_libraries(${PACKAGE_NAME} ${OPENGL_LIBRARIES}) 30 | set(CMAKE_SHARED_LINKER_FLAGS "-L../buildwin") 31 | # add_subdirectory(libs/ocpn-api) target_link_libraries(${PACKAGE_NAME} 32 | # ocpn::api) message(STATUS "${CMLOC}Added ocpn-api for MINGW") 33 | endif (MINGW) 34 | endif (WIN32) 35 | 36 | if (UNIX) 37 | if (PROFILING) 38 | find_library( 39 | GCOV_LIBRARY 40 | NAMES gcov 41 | PATHS /usr/lib/gcc/i686-pc-linux-gnu/4.7 42 | ) 43 | 44 | set(EXTRA_LIBS ${EXTRA_LIBS} ${GCOV_LIBRARY}) 45 | endif (PROFILING) 46 | endif (UNIX) 47 | 48 | if (UNIX 49 | AND NOT APPLE 50 | AND NOT QT_ANDROID 51 | ) 52 | find_package(BZip2 REQUIRED) 53 | include_directories(${BZIP2_INCLUDE_DIR}) 54 | find_package(ZLIB REQUIRED) 55 | include_directories(${ZLIB_INCLUDE_DIR}) 56 | target_link_libraries(${PACKAGE_NAME} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARY}) 57 | endif ( 58 | UNIX 59 | AND NOT APPLE 60 | AND NOT QT_ANDROID 61 | ) 62 | 63 | set(PARENT opencpn) 64 | 65 | if (APPLE) 66 | install( 67 | TARGETS ${PACKAGE_NAME} 68 | RUNTIME 69 | LIBRARY DESTINATION OpenCPN.app/Contents/PlugIns 70 | ) 71 | if (EXISTS ${PROJECT_SOURCE_DIR}/data) 72 | install( 73 | DIRECTORY data 74 | DESTINATION OpenCPN.app/Contents/SharedSupport/plugins/${PACKAGE_NAME} 75 | ) 76 | endif () 77 | 78 | if (EXISTS ${PROJECT_SOURCE_DIR}/UserIcons) 79 | install( 80 | DIRECTORY UserIcons 81 | DESTINATION OpenCPN.app/Contents/SharedSupport/plugins/${PACKAGE_NAME} 82 | ) 83 | endif () 84 | 85 | find_package(ZLIB REQUIRED) 86 | target_link_libraries(${PACKAGE_NAME} ${ZLIB_LIBRARIES}) 87 | 88 | endif (APPLE) 89 | 90 | # Based on code from nohal 91 | if (NOT CMAKE_INSTALL_PREFIX) 92 | set(CMAKE_INSTALL_PREFIX ${TENTATIVE_PREFIX}) 93 | endif (NOT CMAKE_INSTALL_PREFIX) 94 | 95 | message(STATUS "${CMLOC}*** Will install to ${CMAKE_INSTALL_PREFIX} ***") 96 | set(PREFIX_DATA share) 97 | set(PREFIX_PKGDATA ${PREFIX_DATA}/${PACKAGE_NAME}) 98 | # set(PREFIX_LIB "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}") 99 | set(PREFIX_LIB lib) 100 | 101 | if (WIN32) 102 | message(STATUS "${CMLOC}Install Prefix: ${CMAKE_INSTALL_PREFIX}") 103 | set(CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/../OpenCPN) 104 | if (CMAKE_CROSSCOMPILING) 105 | install(TARGETS ${PACKAGE_NAME} RUNTIME DESTINATION "plugins") 106 | set(INSTALL_DIRECTORY "plugins/${PACKAGE_NAME}") 107 | else (CMAKE_CROSSCOMPILING) 108 | install(TARGETS ${PACKAGE_NAME} RUNTIME DESTINATION "plugins") 109 | set(INSTALL_DIRECTORY "plugins\\\\${PACKAGE_NAME}") 110 | endif (CMAKE_CROSSCOMPILING) 111 | 112 | if (EXISTS ${PROJECT_SOURCE_DIR}/UserIcons) 113 | install(DIRECTORY UserIcons DESTINATION "${INSTALL_DIRECTORY}") 114 | message(STATUS "${CMLOC}Install UserIcons: ${INSTALL_DIRECTORY}") 115 | endif (EXISTS ${PROJECT_SOURCE_DIR}/UserIcons) 116 | 117 | if (EXISTS ${PROJECT_SOURCE_DIR}/data) 118 | install(DIRECTORY data DESTINATION "${INSTALL_DIRECTORY}") 119 | message(STATUS "${CMLOC}Install Data: ${INSTALL_DIRECTORY}") 120 | endif (EXISTS ${PROJECT_SOURCE_DIR}/data) 121 | 122 | # fix for missing dll's FILE(GLOB gtkdll_files 123 | # "${CMAKE_CURRENT_SOURCE_DIR}/buildwin/gtk/*.dll") INSTALL(FILES 124 | # ${gtkdll_files} DESTINATION ".") FILE(GLOB expatdll_files 125 | # "${CMAKE_CURRENT_SOURCE_DIR}/buildwin/expat-2.1.0/*.dll") INSTALL(FILES 126 | # ${expatdll_files} DESTINATION ".") 127 | 128 | endif (WIN32) 129 | 130 | if (UNIX AND NOT APPLE) 131 | set(PREFIX_PARENTDATA ${PREFIX_DATA}/${PARENT}) 132 | set(PREFIX_PARENTLIB ${PREFIX_LIB}/${PARENT}) 133 | message(STATUS "${CMLOC}PREFIX_PARENTLIB: ${PREFIX_PARENTLIB}") 134 | message(STATUS "${CMLOC}Library") 135 | install(TARGETS ${PACKAGE_NAME} LIBRARY DESTINATION ${PREFIX_PARENTLIB}) 136 | 137 | if (EXISTS ${PROJECT_SOURCE_DIR}/data) 138 | install(DIRECTORY data 139 | DESTINATION ${PREFIX_PARENTDATA}/plugins/${PACKAGE_NAME} 140 | ) 141 | message( 142 | STATUS 143 | "${CMLOC}Install data: ${PREFIX_PARENTDATA}/plugins/${PACKAGE_NAME}" 144 | ) 145 | endif () 146 | if (EXISTS ${PROJECT_SOURCE_DIR}/UserIcons) 147 | install(DIRECTORY UserIcons 148 | DESTINATION ${PREFIX_PARENTDATA}/plugins/${PACKAGE_NAME} 149 | ) 150 | set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA 151 | "${PROJECT_SOURCE_DIR}/script/postinst" 152 | ) 153 | set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE 154 | "${PROJECT_SOURCE_DIR}/script/postinst" 155 | ) 156 | message( 157 | STATUS 158 | "${CMLOC}Install UserIcons: ${PREFIX_PARENTDATA}/plugins/${PACKAGE_NAME}" 159 | ) 160 | endif () 161 | endif (UNIX AND NOT APPLE) 162 | 163 | if (APPLE) 164 | message(STATUS "${CMLOC}Install Prefix: ${CMAKE_INSTALL_PREFIX}") 165 | 166 | # For Apple build, we need to copy the "data" directory contents to the build 167 | # directory, so that the packager can pick them up. 168 | if (NOT EXISTS "${PROJECT_BINARY_DIR}/data/") 169 | file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/data/") 170 | message("Generating data directory") 171 | endif () 172 | 173 | file( 174 | GLOB_RECURSE PACKAGE_DATA_FILES 175 | LIST_DIRECTORIES true 176 | ${PROJECT_SOURCE_DIR}/data/* 177 | ) 178 | 179 | foreach (_currentDataFile ${PACKAGE_DATA_FILES}) 180 | message(STATUS "${CMLOC}copying: ${_currentDataFile}") 181 | file(COPY ${_currentDataFile} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/data) 182 | endforeach (_currentDataFile) 183 | 184 | if (EXISTS ${PROJECT_SOURCE_DIR}/UserIcons) 185 | file( 186 | GLOB_RECURSE PACKAGE_DATA_FILES 187 | LIST_DIRECTORIES true 188 | ${PROJECT_SOURCE_DIR}/UserIcons/* 189 | ) 190 | 191 | foreach (_currentDataFile ${PACKAGE_DATA_FILES}) 192 | message(STATUS "${CMLOC}copying: ${_currentDataFile}") 193 | file(COPY ${_currentDataFile} 194 | DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/UserIcons 195 | ) 196 | endforeach (_currentDataFile) 197 | endif () 198 | 199 | # On macos, fix paths which points to the build environment, make sure they 200 | # refers to runtime locations 201 | message(STATUS "${CMLOC}copying: Adjusting MacOS library paths") 202 | install(CODE "execute_process( 203 | COMMAND bash ${PROJECT_SOURCE_DIR}/cmake/fix-macos-libs.sh 204 | )" 205 | ) 206 | 207 | install( 208 | TARGETS ${PACKAGE_NAME} 209 | RUNTIME 210 | LIBRARY DESTINATION OpenCPN.app/Contents/PlugIns 211 | ) 212 | message(STATUS "${CMLOC}Install Target: OpenCPN.app/Contents/PlugIns") 213 | 214 | endif (APPLE) 215 | 216 | set(CMLOC ${SAVE_CMLOC}) 217 | -------------------------------------------------------------------------------- /cmake/PluginLocalization.cmake: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------------------------- 2 | # Author: Pavel Kalian / Sean D'Epagnier Copyright: License: GPLv3+ 3 | # --------------------------------------------------------------------------- 4 | 5 | set(SAVE_CMLOC ${CMLOC}) 6 | set(CMLOC "PluginLocalization: ") 7 | 8 | if (OCPN_FLATPAK_CONFIG) 9 | set(CMLOC ${SAVE_CMLOC}) 10 | return() 11 | endif (OCPN_FLATPAK_CONFIG) 12 | 13 | message(STATUS "${CMLOC}Starting POTFILE generation") 14 | 15 | set(POTFILE ${CMAKE_CURRENT_SOURCE_DIR}/po/POTFILES.in) 16 | file(REMOVE ${POTFILE}.test) 17 | file(WRITE ${POTFILE}.test "") 18 | message( 19 | STATUS 20 | "${CMLOC}Checking file: ${CMAKE_CURRENT_SOURCE_DIR}/po/${PACKAGE_NAME}.pot" 21 | ) 22 | if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/po/${PACKAGE_NAME}.pot) 23 | message( 24 | STATUS "${CMLOC}Found: ${CMAKE_CURRENT_SOURCE_DIR}/po/${PACKAGE_NAME}.pot" 25 | ) 26 | else () 27 | file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/po/${PACKAGE_NAME}.pot "") 28 | message( 29 | STATUS 30 | "${CMLOC}Creating empty ${CMAKE_CURRENT_SOURCE_DIR}/po/${PACKAGE_NAME}.pot" 31 | ) 32 | endif () 33 | foreach (POTLINE IN ITEMS ${SRCS}) 34 | file(APPEND ${POTFILE}.test "${POTLINE}\n") 35 | endforeach (POTLINE) 36 | foreach (POTLINE IN ITEMS ${HDRS}) 37 | file(APPEND ${POTFILE}.test "${POTLINE}\n") 38 | endforeach (POTLINE) 39 | # convert crlf to lf for consistency and make copy_if_different work correctly 40 | configure_file(${POTFILE}.test ${POTFILE}.test NEWLINE_STYLE UNIX) 41 | execute_process( 42 | COMMAND ${CMAKE_COMMAND} -E copy_if_different ${POTFILE}.test ${POTFILE} 43 | OUTPUT_QUIET ERROR_QUIET 44 | ) 45 | 46 | find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext) 47 | string(REPLACE "_pi" "" I18N_NAME ${PACKAGE_NAME}) 48 | if (GETTEXT_XGETTEXT_EXECUTABLE) 49 | add_custom_command( 50 | OUTPUT po/${PACKAGE_NAME}.pot.dummy 51 | COMMAND 52 | ${GETTEXT_XGETTEXT_EXECUTABLE} --force-po -F 53 | --package-name=${PACKAGE_NAME} --package-version="${PACKAGE_VERSION}" 54 | --output=po/${PACKAGE_NAME}.pot --keyword=_ --width=80 55 | --files-from=${CMAKE_CURRENT_SOURCE_DIR}/po/POTFILES.in 56 | DEPENDS po/POTFILES.in po/${PACKAGE_NAME}.pot 57 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 58 | COMMENT "${I18N_NAME}-pot-update [${PACKAGE_NAME}]: Generated pot file." 59 | ) 60 | add_custom_target( 61 | ${I18N_NAME}-pot-update 62 | COMMENT "[${PACKAGE_NAME}]-pot-update: Done." 63 | DEPENDS po/${PACKAGE_NAME}.pot.dummy 64 | ) 65 | 66 | endif (GETTEXT_XGETTEXT_EXECUTABLE) 67 | 68 | macro (GETTEXT_UPDATE_PO _potFile) 69 | set(_poFiles ${_potFile}) 70 | get_filename_component(_absPotFile ${_potFile} ABSOLUTE) 71 | 72 | foreach (_currentPoFile ${ARGN}) 73 | get_filename_component(_absFile ${_currentPoFile} ABSOLUTE) 74 | get_filename_component(_poBasename ${_absFile} NAME_WE) 75 | 76 | add_custom_command( 77 | OUTPUT ${_absFile}.dummy 78 | COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} --width=80 --strict --quiet 79 | --update --backup=none --no-location -s ${_absFile} ${_absPotFile} 80 | DEPENDS ${_absPotFile} ${_absFile} 81 | COMMENT "${I18N_NAME}-po-update [${_poBasename}]: Updated po file." 82 | ) 83 | 84 | set(_poFiles ${_poFiles} ${_absFile}.dummy) 85 | 86 | endforeach (_currentPoFile) 87 | 88 | add_custom_target( 89 | ${I18N_NAME}-po-update 90 | COMMENT "[${PACKAGE_NAME}]-po-update: Done." 91 | DEPENDS ${_poFiles} 92 | ) 93 | endmacro (GETTEXT_UPDATE_PO) 94 | 95 | if (GETTEXT_MSGMERGE_EXECUTABLE) 96 | file(GLOB PACKAGE_PO_FILES po/*.po) 97 | gettext_update_po(po/${PACKAGE_NAME}.pot ${PACKAGE_PO_FILES}) 98 | endif (GETTEXT_MSGMERGE_EXECUTABLE) 99 | 100 | set(_gmoFiles) 101 | macro (GETTEXT_BUILD_MO) 102 | file(MAKE_DIRECTORY "Resources") 103 | message(STATUS "${CMLOC}Creating Resources directory") 104 | add_custom_target( 105 | create_resources_dir ALL COMMAND ${CMAKE_COMMAND} -E make_directory 106 | "./Resources" 107 | ) 108 | foreach (_poFile ${ARGN}) 109 | get_filename_component(_absFile ${_poFile} ABSOLUTE) 110 | get_filename_component(_poBasename ${_absFile} NAME_WE) 111 | set(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_poBasename}.mo) 112 | 113 | add_custom_command( 114 | OUTPUT ${_gmoFile} 115 | COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --check -o ${_gmoFile} ${_absFile} 116 | COMMAND ${CMAKE_COMMAND} -E copy ${_gmoFile} 117 | "Resources/${_poBasename}.lproj/opencpn-${PACKAGE_NAME}.mo" 118 | DEPENDS ${_absFile} 119 | COMMENT "${I18N_NAME}-i18n [${_poBasename}]: Created mo file." 120 | ) 121 | 122 | if (APPLE) 123 | install( 124 | FILES ${_gmoFile} 125 | DESTINATION OpenCPN.app/Contents/Resources/${_poBasename}.lproj 126 | RENAME opencpn-${PACKAGE_NAME}.mo 127 | ) 128 | message( 129 | STATUS 130 | "${CMLOC}Install language files to: OpenCPN.app/Contents/Resources/${_poBasename}.lproj renamed to: opencpn-${PACKAGE_NAME}.mo" 131 | ) 132 | else (APPLE) 133 | install( 134 | FILES ${_gmoFile} 135 | DESTINATION ${PREFIX_DATA}/locale/${_poBasename}/LC_MESSAGES 136 | RENAME opencpn-${PACKAGE_NAME}.mo 137 | ) 138 | message( 139 | STATUS 140 | "${CMLOC}Install language files to: ${PREFIX_DATA}/locale/${_poBasename}/LC_MESSAGES renamed to: opencpn-${PACKAGE_NAME}.mo" 141 | ) 142 | endif (APPLE) 143 | 144 | set(_gmoFiles ${_gmoFiles} ${_gmoFile}) 145 | endforeach (_poFile) 146 | endmacro (GETTEXT_BUILD_MO) 147 | 148 | if (GETTEXT_MSGFMT_EXECUTABLE) 149 | file(GLOB PACKAGE_PO_FILES po/*.po) 150 | gettext_build_mo(${PACKAGE_PO_FILES}) 151 | add_custom_target( 152 | ${I18N_NAME}-i18n 153 | COMMENT "${PACKAGE_NAME}-i18n: Done." 154 | DEPENDS ${_gmoFiles} 155 | ) 156 | add_dependencies(${PACKAGE_NAME} ${I18N_NAME}-i18n) 157 | endif (GETTEXT_MSGFMT_EXECUTABLE) 158 | 159 | set(CMLOC ${SAVE_CMLOC}) 160 | -------------------------------------------------------------------------------- /cmake/android-aarch64-toolchain.cmake: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Summary: Cmake toolchain file for android arm64 3 | # License: GPLv3+ 4 | # Copyright (c) 2021 Alec Leamas 5 | # ~~~ 6 | 7 | # This program is free software; you can redistribute it and/or modify it under 8 | # the terms of the GNU General Public License as published by the Free Software 9 | # Foundation; either version 3 of the License, or (at your option) any later 10 | # version. 11 | 12 | set(CMAKE_SYSTEM_NAME Android) 13 | set(CMAKE_SYSTEM_VERSION 21) 14 | set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) 15 | if (DEFINED ENV{NDK_HOME}) 16 | set(CMAKE_ANDROID_NDK $ENV{NDK_HOME}) 17 | else () 18 | set(CMAKE_ANDROID_NDK /opt/android/ndk) 19 | endif () 20 | 21 | set(ARM_ARCH 22 | aarch64 23 | CACHE STRING "Selected arm architecture" FORCE 24 | ) 25 | -------------------------------------------------------------------------------- /cmake/android-armhf-toolchain.cmake: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Summary: Cmake toolchain file for 32-bit android armhf 3 | # License: GPLv3+ 4 | # Copyright (c) 2021 Alec Leamas 5 | # ~~~ 6 | 7 | # This program is free software; you can redistribute it and/or modify it under 8 | # the terms of the GNU General Public License as published by the Free Software 9 | # Foundation; either version 3 of the License, or (at your option) any later 10 | # version. 11 | 12 | set(CMAKE_SYSTEM_NAME Android) 13 | set(CMAKE_SYSTEM_VERSION 21) 14 | set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a) 15 | if (DEFINED ENV{NDK_HOME}) 16 | set(CMAKE_ANDROID_NDK $ENV{NDK_HOME}) 17 | else () 18 | set(CMAKE_ANDROID_NDK /opt/android/ndk) 19 | endif () 20 | set(ARM_ARCH 21 | armhf 22 | CACHE STRING "Selected arm architecture" FORCE 23 | ) 24 | -------------------------------------------------------------------------------- /cmake/fix-macos-libs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Adjust absolute paths to wxWidgets libraries to match their 4 | # location ot the target MacOS system where they are installed 5 | # as part of OpenCPN 6 | 7 | readonly RUNTIME_PATH="@executable_path/../Frameworks/" 8 | 9 | plugin=$(find . -maxdepth 1 -name '*.dylib') 10 | for lib in $(otool -L "$plugin" | awk ' /wx/ {print $1}'); do 11 | libdir=${lib%/*} 12 | if [ "$libdir" = "$lib" ]; then 13 | continue 14 | elif [ "$libdir" != "$RUNTIME_PATH" ]; then 15 | runtime_lib=$(echo $lib | sed "s|$libdir|$RUNTIME_PATH|") 16 | install_name_tool -change "$lib" "$runtime_lib" "$plugin" 17 | fi 18 | done 19 | echo "fix-macos-libs.sh: Revised library paths:" 20 | otool -L "$plugin" | grep wx 21 | -------------------------------------------------------------------------------- /cmake/in-files/PluginCPackOptions.cmake.in: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------------------------- 2 | # Author: Jon Gough Copyright: 2020 License: GPLv3+ 3 | # --------------------------------------------------------------------------- 4 | 5 | # This file contains changes needed during the make package process depending on the type of package being created 6 | 7 | if(CPACK_GENERATOR MATCHES "DEB") 8 | set(CPACK_PACKAGE_FILE_NAME "@PACKAGING_NAME@") 9 | if(CPACK_DEBIAN_PACKAGE_ARCHITECTURE MATCHES "x86_64") 10 | set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE @ARCH_DEB@) 11 | endif() 12 | else() 13 | set(CPACK_PACKAGE_FILE_NAME "@PACKAGING_NAME_XML@") 14 | set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE @ARCH@) 15 | endif() 16 | -------------------------------------------------------------------------------- /cmake/in-files/flatpak_args.in: -------------------------------------------------------------------------------- 1 | # add flatpak-build args in here like this: 2 | #finish-args: 3 | # - --socket=x11 4 | # - --socket=pulseaudio 5 | # - --filesystem=home 6 | # - --device=all 7 | # be carefull about indents and naming. 8 | finish-args: 9 | - --socket=x11 10 | - --socket=pulseaudio 11 | - --filesystem=home 12 | - --device=all 13 | 14 | -------------------------------------------------------------------------------- /cmake/in-files/flatpak_extra_modules.in: -------------------------------------------------------------------------------- 1 | # add flatpak-options args in here like this: 2 | # - name: libusb 3 | # config-opts: 4 | # - --disable-shared 5 | # - --enable-static 6 | # - --disable-udev 7 | # - --prefix=/app/extensions/${PACKAGE} 8 | # sources: 9 | # - type: archive 10 | # url: https://downloads.sourceforge.net/project/libusb/libusb-1.0/libusb-1.0.24/libusb-1.0.24.tar.bz2 11 | # sha256: 7efd2685f7b327326dcfb85cee426d9b871fd70e22caa15bb68d595ce2a2b12a 12 | # cleanup: ["/include", "/lib/*.a", "/lib/*.la", "/lib/pkgconfig"] 13 | # 14 | # be carefull about indents and naming. 15 | -------------------------------------------------------------------------------- /cmake/in-files/flatpak_options.in: -------------------------------------------------------------------------------- 1 | # add flatpak-options args in here like this: 2 | #build-options: 3 | # build-args: 4 | # - --share=network 5 | # be carefull about indents and naming. 6 | build-options: 7 | build-args: 8 | - --share=network 9 | -------------------------------------------------------------------------------- /cmake/in-files/org.opencpn.OpenCPN.Plugin.yaml.in: -------------------------------------------------------------------------------- 1 | id: org.opencpn.OpenCPN.Plugin.${PACKAGE} 2 | runtime: org.opencpn.OpenCPN 3 | runtime-version: ${RUNTIME_VERSION} 4 | sdk: org.freedesktop.Sdk//${SDK_VER} 5 | build-extension: true 6 | separate-locales: false 7 | appstream-compose: false 8 | ${finish_args} 9 | ${build_options} 10 | 11 | modules: 12 | - name: ${PACKAGE} 13 | no-autogen: true 14 | buildsystem: cmake 15 | builddir: true 16 | config-opts: 17 | - -DCMAKE_INSTALL_PREFIX=/app/extensions/${PACKAGE} 18 | - -DOCPN_FLATPAK_BUILD=ON 19 | - -DOCPN_TARGET=${OCPN_TARGET} 20 | - -DSDK_VER=${SDK_VER} 21 | - -DWX_VER=${WX_VER} 22 | build-options: 23 | cflags: -fPIC 24 | cxxflags: -fPIC -DFLATPAK 25 | strip: true 26 | sources: 27 | - type: git 28 | url: https://${GIT_REPOSITORY_SERVER}/${GIT_REPOSITORY} 29 | ${GIT_BRANCH_OR_TAG}: ${GIT_REPOSITORY_ITEM} 30 | ${flatpak_extra_modules} 31 | -------------------------------------------------------------------------------- /cmake/in-files/pkg_version.sh.in: -------------------------------------------------------------------------------- 1 | # 2 | # File is 'sourced' in script files to ensure the correct environment variables are created 3 | # 4 | 5 | VERSION=@PACKAGE_VERSION@.@PKG_RELEASE@ 6 | VERSION_DATE="@GIT_COMMIT_DATE@" 7 | PKG_TARGET=@PKG_TARGET@ 8 | PKG_TARGET_VERSION=@PKG_TARGET_VERSION@ 9 | 10 | # Opencpn api version, part of win32 installer name (major * 100 + minor). 11 | OCPN_API_VERSION=@OCPN_API_VERSION_MAJOR@.@OCPN_API_VERSION_MINOR@ 12 | -------------------------------------------------------------------------------- /cmake/in-files/plugin.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | ${COMMON_NAME} 4 | ${PACKAGE_VERSION} 5 | ${PROJECT_VERSION_TWEAK} 6 | ${XML_SUMMARY} 7 | 8 | ${OCPN_API_VERSION_MAJOR}.${OCPN_API_VERSION_MINOR} 9 | yes 10 | ${PACKAGE_CONTACT} 11 | https://github.com/${GIT_REPOSITORY} 12 | 13 | 14 | ${XML_DESCRIPTION} 15 | 16 | 17 | ${PKG_TARGET_FULL} 18 | ${PKG_BUILD_TARGET} 19 | ${PKG_BUILT_WITH_GTK} 20 | ${PKG_TARGET_VERSION} 21 | ${ARCH} 22 | 23 | ${PKG_URL} 24 | 25 | ${XML_INFO_URL} 26 | 27 | -------------------------------------------------------------------------------- /cmake/in-files/readme.txt: -------------------------------------------------------------------------------- 1 | The files in this directory are not executed but are transformed or used by the build process. 2 | 3 | version.h.in is updated to include the current settings from CMakeLists.txt and put in a location that 4 | is part of the include directory set. Source code that needs these settings just have to use: 5 | #include "version.h" 6 | at/near the top of the source code file. 7 | 8 | the wxWTranslateCatalog.h.in file is used to ensure that the plugins language files are accessed rather than 9 | OpenCPN language files. This allows for change of context of words to be applied correctly. Without this there 10 | can be confusion when a language uses a different word translation in different contexts. 11 | -------------------------------------------------------------------------------- /cmake/in-files/version.h.in: -------------------------------------------------------------------------------- 1 | #define PLUGIN_NAME ${PROJECT_NAME} 2 | #define PLUGIN_CATALOG_NAME wxS("opencpn-${PACKAGE_NAME}") 3 | #define PLUGIN_VERSION_MAJOR ${VERSION_MAJOR} 4 | #define PLUGIN_VERSION_MINOR ${VERSION_MINOR} 5 | #define PLUGIN_VERSION_PATCH ${VERSION_PATCH} 6 | #define PLUGIN_VERSION_TWEAK ${VERSION_TWEAK} 7 | #define PLUGIN_VERSION_DATE "${VERSION_DATE}" 8 | #define PLUGIN_COMMON_NAME "${COMMON_NAME}" 9 | #define PLUGIN_SHORT_DESCRIPTION "${SHORT_DESCRIPTION}" 10 | #define PLUGIN_LONG_DESCRIPTION "${LONG_DESCRIPTION}" 11 | #define PLUGIN_PACKAGE_NAME "${PACKAGE_NAME}" 12 | // API version of OCPN to use 13 | #define OCPN_API_VERSION_MAJOR ${OCPN_API_VERSION_MAJOR} 14 | #define OCPN_API_VERSION_MINOR ${OCPN_API_VERSION_MINOR} 15 | // Include extra version settings if required 16 | ${EXTRA_VERSION_INFO} 17 | -------------------------------------------------------------------------------- /cmake/in-files/wxWTranslateCatalog.h.in: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * $Id: ocpn_draw_pi.h,v 1.0 2015/01/28 01:54:37 jongough Exp $ 3 | * 4 | * Project: OpenCPN 5 | * Purpose: Redefine _() macro to allow usage of catalog 6 | * Author: Jon Gough 7 | * 8 | *************************************************************************** 9 | * Copyright (C) 2010 by David S. Register * 10 | * $EMAIL$ * 11 | * * 12 | * This program is free software; you can redistribute it and/or modify * 13 | * it under the terms of the GNU General Public License as published by * 14 | * the Free Software Foundation; either version 2 of the License, or * 15 | * (at your option) any later version. * 16 | * * 17 | * This program is distributed in the hope that it will be useful, * 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 20 | * GNU General Public License for more details. * 21 | * * 22 | * You should have received a copy of the GNU General Public License * 23 | * along with this program; if not, write to the * 24 | * Free Software Foundation, Inc., * 25 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 26 | *************************************************************************** 27 | */ 28 | #ifndef _PICATTRANS_H_ 29 | #define _PICATTRANS_H_ 30 | 31 | #ifndef WXINTL_NO_GETTEXT_MACRO 32 | #ifdef _ 33 | #undef _ 34 | #endif // _ 35 | #if wxCHECK_VERSION(3,0,0) 36 | #define _(s) wxGetTranslation((s), wxS("opencpn-${PACKAGE_NAME}")) 37 | #else // wxCHECK_VERSION(3,0,0) 38 | #define _(s) wxGetTranslation(wxT(s), wxT("opencpn-${PACKAGE_NAME}")) 39 | #endif // wxCHECK_VERSION(3,0,0) 40 | #endif // WXINTL_NO_GETTEXT_MACRO 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /cmake/readme.txt: -------------------------------------------------------------------------------- 1 | The *.cmake files in this directory provide resources to build the make environment. However, the contents of these 2 | files is mainly static, so this helps reduce the size and complexity of the main CMakeLists.txt file. 3 | 4 | The following files are manadatory for the cmake process to work: 5 | pluginConfigure.cmake 6 | PluginInstall.cmake 7 | PluginLocalization.cmake 8 | PluginPackage.cmake 9 | PluginSetup.cmake 10 | 11 | These file should only be changed with great care as they use generalised processes to handle the generation of the 12 | build environments. If you need to add functionality that you need for your plugin then add extra cmake files here 13 | for your purpose. It is strongly suggested that you do not change these files as if updates to the process are 14 | required it is much easier to do a file replace than identify what has changed. 15 | 16 | An example of an 'extra' cmake file can be seen with: 17 | FindTinyXML.cmake 18 | 19 | Extra files are added to the CMakeLists.txt file by using an include statement such as: 20 | include("cmake/FindTinyXML.cmake") 21 | 22 | Please be case sensitive as it may work on windows builds without this but Linux builds will not. 23 | -------------------------------------------------------------------------------- /data/boat-grey.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 83 | 97 | 100 | 104 | 105 | 106 | 110 | 113 | 117 | 118 | 119 | 123 | 126 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /data/boat-white.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 83 | 97 | 100 | 104 | 105 | 106 | 110 | 113 | 117 | 118 | 119 | 123 | 126 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /data/pypilot.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 84 | 99 | 103 | 107 | 108 | 109 | 114 | 118 | 122 | 123 | 124 | 129 | 133 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /data/pypilot_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypilot/pypilot_pi/cf25bb4e8167462fdc2882334c95dc9dee47ef4c/data/pypilot_panel.png -------------------------------------------------------------------------------- /data/pypilot_rollover.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 84 | 99 | 103 | 107 | 108 | 109 | 114 | 118 | 122 | 123 | 124 | 129 | 133 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /data/pypilot_toggled.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 84 | 99 | 103 | 107 | 108 | 109 | 114 | 118 | 122 | 123 | 124 | 129 | 133 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /libs/wxservdisc/AUTHORS: -------------------------------------------------------------------------------- 1 | Christian Beier 2 | Jer 3 | -------------------------------------------------------------------------------- /libs/wxservdisc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | 3 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 4 | 5 | option(WXSERVDISC_INSTALL "Generate installation target" ON) 6 | 7 | add_subdirectory(src) 8 | #add_subdirectory(examples) 9 | 10 | 11 | ########### install files ############### 12 | 13 | if(WXSERVDISC_INSTALL) 14 | install(FILES README.md AUTHORS NEWS DESTINATION doc/wxservdisc) 15 | endif() 16 | 17 | -------------------------------------------------------------------------------- /libs/wxservdisc/NEWS: -------------------------------------------------------------------------------- 1 | 2 | wxServDisc 0.3 3 | * Now closes sockets properly. 4 | * Lookups should now be faster. 5 | * Some more code cleanups. 6 | 7 | wxServDisc 0.2 8 | * Initial public release. 9 | -------------------------------------------------------------------------------- /libs/wxservdisc/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/bk138/wxservdisc.svg?branch=master)](https://travis-ci.org/bk138/wxservdisc) [![Build status](https://ci.appveyor.com/api/projects/status/f9bga2cpp77m2ab7?svg=true)](https://ci.appveyor.com/project/bk138/wxservdisc) 2 | 3 | 4 | wxServDisc - a wxwidgets zeroconf service discovery module 5 | ========================================================== 6 | 7 | API: 8 | --- 9 | 10 | // type can be one of QTYPE_A, QTYPE_NS, QTYPE_CNAME, QTYPE_PTR or QTYPE_SRV 11 | wxServDisc(void* parent, const wxString& what, int type); 12 | ~wxServDisc(); 13 | 14 | // yeah well... 15 | std::vector getResults() const; 16 | size_t getResultCount() const; 17 | 18 | // get query name 19 | const wxString& getQuery() const { const wxString& ref = query; return ref; }; 20 | // get error string 21 | const wxString& getErr() const { const wxString& ref = err; return ref; }; 22 | 23 | 24 | Typically you would do a three-stage query when looking up the address of a 25 | service instance (look into sdwrap sample to see how it's done...): 26 | 27 | wxServDisc *servscan = new wxServDisc(this, wxT("_rfb._tcp.local."), QTYPE_PTR); 28 | wxServDisc namescan(0, servscan->getResults().at(0).name, QTYPE_SRV); 29 | wxServDisc addrscan(0, namescan.getResults().at(0).name;, QTYPE_A); 30 | wxString addr = addrscan.getResults().at(0).ip; 31 | 32 | 33 | Ah yes and a wxServDisc instance sends a custom event when sth. is discovered. 34 | so you have to add it to your event table, if you want to use it: 35 | 36 | // map recv of wxServDiscNOTIFY to some method 37 | BEGIN_EVENT_TABLE(MyFrameMain, FrameMain) 38 | EVT_COMMAND (wxID_ANY, wxServDiscNOTIFY, MyFrameMain::onSDNotify) 39 | END_EVENT_TABLE() 40 | 41 | In that event listener function, you can then call getResults(). 42 | 43 | 44 | wxServDisc uses mdnsd (C) Jer internally. 45 | 46 | 47 | 48 | 49 | BUILDING: 50 | -------- 51 | 52 | 53 | Prerequisites: wxWidgets >= 2.8 54 | 55 | wxServDisc uses CMake as its build system. Thus, it's the usual: 56 | 57 | mkdir build 58 | cd build 59 | cmake .. 60 | make 61 | 62 | from the root of the source tree. 63 | 64 | 65 | 66 | That's it, have fun! 67 | 68 | christian beier 69 | 70 | -------------------------------------------------------------------------------- /libs/wxservdisc/src/1035.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" 3 | { 4 | #endif 5 | 6 | #ifndef _1035_h 7 | #define _1035_h 8 | 9 | 10 | 11 | // be familiar with rfc1035 if you want to know what all the variable names mean, but this hides most of the dirty work 12 | // all of this code depends on the buffer space a packet is in being 4096 and zero'd before the packet is copied in 13 | // also conveniently decodes srv rr's, type 33, see rfc2782 14 | 15 | // should be reasonably large, for udp 16 | #define MAX_PACKET_LEN 4000 17 | 18 | struct question 19 | { 20 | unsigned char *name; 21 | unsigned short int type, rr_class; 22 | }; 23 | 24 | #define QTYPE_A 1 25 | #define QTYPE_NS 2 26 | #define QTYPE_CNAME 5 27 | #define QTYPE_PTR 12 28 | #define QTYPE_SRV 33 29 | 30 | struct resource 31 | { 32 | unsigned char *name; 33 | unsigned short int type, rr_class; 34 | unsigned long int ttl; 35 | unsigned short int rdlength; 36 | unsigned char *rdata; 37 | union { 38 | struct { unsigned long int ip; char *name; } a; 39 | struct { unsigned char *name; } ns; 40 | struct { unsigned char *name; } cname; 41 | struct { unsigned char *name; } ptr; 42 | struct { unsigned short int priority, weight, port; unsigned char *name; } srv; 43 | } known; 44 | }; 45 | 46 | struct message 47 | { 48 | // external data 49 | unsigned short int id; 50 | struct { unsigned short qr:1, opcode:4, aa:1, tc:1, rd:1, ra:1, z:3, rcode:4; } header; 51 | unsigned short int qdcount, ancount, nscount, arcount; 52 | struct question *qd; 53 | struct resource *an, *ns, *ar; 54 | 55 | // internal variables 56 | unsigned char *_buf, *_labels[20]; 57 | int _len, _label; 58 | 59 | // packet acts as padding, easier mem management 60 | unsigned char _packet[MAX_PACKET_LEN]; 61 | }; 62 | 63 | // returns the next short/long off the buffer (and advances it) 64 | unsigned short int net2short(unsigned char **buf); 65 | unsigned long int net2long(unsigned char **buf); 66 | 67 | // copies the short/long into the buffer (and advances it) 68 | void short2net(unsigned short int i, unsigned char **buf); 69 | void long2net(unsigned long int l, unsigned char **buf); 70 | 71 | // parse packet into message, packet must be at least MAX_PACKET_LEN and message must be zero'd for safety 72 | void message_parse(struct message *m, unsigned char *packet); 73 | 74 | // create a message for sending out on the wire 75 | struct message *message_wire(void); 76 | 77 | // append a question to the wire message 78 | void message_qd(struct message *m, unsigned char *name, unsigned short int type, unsigned short int rr_class); 79 | 80 | // append a resource record to the message, all called in order! 81 | void message_an(struct message *m, unsigned char *name, unsigned short int type, unsigned short int rr_class, unsigned long int ttl); 82 | void message_ns(struct message *m, unsigned char *name, unsigned short int type, unsigned short int rr_class, unsigned long int ttl); 83 | void message_ar(struct message *m, unsigned char *name, unsigned short int type, unsigned short int rr_class, unsigned long int ttl); 84 | 85 | // append various special types of resource data blocks 86 | void message_rdata_long(struct message *m, unsigned long int l); 87 | void message_rdata_name(struct message *m, unsigned char *name); 88 | void message_rdata_srv(struct message *m, unsigned short int priority, unsigned short int weight, unsigned short int port, unsigned char *name); 89 | void message_rdata_raw(struct message *m, unsigned char *rdata, unsigned short int rdlength); 90 | 91 | // return the wire format (and length) of the message, just free message when done 92 | unsigned char *message_packet(struct message *m); 93 | int message_packet_len(struct message *m); 94 | 95 | 96 | #endif // 1035_H 97 | 98 | 99 | #ifdef __cplusplus 100 | } 101 | #endif 102 | -------------------------------------------------------------------------------- /libs/wxservdisc/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # source and targets 4 | # 5 | SET(wxservdisc_LIB_SRCS 6 | 1035.c 7 | mdnsd.c 8 | wxServDisc.cpp 9 | wxServDisc.h 10 | 1035.h 11 | mdnsd.h 12 | ) 13 | 14 | SET(CMAKE_CXX_FLAGS "-fPIC") 15 | 16 | add_library(wxservdisc STATIC ${wxservdisc_LIB_SRCS}) 17 | 18 | 19 | # 20 | # dependencies 21 | # 22 | find_package(wxWidgets REQUIRED core base net) 23 | include(${wxWidgets_USE_FILE}) 24 | target_link_libraries(wxservdisc ${wxWidgets_LIBRARIES}) 25 | 26 | 27 | 28 | #target_link_libraries(wxservdisc ws2_32) 29 | 30 | #set_target_properties(wxservdisc PROPERTIES VERSION 4.2.0 SOVERSION 4) 31 | 32 | 33 | # 34 | # installation 35 | # 36 | if(WXSERVDISC_INSTALL) 37 | install(TARGETS wxservdisc DESTINATION lib) 38 | 39 | install(FILES wxServDisc.h DESTINATION include) 40 | endif() 41 | -------------------------------------------------------------------------------- /libs/wxservdisc/src/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Makefile.am -- Process this file with automake to produce Makefile.in 2 | 3 | 4 | lib_LTLIBRARIES = libwxservdisc.la 5 | libwxservdisc_la_SOURCES = 1035.c mdnsd.c wxServDisc.cpp 1035.h mdnsd.h 6 | include_HEADERS = wxServDisc.h 7 | libwxservdisc_la_CFLAGS = -g -Wall 8 | libwxservdisc_la_CXXFLAGS = -g -Wall 9 | libwxservdisc_la_CPPFLAGS = $(WX_CPPFLAGS) 10 | libwxservdisc_la_LDFLAGS = $(WX_LDFLAGS) 11 | if MINGW 12 | libwxservdisc_la_LIBADD = -lws2_32 13 | libwxservdisc_la_LDFLAGS += -no-undefined -version-info 0:3:0 -static-libgcc -static-libstdc++ 14 | endif 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /libs/wxservdisc/src/README.mdnsd: -------------------------------------------------------------------------------- 1 | mdnsd - embeddable Multicast DNS Daemon 2 | 3 | This package is intended for software developers and integrators, there isn't really anything here for an end 4 | user. More info is available at http://dotlocal.org/mdnsd/ or by emailing me. The license is GPL and BSD, with 5 | alternative licensing available upon request if needed. 6 | 7 | You should be able to just type make and it will build the included example apps. Otherwise, check out mdnsd.h 8 | to get started, the API is as simple as I could make it, but I hope to find some easier/better ways to improve it 9 | in the future. Also included are some other utilities, sdtxt.* for service discovery TXT record 10 | parsing/generation, and xht.* for simple fast hashtables, and 1035.* which mdnsd uses for standalone dns parsing. 11 | 12 | Jer 13 | jer@jabber.org 14 | -------------------------------------------------------------------------------- /libs/wxservdisc/src/TODO.mdnsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | - calling flush() regularly? 4 | - registering several queries on _one_ mdnsd? - seems not to work...bug in mdnsd 5 | - maybe steal from mdns-scan or jdns... 6 | -------------------------------------------------------------------------------- /libs/wxservdisc/src/mdnsd.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" 3 | { 4 | #endif 5 | 6 | #ifndef mdnsd_h 7 | #define mdnsd_h 8 | #include "1035.h" 9 | 10 | 11 | typedef struct mdnsd_struct *mdnsd; // main daemon data 12 | typedef struct mdnsdr_struct *mdnsdr; // record entry 13 | // answer data 14 | typedef struct mdnsda_struct 15 | { 16 | unsigned char *name; 17 | unsigned short int type; 18 | unsigned long int ttl; 19 | unsigned short int rdlen; 20 | unsigned char *rdata; 21 | unsigned long int ip; // A 22 | unsigned char *rdname; // NS/CNAME/PTR/SRV 23 | struct { unsigned short int priority, weight, port; } srv; // SRV 24 | } *mdnsda; 25 | 26 | /////////// 27 | // Global functions 28 | // 29 | // create a new mdns daemon for the given class of names (usually 1) and maximum frame size 30 | mdnsd mdnsd_new(int rr_class, int frame); 31 | // 32 | // gracefully shutdown the daemon, use mdnsd_out() to get the last packets 33 | void mdnsd_shutdown(mdnsd d); 34 | // 35 | // flush all cached records (network/interface changed) 36 | void mdnsd_flush(mdnsd d); 37 | // 38 | // free given mdnsd (should have used mdnsd_shutdown() first!) 39 | void mdnsd_free(mdnsd d); 40 | // 41 | /////////// 42 | 43 | /////////// 44 | // I/O functions 45 | // 46 | // incoming message from host (to be cached/processed) 47 | void mdnsd_in(mdnsd d, struct message *m, unsigned long int ip, unsigned short int port); 48 | // 49 | // outgoing messge to be delivered to host, returns >0 if one was returned and m/ip/port set 50 | int mdnsd_out(mdnsd d, struct message *m, unsigned long int *ip, unsigned short int *port); 51 | // 52 | // returns the max wait-time until mdnsd_out() needs to be called again 53 | struct timeval *mdnsd_sleep(mdnsd d); 54 | // 55 | //////////// 56 | 57 | /////////// 58 | // Q/A functions 59 | // 60 | // register a new query 61 | // answer(record, arg) is called whenever one is found/changes/expires (immediate or anytime after, mdnsda valid until ->ttl==0) 62 | // either answer returns -1, or another mdnsd_query with a NULL answer will remove/unregister this query 63 | void mdnsd_query(mdnsd d, char *host, int type, int (*answer)(mdnsda a, void *arg), void *arg); 64 | // 65 | // returns the first (if last == NULL) or next answer after last from the cache 66 | // mdnsda only valid until an I/O function is called 67 | mdnsda mdnsd_list(mdnsd d, char *host, int type, mdnsda last); 68 | // 69 | /////////// 70 | 71 | /////////// 72 | // Publishing functions 73 | // 74 | // create a new unique record (try mdnsda_list first to make sure it's not used) 75 | // conflict(arg) called at any point when one is detected and unable to recover 76 | // after the first data is set_*(), any future changes effectively expire the old one and attempt to create a new unique record 77 | mdnsdr mdnsd_unique(mdnsd d, char *host, int type, long int ttl, void (*conflict)(char *host, int type, void *arg), void *arg); 78 | // 79 | // create a new shared record 80 | mdnsdr mdnsd_shared(mdnsd d, char *host, int type, long int ttl); 81 | // 82 | // de-list the given record 83 | void mdnsd_done(mdnsd d, mdnsdr r); 84 | // 85 | // these all set/update the data for the given record, nothing is published until they are called 86 | void mdnsd_set_raw(mdnsd d, mdnsdr r, char *data, int len); 87 | void mdnsd_set_host(mdnsd d, mdnsdr r, char *name); 88 | void mdnsd_set_ip(mdnsd d, mdnsdr r, unsigned long int ip); 89 | void mdnsd_set_srv(mdnsd d, mdnsdr r, int priority, int weight, int port, char *name); 90 | // 91 | /////////// 92 | 93 | 94 | #endif 95 | 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | -------------------------------------------------------------------------------- /libs/wxservdisc/src/wxServDisc.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | /* 3 | wxServDisc.h: wxServDisc API definition 4 | 5 | This file is part of wxServDisc, a crossplatform wxWidgets 6 | Zeroconf service discovery module. 7 | 8 | Copyright (C) 2008 Christian Beier 9 | 10 | wxServDisc is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; either version 2 of the License, or 13 | (at your option) any later version. 14 | 15 | wxServDisc is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | You should have received a copy of the GNU General Public License 21 | along with this program; if not, write to the Free Software 22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 | */ 24 | 25 | #ifndef WXSERVDISC_H 26 | #define WXSERVDISC_H 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "1035.h" 35 | #include "mdnsd.h" 36 | 37 | // all the nice socket includes in one place here 38 | #ifdef _WIN32 39 | // https://stackoverflow.com/questions/5004858/stdmin-gives-error 40 | #define NOMINMAX 41 | // mingw/ visual studio socket includes 42 | //#include 43 | //#include 44 | #define SHUT_RDWR SD_BOTH 45 | #else // proper UNIX 46 | typedef int SOCKET; // under windows, SOCKET is unsigned 47 | #define INVALID_SOCKET -1 // so there also is no -1 return value 48 | #define closesocket(s) close(s) // under windows, it's called closesocket 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #endif 56 | 57 | 58 | 59 | 60 | // make available custom notify event if getResults() would yield sth new 61 | #if wxVERSION_NUMBER < 2900 62 | DECLARE_EVENT_TYPE(wxServDiscNOTIFY, -1); 63 | #else 64 | wxDECLARE_EVENT(wxServDiscNOTIFY, wxCommandEvent); 65 | #endif 66 | 67 | 68 | 69 | 70 | // resource name with ip addr and port number 71 | struct wxSDEntry 72 | { 73 | wxString name; 74 | wxString ip; 75 | int port; 76 | long time; 77 | wxSDEntry() { port=0; time=0; } 78 | }; 79 | 80 | 81 | 82 | // our main class 83 | class wxServDisc: public wxObject, public wxThreadHelper 84 | { 85 | public: 86 | // type can be one of QTYPE_A, QTYPE_NS, QTYPE_CNAME, QTYPE_PTR or QTYPE_SRV 87 | wxServDisc(void* parent, const wxString& what, int type); 88 | ~wxServDisc(); 89 | 90 | /// Returns true if service discovery successfully started. If not, getErr() may contain a hint. 91 | bool isOK() const { return err.length() == 0; }; 92 | 93 | // yeah well... 94 | std::vector getResults() const; 95 | size_t getResultCount() const; 96 | 97 | // get query name 98 | const wxString& getQuery() const { const wxString& ref = query; return ref; }; 99 | // get error string 100 | const wxString& getErr() const { const wxString& ref = err; return ref; }; 101 | 102 | 103 | private: 104 | SOCKET mSock; 105 | wxString err; 106 | void *parent; 107 | wxString query; 108 | int querytype; 109 | WX_DECLARE_STRING_HASH_MAP(wxSDEntry, wxSDMap); 110 | wxSDMap results; 111 | wxStopWatch mWallClock; 112 | 113 | // this runs as a separate thread 114 | virtual wxThread::ExitCode Entry(); 115 | 116 | // create a multicast 224.0.0.251:5353 socket, windows or unix style 117 | SOCKET msock(); 118 | // send/receive message m 119 | bool sendm(struct message *m, SOCKET s, unsigned long int ip, unsigned short int port); 120 | int recvm(struct message *m, SOCKET s, unsigned long int *ip, unsigned short int *port); 121 | // callback for the mdns resolver 122 | static int ans(mdnsda a, void *caller); 123 | 124 | void post_notify(); 125 | }; 126 | 127 | 128 | 129 | #endif // WXSERVDISC_H 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /manual/.gitignore: -------------------------------------------------------------------------------- 1 | docs 2 | -------------------------------------------------------------------------------- /manual/antora.yml: -------------------------------------------------------------------------------- 1 | name: pypilot 2 | title: Pypilot Autopilot 3 | version: ~ 4 | -------------------------------------------------------------------------------- /manual/modules/ROOT/images/pypilot-menus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypilot/pypilot_pi/cf25bb4e8167462fdc2882334c95dc9dee47ef4c/manual/modules/ROOT/images/pypilot-menus.png -------------------------------------------------------------------------------- /manual/modules/ROOT/images/pypilot_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypilot/pypilot_pi/cf25bb4e8167462fdc2882334c95dc9dee47ef4c/manual/modules/ROOT/images/pypilot_icon.png -------------------------------------------------------------------------------- /manual/modules/ROOT/images/pypilot_plugin_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypilot/pypilot_pi/cf25bb4e8167462fdc2882334c95dc9dee47ef4c/manual/modules/ROOT/images/pypilot_plugin_screenshot.png -------------------------------------------------------------------------------- /manual/modules/ROOT/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = Pypilot Autopilot 2 | 3 | image::pypilot_icon.png[] 4 | 5 | == Links 6 | 7 | * Source: https://github.com/pypilot/pypilot_pi + 8 | * Maintenance Source: https://github.com/rgleason/pypilot_pi + 9 | * Download:https://opencpn.org/OpenCPN/plugins/pypilot.html + 10 | * Forum: https://www.cruisersforum.com/forums/f134/pypilot-199337.html[Pypilot Cruiser's Forum Thread] 11 | 12 | == 1. What and Why 13 | 14 | The pypilot plugin provides an interface to the free software autopilot 15 | pypilot. Control, configure and calibrate the autopilot from OpenCPN. 16 | 17 | The Pypilot_pi interface plugin will work with any operating system 18 | running opencpn (Linux, Windows, MacOS, Android are available). The 19 | Pypilot_pi interface plugin is separate and distinct from the plugin 20 | “autopilot_route_pi”. 21 | 22 | The pypilot server that pypilot_pi connects to, so far typically runs on 23 | raspberry pi, but it can work on orange pi or potentially other systems 24 | as well. 25 | 26 | Note: OpenCPN can communicate with pypilot server already via nmea to 27 | receive compass heading, and to autopilot, so this plugin is not 28 | strictly required. 29 | 30 | This plugin allows for configuration and tuning of the 31 | autopilot in ways not possible through basic nmea0183 messaging. The 32 | plugin also allows for graphical overlays of the autopilot settings 33 | directly onto the chart. 34 | 35 | image::pypilot_plugin_screenshot.png[] 36 | 37 | == 2. Installation 38 | 39 | The OpenCPN Manual has general information in xref:opencpn-plugins:misc:plugin-install.adoc[Plugin Download, Install and Enable] for installing this plugin. 40 | 41 | == 3. Other Information 42 | 43 | OpenCPN Plugin for Pypilot Autopilots An OpenSource Marine Autopilot. 44 | 45 | * https://pypilot.org/wiki/doku.php[PyPilot Website (Hardware and Software] 46 | * https://github.com/pypilot/pypilot[Github Repository] (Python & C++) 47 | * https://github.com/pypilot/pypilot/wiki/Hardware[Hardware] 48 | * Example: Pypilot is tested and working on a trimaran sailing at 15 knots. 49 | * Example: https://youtu.be/KQuBwLSMSxI[Video: Pypilot on Princess Mia] 50 | 51 | 52 | == 4. Capable of steering under sail in harbors. 53 | 54 | The autopilot route plugin capable of steering under sail in harbors 55 | 56 | * Example: 57 | https://phoenixketch.blogspot.com/2019/01/pypilot-open-source-marine-autopilot.html[Hydraulic 58 | Installation: S/V Phoenix [Ketch] with Pypilot] 59 | 60 | == 5. PyPilot Forums 61 | 62 | * https://www.cruisersforum.com/forums/f134/pypilot-199337.html[Pypilot Cruiser's Forum Thread] 63 | * https://www.cruisersforum.com/forums/f134/autopilot-open-source-191315.html[Cruiser's Forum Autopilot - Open Source] 64 | * https://www.cruisersforum.com/forums/f13/free-autopilot-186378.html[Cruiser's Forum Free Autopilot Discussion] 65 | * https://forum.openmarine.net/forumdisplay.php?fid=17[PyPilot OpenMarine Forum] 66 | * https://www.cruisersforum.com/forums/f134/opencpn-and-arduboat-199849.html[PyPilot with Arduboat Discussion] 67 | 68 | Sean D'Epagnier's https://github.com/pypilot/pypilot/wiki/autopilot_computer[PyPilot AutoPilot] using raspberry zero-W or orange, 69 | 70 | * https://github.com/pypilot/pypilot/wiki/controller[Controller], 71 | * https://github.com/pypilot/pypilot/wiki/imu[IMU] with 72 | * https://github.com/pypilot/pypilot/wiki/LCD_keypad[Optional user 73 | interface LCD and keypad], gps and weather sensors. 74 | 75 | https://github.com/pypilot/pypilot/wiki/webapp[Pypilot Webapp] if using 76 | tinypilot, creates a webserver which provides remote autopilot control 77 | through a browser. Trimaran test used rtlsdr IR remote for control. It 78 | can use any tv remote, also buttons, or gui program through openplotter. 79 | 80 | This Autopilot uses modified and improved versions of SignalK and 81 | RTMUlib2. More details are available in the 82 | 83 | * https://github.com/pypilot/pypilot/wiki[Wiki] 84 | * https://github.com/pypilot/pypilot/blob/master/README[README] 85 | 86 | image::pypilot-menus.png[] 87 | 88 | == 6. PyPilot Integrated Hardware Shop 89 | 90 | https://pypilot.org/store/[Pypilot Store] 91 | 92 | * PyPilot Motor Controller 93 | * TinyPilot Computer 94 | * Minimal wind sensor - Wind speed and direction 95 | * Weather Sensors with Display - Wind and Barometric Pressure 96 | * The wind sensor uses http://www.sailsmarine.com/ItemDetail.aspx?c=196659&l=g[Davis 6410 Wind 97 | instrument] 98 | 99 | https://www.tindie.com/stores/seandepagnier/[Tindie Store] 100 | 101 | * Orange pi Zero IMU Hat mpu9255 9DOF inertial sensor 102 | * Raspberry pi Nokia 5110 LCD Hat 103 | * Orange pi Nokia 5110 LCD Hat 104 | * Raspberry pi Zero IMU Hat mpu9255 9DOF inertial sensor 105 | 106 | Another favorite rpi from the Tindie Store is 107 | https://www.tindie.com/products/astuder/daisy-hat-ais-receiver-for-raspberry-pi/[dAISy 108 | HAT AIS Receiver for Raspberry Pi] 109 | 110 | Pypilot is free software like Opencpn and it is fully supported by 111 | opencpn, and is better supported than any autopilot. It has 2 112 | specialized opencpn plugins designed for it. For the cost of a raspberry 113 | pi, some $4 sensors, and a motor controller you can build, or buy for 114 | $75 and just use a windshield wiper motor and a belt to the wheel, or if 115 | you have a tiller: 116 | 117 | See https://youtu.be/ZaLBRRelT-M 118 | -------------------------------------------------------------------------------- /manual/site.yml: -------------------------------------------------------------------------------- 1 | site: 2 | title: PyPilot Autopilot 3 | url: https://nowhere.net 4 | start_page: pypilot:ROOT:index.adoc 5 | 6 | content: 7 | sources: 8 | - url: .. 9 | start_path: manual 10 | branches: HEAD 11 | edit_url: https://github.com/opencpn-manuals/pypilot_pi/edit/master/{path} 12 | 13 | ui: 14 | bundle: 15 | url: https://gitlab.com/leamas/antora-ui-default/-/raw/master/latest/ui-bundle.zip 16 | snapshot: true 17 | 18 | output: 19 | dir: ./docs 20 | clean: true 21 | -------------------------------------------------------------------------------- /mingw/fedora/README.md: -------------------------------------------------------------------------------- 1 | What's here? 2 | ============ 3 | 4 | Tools to build a windows 32-bit executable using the mingw toolchain. 5 | 6 | How? 7 | ==== 8 | $ sudo dnf copr enable /opencpn-mingw 9 | $ sudo dnf builddep opencpn-deps.spec 10 | $ cd ../.. 11 | $ rm -rf build; mkdir build 12 | $ cd build; 13 | $ cmake -DCMAKE_TOOLCHAIN_FILE=../mingw/fedora/toolchain.cmake .. 14 | $ make 15 | $ make package 16 | 17 | Notes: 18 | ===== 19 | The build requires updated packages, notably wx3GTK, available at 20 | https://copr.fedorainfracloud.org/coprs/leamas/opencpn-mingw. 21 | The copr enable command above sets up access to this repo. 22 | -------------------------------------------------------------------------------- /mingw/fedora/opencpn-deps.spec: -------------------------------------------------------------------------------- 1 | Name: opencpn-deps 2 | Version: 0.1 3 | Release: 1%{?dist} 4 | Summary: Empty package with opencpn build dependencies 5 | 6 | License: MIT 7 | URL: https://github.com/leamas/opencpn 8 | 9 | BuildRequires: binutils 10 | BuildRequires: cmake 11 | BuildRequires: gettext 12 | BuildRequires: git 13 | BuildRequires: make 14 | BuildRequires: mingw-binutils-generic 15 | BuildRequires: mingw-filesystem-base 16 | BuildRequires: mingw32-binutils 17 | BuildRequires: mingw32-bzip2 18 | BuildRequires: mingw32-cairo 19 | BuildRequires: mingw32-curl 20 | BuildRequires: mingw32-expat 21 | BuildRequires: mingw32-filesystem 22 | BuildRequires: mingw32-fontconfig 23 | BuildRequires: mingw32-freetype 24 | BuildRequires: mingw32-gcc 25 | BuildRequires: mingw32-gcc-c++ 26 | BuildRequires: mingw32-cpp 27 | BuildRequires: mingw32-gettext 28 | BuildRequires: mingw32-headers 29 | BuildRequires: mingw32-glib2 30 | BuildRequires: mingw32-gtk2 31 | BuildRequires: mingw32-libarchive 32 | BuildRequires: mingw32-libffi 33 | BuildRequires: mingw32-libpng 34 | BuildRequires: mingw32-libtiff 35 | BuildRequires: mingw32-libxml2 36 | BuildRequires: mingw32-nsiswrapper 37 | BuildRequires: mingw32-openssl 38 | BuildRequires: mingw32-pcre 39 | BuildRequires: mingw32-pixman 40 | BuildRequires: mingw32-sqlite 41 | BuildRequires: mingw32-win-iconv 42 | BuildRequires: mingw32-wxWidgets3 >= 3.0.2 43 | BuildRequires: mingw32-xz-libs 44 | BuildRequires: p7zip 45 | BuildRequires: wget 46 | 47 | %description 48 | 49 | Empty package used to catch build dependencies for opencpn using 50 | the mingw tools to create a Windows 32-bit executable 51 | 52 | Use dnf builddep opencpn-deps.spec to install the dependencies. 53 | 54 | %prep 55 | 56 | 57 | %build 58 | 59 | 60 | %install 61 | 62 | 63 | %files 64 | %doc COPYING 65 | 66 | 67 | %changelog 68 | * Fri Mar 01 2019 Alec Leamas - 0.1-1 69 | - Initial release 70 | -------------------------------------------------------------------------------- /mingw/fedora/toolchain.cmake: -------------------------------------------------------------------------------- 1 | # the name of the target operating system 2 | SET(CMAKE_SYSTEM_NAME Windows) 3 | 4 | # which compilers to use for C and C++ 5 | SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc) 6 | SET(CMAKE_CXX_COMPILER i686-w64-mingw32-c++) 7 | SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) 8 | 9 | # here is the target environment located 10 | SET(CMAKE_FIND_ROOT_PATH 11 | /usr/i686-w64-mingw32i;/usr/i686-w64-mingw32/sys-root/mingw) 12 | 13 | # adjust the default behaviour of the FIND_XXX() commands: 14 | # search headers and libraries in the target environment, search 15 | # programs in the host environment 16 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 17 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 18 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 19 | -------------------------------------------------------------------------------- /mingw/readme.txt: -------------------------------------------------------------------------------- 1 | This directory structure is used by the mingw build process script file: 2 | circleci-build-mingw.sh 3 | 4 | If new dependencies for the build need to be added then they should go in the file: 5 | mingw/fedora/opencpn-deps.spec 6 | 7 | These dependencies can be subtally different from the other spec files being used 8 | -------------------------------------------------------------------------------- /msvc/win_deps.bat: -------------------------------------------------------------------------------- 1 | :: Install build dependencies. Requires a working choco installation, 2 | :: see https://docs.chocolatey.org/en-us/choco/setup. 3 | :: 4 | :: Usage: 5 | :: win_deps.bat [wx32] 6 | :: 7 | :: Arguments: 8 | :: wx32: 9 | :: If present install dependencies for building against 10 | :: wxWidgets 3.2. If non-existing or anything but wx32 11 | :: build using 3.1 12 | :: Output: 13 | :: cache\wx-config.bat: 14 | :: Script which set wxWidgets_LIB_DIR and wxWidgets_ROOT_DIR 15 | :: 16 | :: Initial run will do choco installs requiring administrative 17 | :: privileges. 18 | :: 19 | :: NOTE: at the very end, this script runs refreshenv. This clears the 20 | :: process's PATH and replaces it with a fresh copy from the 21 | :: registry. This means that any "set PATH=..." is lost for caller. 22 | 23 | :: Install the pathman tool: https://github.com/therootcompany/pathman 24 | :: Fix PATH so it can be used in this script 25 | :: 26 | 27 | @echo off 28 | echo In win_deps 29 | 30 | setlocal enabledelayedexpansion 31 | 32 | if not exist %SCRIPTDIR%\..\cache ( mkdir %SCRIPTDIR%\..\cache ) 33 | set "CONFIG_FILE=%SCRIPTDIR%\..\cache\wx-config.bat" 34 | set EXTRA_PATH= 35 | 36 | git --version > nul 2>&1 37 | if errorlevel 1 ( 38 | set "GIT_HOME=C:\Program Files\Git" 39 | if not exist "!GIT_HOME!" choco install -y git 40 | ) 41 | echo done git 42 | :: Install choco cmake and add it's persistent user path element 43 | :: 44 | cmake --version > nul 2>&1 45 | if errorlevel 1 ( 46 | set "CMAKE_HOME=C:\Program Files\CMake" 47 | choco install -y --no-progress cmake 48 | set "EXTRA_PATH=%CMAKE_HOME%\bin;%EXTRA_PATH%" 49 | ) 50 | 51 | :: Install choco poedit and add it's persistent user path element 52 | :: 53 | set "POEDIT_HOME=C:\Program Files (x86)\Poedit\GettextTools" 54 | if not exist "%POEDIT_HOME%" (choco install -y poedit) 55 | dir "%POEDIT_HOME%" 56 | set "EXTRA_PATH=%POEDIT_HOME%\bin;%EXTRA_PATH%" 57 | 58 | :: Update required python stuff 59 | :: 60 | echo doing python 61 | python --version > nul 2>&1 && python -m ensurepip > nul 2>&1 62 | if errorlevel 1 choco install -y python 63 | python --version 64 | python -m ensurepip 65 | python -m pip install --upgrade pip 66 | python -m pip install -q setuptools wheel 67 | python -m pip install -q cloudsmith-cli 68 | python -m pip install -q cryptography 69 | 70 | :: Install pre-compiled wxWidgets and other DLL; add required paths. 71 | :: 72 | set SCRIPTDIR=%~dp0 73 | if "%~1"=="wx32" ( 74 | set "WXWIN=%SCRIPTDIR%..\cache\wxWidgets-3.2.1" 75 | set "wxWidgets_ROOT_DIR=!WXWIN!" 76 | set "wxWidgets_LIB_DIR=!WXWIN!\lib\vc14x_dll" 77 | set "TARGET_TUPLE=msvc-wx32" 78 | ) else ( 79 | set "WXWIN=%SCRIPTDIR%..\cache\wxWidgets-3.1.2" 80 | set "wxWidgets_ROOT_DIR=!WXWIN!" 81 | set "wxWidgets_LIB_DIR=!WXWIN!\lib\vc_dll" 82 | set "TARGET_TUPLE=msvc" 83 | ) 84 | 85 | :: Add settings to CONFIG_FILE to allow them to be set in the calling batch file 86 | echo set "EXTRA_PATH=%EXTRA_PATH%" > %CONFIG_FILE% 87 | echo set "wxWidgets_ROOT_DIR=%wxWidgets_ROOT_DIR%" >> %CONFIG_FILE% 88 | echo set "wxWidgets_LIB_DIR=%wxWidgets_LIB_DIR%" >> %CONFIG_FILE% 89 | echo set "TARGET_TUPLE=%TARGET_TUPLE%" >> %CONFIG_FILE% 90 | 91 | if not exist "%WXWIN%" ( 92 | wget --version > nul 2>&1 || choco install -y wget 93 | if "%~1"=="wx32" ( 94 | echo Downloading 3.2.1 95 | if not exist %SCRIPTDIR%..\cache\wxWidgets-3.2.1 ( 96 | mkdir %SCRIPTDIR%..\cache\wxWidgets-3.2.1 97 | ) 98 | set "GITHUB_DL=https://github.com/wxWidgets/wxWidgets/releases/download" 99 | wget -nv !GITHUB_DL!/v3.2.1/wxMSW-3.2.1_vc14x_Dev.7z 100 | 7z x -o%SCRIPTDIR%..\cache\wxWidgets-3.2.1 wxMSW-3.2.1_vc14x_Dev.7z 101 | wget -nv !GITHUB_DL!/v3.2.1/wxWidgets-3.2.1-headers.7z 102 | 7z x -o%SCRIPTDIR%..\cache\wxWidgets-3.2.1 wxWidgets-3.2.1-headers.7z 103 | ) else ( 104 | echo Downloading 3.1.2 105 | wget -O wxWidgets-3.1.2.7z -nv ^ 106 | https://download.opencpn.org/s/E2p4nLDzeqx4SdX/download 107 | 7z i > nul 2>&1 || choco install -y 7zip 108 | 7z x wxWidgets-3.1.2.7z -o%WXWIN% 109 | ) 110 | ) 111 | dir cache 112 | type "%CONFIG_FILE%" 113 | refreshenv 114 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | src/pypilot_pi.cpp 2 | src/pypilot_client.cpp 3 | src/pypilotDialog.cpp 4 | src/GainsDialog.cpp 5 | src/ConfigurationDialog.cpp 6 | src/StatisticsDialog.cpp 7 | src/SettingsDialog.cpp 8 | src/pypilotClientDialog.cpp 9 | src/pypilotUI.cpp 10 | src/icons.cpp 11 | src/CalibrationPlot.h 12 | src/ConfigurationDialog.h 13 | src/GainsDialog.h 14 | src/icons.h 15 | src/msvcdefs.h 16 | src/pypilot_client.h 17 | src/pypilot_pi.h 18 | src/pypilotClientDialog.h 19 | src/pypilotDialog.h 20 | src/pypilotUI.h 21 | src/StatisticsDialog.h 22 | src/SettingsDialog.h 23 | src/wxWTranslateCatalog.h 24 | src/CalibrationDialog.cpp 25 | src/CalibrationPlot.cpp 26 | -------------------------------------------------------------------------------- /po/POTFILES.in.test: -------------------------------------------------------------------------------- 1 | src/pypilot_pi.cpp 2 | src/pypilot_client.cpp 3 | src/pypilotDialog.cpp 4 | src/GainsDialog.cpp 5 | src/ConfigurationDialog.cpp 6 | src/StatisticsDialog.cpp 7 | src/SettingsDialog.cpp 8 | src/pypilotClientDialog.cpp 9 | src/pypilotUI.cpp 10 | src/icons.cpp 11 | src/CalibrationPlot.h 12 | src/ConfigurationDialog.h 13 | src/GainsDialog.h 14 | src/icons.h 15 | src/msvcdefs.h 16 | src/pypilot_client.h 17 | src/pypilot_pi.h 18 | src/pypilotClientDialog.h 19 | src/pypilotDialog.h 20 | src/pypilotUI.h 21 | src/StatisticsDialog.h 22 | src/SettingsDialog.h 23 | src/wxWTranslateCatalog.h 24 | src/CalibrationDialog.cpp 25 | src/CalibrationPlot.cpp 26 | -------------------------------------------------------------------------------- /po/trans-po.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | __author__ = 'Rory McCann ' 4 | __version__ = '1.0' 5 | __licence__ = 'GPLv3' 6 | 7 | import polib, subprocess, re, sys, time 8 | 9 | def translate_subpart(string, lang): 10 | """Simple translate for just a certin string""" 11 | 12 | print('translate', string, lang) 13 | translater = subprocess.Popen(['trans', '-b', ':' + lang], stdin=subprocess.PIPE, stdout=subprocess.PIPE) 14 | translater.stdin.write((string+'\n').encode()) 15 | stringout, _ = translater.communicate() 16 | stringout = stringout[:-1].decode("utf8") 17 | 18 | if stringout: 19 | print('translated', string, lang, stringout) 20 | return stringout 21 | time.sleep(1) 22 | print('failed to translate ', string) 23 | return '' 24 | 25 | def translate(string, lang_direction): 26 | """Takes a string that is to be translated and returns the translated string, doesn't translate the %(format)s parts, they must remain the same text as the msgid""" 27 | # simple format chars like %s can be 'translated' ok, they just pass through unaffected 28 | named_format_regex = re.compile(r"%\([^\)]+?\)[sd]", re.VERBOSE) 29 | matches = named_format_regex.findall(string) 30 | new = None 31 | 32 | if len(matches) == 0: 33 | # There are no format specifiers in this string, so just do a straight translation 34 | 35 | # this fails if we've missed a format specifier 36 | assert "%(" not in string, string 37 | 38 | new = translate_subpart(string, lang_direction) 39 | 40 | else: 41 | 42 | # we need to do complicate translation of the bits inside 43 | full_trans = translate_subpart(string, lang_direction) 44 | 45 | for match in matches: 46 | # then, for each format specifier, replace back in the string 47 | 48 | translated_match = translate_subpart(match, lang_direction) 49 | 50 | # during the translation some extra punctuation/spaces might have been added 51 | # remove them 52 | translated_match_match = named_format_regex.search(translated_match) 53 | assert translated_match_match 54 | translated_match = translated_match_match.group(0) 55 | 56 | # put back the format specifier, the case of the format specifier might have changed 57 | replace = re.compile(re.escape(translated_match), re.IGNORECASE) 58 | full_trans = replace.sub(match, full_trans) 59 | 60 | 61 | new = full_trans 62 | 63 | return new 64 | 65 | def translate_po(filename, lang): 66 | """Given a .po file, Translate it""" 67 | pofile = polib.pofile(filename) 68 | 69 | # pretend the same plural forms as English 70 | pofile.metadata['Plural-Forms'] = 'nplurals=2; plural=(n != 1)' 71 | save = False 72 | 73 | try: 74 | for entry in pofile: 75 | 76 | if entry.msgstr: 77 | continue # already translated 78 | if entry.msgid_plural == '': 79 | # not a pluralized string 80 | entry.msgstr = translate(entry.msgid, lang) 81 | if not entry.msgstr: 82 | break 83 | save = True 84 | else: 85 | # pluralised string 86 | # we just pretend to use the same rules as english 87 | entry.msgstr_plural['0'] = translate(entry.msgid, lang) 88 | entry.msgstr_plural['1'] = translate(entry.msgid_plural, lang) 89 | 90 | finally: 91 | if save: 92 | pofile.save(filename) 93 | 94 | if __name__ == '__main__': 95 | translate_po(sys.argv[1] + '_' + sys.argv[2] + '.po', sys.argv[1]) 96 | -------------------------------------------------------------------------------- /po/translate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function translate() { 4 | ./trans-po.py $1 $2 5 | } 6 | 7 | translate ca ES # Catalan 8 | translate da DK # Danish 9 | translate de DE # German 10 | translate el GR # Greek 11 | # translate eo # Esperanto 12 | translate es ES # Spanish 13 | translate fi FI # Finnish 14 | translate fr FR # French 15 | translate it IT # Italian 16 | translate nl NL # Dutch 17 | translate nb NO # Norwegian 18 | translate pl PL # Polish 19 | translate pt PT # Portuguese 20 | translate ru RU # Russian 21 | translate sv SE # Swedish 22 | -------------------------------------------------------------------------------- /run-circleci-local.txt: -------------------------------------------------------------------------------- 1 | circleci local execute build-debian-x86_64-11-bullseye -e CIRCLECI_LOCAL=true -v "/home/jon/opencpn/circleci-output:/home/circleci/circleci-output" -v "/home/jon/opencpn/circleci-cache:/home/circleci/circleci-cache" -e LOCAL_DEPLOY=true -e CLOUDSMITH_API_KEY="123" 2 | -------------------------------------------------------------------------------- /src/CalibrationDialog.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2018 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #include 28 | 29 | #include "pypilotUI.h" 30 | 31 | class pypilot_pi; 32 | 33 | class CalibrationDialog : public CalibrationDialogBase 34 | { 35 | public: 36 | CalibrationDialog( pypilot_pi &_pypilot_pi, wxWindow* parent); 37 | 38 | void Receive(std::string name, Json::Value &value); 39 | std::map &GetWatchlist(); 40 | 41 | private: 42 | void OnPaintAccelPlot( wxPaintEvent& event ) { m_accelCalibrationPlot->OnPaint(); } 43 | void OnPaintCompassPlot( wxPaintEvent& event ) { m_compassCalibrationPlot->OnPaint(); } 44 | void OnMouseEventsAccel( wxMouseEvent& event ); 45 | void OnMouseEventsCompass( wxMouseEvent& event ); 46 | void OnCalibrationLocked( wxCommandEvent& event ); 47 | void OnAboutCalibrationLocked( wxCommandEvent& event ); 48 | void OnClose( wxCommandEvent& event ); 49 | void OnLevel( wxCommandEvent& event ); 50 | void OnAboutLevel( wxCommandEvent& event ); 51 | void UpdateHeadingOffset(wxTimerEvent &); 52 | void OnHeadingOffset( wxSpinEvent& event ); 53 | void OnHeadingOffsetText( wxCommandEvent& event ); 54 | void OnAboutHeadingOffset( wxCommandEvent& event ); 55 | 56 | void RefreshTimer(wxTimerEvent &); 57 | 58 | void RudderCalCommand(const char *command); 59 | void OnRudderCentered( wxCommandEvent& event ) { RudderCalCommand("centered"); } 60 | void OnRudderResetCalibration( wxCommandEvent& event ) { RudderCalCommand("reset"); } 61 | void OnRudderStarboardRange( wxCommandEvent& event ) { RudderCalCommand("starboard range"); } 62 | void OnRudderPortRange( wxCommandEvent& event ) { RudderCalCommand("port range"); } 63 | void OnRudderRange( wxSpinEvent& event ); 64 | void OnAboutRudderCalibration( wxCommandEvent& event ); 65 | 66 | double m_pitch; 67 | 68 | pypilot_pi &m_pypilot_pi; 69 | wxDateTime m_lastOffsetTime; 70 | 71 | wxTimer m_HeadingOffsetTimer; 72 | wxTimer m_refreshtimer; 73 | }; 74 | -------------------------------------------------------------------------------- /src/CalibrationPlot-sean.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2020 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #include 28 | 29 | #include "CalibrationPlot.h" 30 | 31 | bool json_to_float(Json::Value &value, float p[], unsigned int count) 32 | { 33 | if(!value.isArray() || value.size() < count) 34 | return false; 35 | for(unsigned int i=0; i &points) 44 | { 45 | points.clear(); 46 | if(!value.isArray()) 47 | return; 48 | for(unsigned int i=0; i points; 89 | int lats = 16, lons = 32; 90 | for(int lat=1; lat= 20) { 137 | for(int i=0; i<19; i++) 138 | m_recentpoints[i] = m_recentpoints[i+1]; 139 | m_recentpoints.pop_back(); 140 | } 141 | if(json_to_float(value, p.p, 3)) 142 | m_recentpoints.push_back(p); 143 | } else if(name == "imu."+m_name+".calibration.sigmapoints") 144 | json_to_float_3_array(value, m_sigmapoints); 145 | else if(name == "imu."+m_name+".calibration.points") 146 | json_to_float_3_array(value, m_points); 147 | else if(name == "imu."+m_name+".calibration") { 148 | if(value.isArray() && value.size() > 0) 149 | json_to_float(value[0], m_cal, m_name == "accel" ? 4 : 5); 150 | } 151 | } 152 | 153 | void CalibrationPlot::OnPaint() 154 | { 155 | SetCurrent( m_glContext ); 156 | wxPaintDC dc( this ); 157 | 158 | int w, h; 159 | GetClientSize( &w, &h ); 160 | glViewport( 0, 0, (GLint) w, (GLint) h ); 161 | 162 | glMatrixMode(GL_PROJECTION); 163 | glLoadIdentity(); 164 | 165 | float ar = float(w) / float(h); 166 | float fac = .05f; 167 | glFrustum( -fac*ar, fac*ar, -fac, fac, .1, 15 ); 168 | glMatrixMode(GL_MODELVIEW); 169 | 170 | glClearColor(0, 0, 0, 0); 171 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 172 | 173 | glPushMatrix(); 174 | 175 | float s = m_userscale; 176 | if(m_name == "compass") 177 | s*=.016f; 178 | 179 | glScalef(s, s, s); 180 | TranslateAfter( 0, 0, -1 ); 181 | 182 | //glPolygonMode(GL_FRONT_AND_BACK, self.mode) 183 | glLineWidth(1); 184 | 185 | //q = quaternion.multiply(self.fusionQPose, self.alignmentQ) 186 | //down = quaternion.rotvecquat([0, 0, 1], quaternion.conjugate(q)) 187 | //glRotatef(-math.degrees(quaternion.angle(q)), *q[1:]) 188 | 189 | glColor3f(0.0f, .3f, .8f); 190 | glPointSize(1); 191 | glPushMatrix(); 192 | s = m_cal[3]; 193 | glScalef(s, s, s); 194 | 195 | glEnableClientState(GL_VERTEX_ARRAY); 196 | glVertexPointer(3, GL_FLOAT, 0, m_sphere); 197 | glDrawArrays(GL_LINE_STRIP, 0, m_spherepoints); 198 | glDisableClientState(GL_VERTEX_ARRAY); 199 | glPopMatrix(); 200 | 201 | glTranslatef(-m_cal[0], -m_cal[1], -m_cal[2]); 202 | 203 | glColor3f(1, 1, 0); 204 | glPointSize(4); 205 | glBegin(GL_POINTS); 206 | for(unsigned int i=0; i 0 && m_userscale < 1) { 245 | m_userscale /= .9f; 246 | rotation--; 247 | } 248 | while(rotation < 0 && m_userscale > .1) { 249 | m_userscale *= .9f; 250 | rotation++; 251 | } 252 | Refresh(); 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /src/CalibrationPlot.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2018 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | struct point { 34 | float p[3]; 35 | }; 36 | 37 | class CalibrationPlot : public wxGLCanvas 38 | { 39 | public: 40 | CalibrationPlot(wxWindow *parent, wxString name); 41 | ~CalibrationPlot(); 42 | void Receive(std::string name, Json::Value &value); 43 | void OnPaint(); 44 | void OnMouseEvents( wxMouseEvent& event ); 45 | 46 | private: 47 | std::vector m_recentpoints, m_sigmapoints, m_points; 48 | float m_fusionQPose[4], m_alignmentQ[4]; 49 | wxGLContext m_glContext; 50 | wxString m_name; 51 | float m_userscale; 52 | 53 | wxPoint m_lastmouse; 54 | float m_cal[5]; 55 | 56 | int m_spherepoints; 57 | GLfloat *m_sphere; 58 | }; 59 | -------------------------------------------------------------------------------- /src/ConfigurationDialog.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2018 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #include "pypilotUI.h" 28 | 29 | class pypilot_pi; 30 | 31 | class ConfigurationDialog : public ConfigurationDialogBase 32 | { 33 | friend pypilotDialog; 34 | public: 35 | ConfigurationDialog( pypilot_pi &_pypilot_pi, wxWindow* parent); 36 | ~ConfigurationDialog() {} 37 | bool Show( bool show=true ); 38 | void DetectedHost(wxString); 39 | 40 | private: 41 | void OnAboutTacking( wxCommandEvent& event ); 42 | void OnAboutAlwaysConfirmTacking( wxCommandEvent& event ); 43 | void OnAboutCenter( wxCommandEvent& event ); 44 | void OnAboutForwardNMEA( wxCommandEvent& event ); 45 | void OnAboutEnableOverlay( wxCommandEvent& event ); 46 | void OnAboutTrueNorth( wxCommandEvent& event ); 47 | void OnAboutSwitchToNAVMode( wxCommandEvent& event ); 48 | void OnAboutManualControlSpeed( wxCommandEvent& event ); 49 | void OnAddControlAngle( wxCommandEvent& event ); 50 | void OnRemoveControlAngle( wxCommandEvent& event ); 51 | void OnInformation( wxCommandEvent& event ); 52 | 53 | void OnOk( wxCommandEvent& event ); 54 | void OnClose( wxCommandEvent& event ); 55 | void OnHost( wxCommandEvent& event ); 56 | 57 | double ApplyTrueNorth(double value); 58 | 59 | std::list m_watchlist; 60 | pypilot_pi &m_pypilot_pi; 61 | }; 62 | -------------------------------------------------------------------------------- /src/GainsDialog.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2018 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #include 28 | 29 | #include "pypilotUI.h" 30 | class pypilot_pi; 31 | 32 | struct Gain; 33 | 34 | class GainsDialog : public GainsDialogBase 35 | { 36 | public: 37 | GainsDialog( pypilot_pi &_pypilot_pi, wxWindow* parent); 38 | ~GainsDialog(); 39 | 40 | bool Show( bool show=true ); 41 | 42 | void Receive(std::string name, Json::Value &value); 43 | std::map &GetWatchlist(); 44 | 45 | private: 46 | void OnProfile( wxCommandEvent& event ); 47 | void OnAddProfile( wxCommandEvent& event ); 48 | void OnRemoveProfile( wxCommandEvent& event ); 49 | void SendProfiles(); 50 | void OnPilot( wxCommandEvent& event ); 51 | void OnClose( wxCommandEvent& event ); 52 | void OnTimer( wxTimerEvent & ); 53 | void OnGainSlider( wxScrollEvent& event ); 54 | 55 | void EnumeratePilots(); 56 | void EnumerateGains(); 57 | 58 | wxTimer m_Timer; 59 | std::map m_watchlist; 60 | std::map m_gains; 61 | std::map m_gainvals; 62 | 63 | pypilot_pi &m_pypilot_pi; 64 | 65 | wxString m_profile; 66 | }; 67 | -------------------------------------------------------------------------------- /src/SettingsDialog.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2023 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #include "pypilotUI.h" 28 | #include "pypilot_pi.h" 29 | #include "pypilotClientDialog.h" 30 | 31 | #include "SettingsDialog.h" 32 | 33 | SettingsDialog::SettingsDialog(pypilot_pi &_pypilot_pi, wxWindow* parent) : 34 | SettingsDialogBase(parent), 35 | m_pypilot_pi(_pypilot_pi) 36 | { 37 | m_settings_time = wxDateTime::UNow(); 38 | } 39 | 40 | void SettingsDialog::Receive(std::string name, Json::Value &value) 41 | { 42 | if(m_settings.find(name) != m_settings.end()) 43 | m_settings_values[name] = value.asDouble(); 44 | if((wxDateTime::UNow() - m_settings_time).GetMilliseconds() > 3000) { 45 | for(std::map::iterator i = m_settings_values.begin(); i != m_settings_values.end(); i++) 46 | m_settings[i->first]->SetValue(i->second); 47 | m_settings_time = wxDateTime::UNow(); 48 | } 49 | } 50 | 51 | std::map &SettingsDialog::GetWatchlist() 52 | { 53 | static std::map list; 54 | if(list.size()) 55 | return list; 56 | 57 | std::list settings; 58 | m_pypilot_pi.m_client.GetSettings(settings, "units"); 59 | if(settings.size() == 0) 60 | return list; 61 | 62 | double period = 0.5; 63 | for(std::list::iterator i = settings.begin(); i != settings.end(); i++) { 64 | Json::Value &clist = m_pypilot_pi.m_client.list(); 65 | Json::Value setting = clist[*i]; 66 | wxSpinCtrlDouble *s = new wxSpinCtrlDouble(this, wxID_ANY); 67 | double min = setting["min"].asDouble(), max = setting["max"].asDouble(); 68 | s->SetRange(min, max); 69 | s->SetIncrement(wxMin(1, (max - min) / 100.0)); 70 | s->SetDigits(-log(s->GetIncrement()) / log(10) + 1); 71 | m_fgSettings->Add(new wxStaticText(this, wxID_ANY, *i), 0, wxALL, 5 ); 72 | m_fgSettings->Add(s, 0, wxALL | wxEXPAND); 73 | m_fgSettings->Add(new wxStaticText(this, wxID_ANY, setting["units"].asString()), 0, wxALL, 5 ); 74 | m_settings[*i] = s; 75 | s->Connect( wxEVT_SPINCTRLDOUBLE, wxSpinDoubleEventHandler( SettingsDialog::OnSpin ), NULL, this); 76 | list[*i] = period; 77 | } 78 | Fit(); 79 | 80 | return list; 81 | } 82 | 83 | void SettingsDialog::OnpypilotClient( wxCommandEvent& event ) 84 | { 85 | m_pypilot_pi.m_pypilotClientDialog->Show(!m_pypilot_pi.m_pypilotClientDialog->IsShown()); 86 | m_pypilot_pi.UpdateWatchlist(); 87 | } 88 | 89 | void SettingsDialog::OnClose( wxCommandEvent& event ) 90 | { 91 | Hide(); 92 | m_pypilot_pi.UpdateWatchlist(); 93 | } 94 | 95 | void SettingsDialog::OnSpin(wxSpinDoubleEvent& event ) 96 | { 97 | for(std::map::iterator i = m_settings.begin(); 98 | i != m_settings.end(); i++) { 99 | wxSpinCtrlDouble *s = i->second; 100 | #ifdef __OCPN__ANDROID__ 101 | if(!s->HasFocus()) 102 | continue; 103 | #else 104 | if(event.GetEventObject() != s) 105 | continue; 106 | #endif 107 | std::string name = i->first; 108 | m_pypilot_pi.m_client.set(name, s->GetValue()); 109 | m_settings_time = wxDateTime::UNow(); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/SettingsDialog.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2023 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #include 28 | 29 | #include "pypilotUI.h" 30 | 31 | class pypilot_pi; 32 | 33 | class SettingsDialog : public SettingsDialogBase 34 | { 35 | public: 36 | SettingsDialog( pypilot_pi &_pypilot_pi, wxWindow* parent); 37 | 38 | void Receive(std::string name, Json::Value &value); 39 | std::map &GetWatchlist(); 40 | 41 | private: 42 | void OnpypilotClient( wxCommandEvent& event ); 43 | void OnClose( wxCommandEvent& event ); 44 | void OnSpin(wxSpinDoubleEvent& event ); 45 | 46 | pypilot_pi &m_pypilot_pi; 47 | 48 | std::map m_settings; 49 | 50 | std::map m_settings_values; 51 | wxDateTime m_settings_time; 52 | }; 53 | -------------------------------------------------------------------------------- /src/StatisticsDialog.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2018 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #include "pypilotUI.h" 28 | #include "pypilot_pi.h" 29 | #include "StatisticsDialog.h" 30 | 31 | StatisticsDialog::StatisticsDialog(pypilot_pi &_pypilot_pi, wxWindow* parent) : 32 | StatisticsDialogBase(parent), 33 | m_pypilot_pi(_pypilot_pi) 34 | { 35 | #ifdef __OCPN__ANDROID__ 36 | GetHandle()->setStyleSheet( qtStyleSheet); 37 | #endif 38 | } 39 | 40 | StatisticsDialog::~StatisticsDialog() 41 | { 42 | } 43 | 44 | void StatisticsDialog::Receive(std::string name, Json::Value &value) 45 | { 46 | if(name == "ap.version") 47 | m_stVersion->SetLabel(value.asString()); 48 | else if(name == "imu.uptime") 49 | m_stUptime->SetLabel(value.asString()); 50 | else if(name == "ap.runtime") 51 | m_stAPRuntime->SetLabel(value.asString()); 52 | else if(name == "servo.watts") 53 | m_stWatts->SetLabel(jsonformat("%.2f", value)); 54 | else if(name == "servo.amp_hours") 55 | m_stAmpHours->SetLabel(jsonformat("%.2f", value)); 56 | else if(name == "servo.voltage") 57 | m_stVoltage->SetLabel(jsonformat("%.2f", value)); 58 | else if(name == "servo.controller_temp") 59 | m_stControllerTemp->SetLabel(jsonformat("%.1f", value)); 60 | else if(name == "servo.motor_temp") 61 | m_stMotorTemp->SetLabel(jsonformat("%.1f", value)); 62 | else if(wxString(name).EndsWith(".source")) { 63 | if(m_sources.find(name) == m_sources.end()) { 64 | m_fgStats->Add( new wxStaticText(this, wxID_ANY, name), 0, wxALL, 5); 65 | wxStaticText *s = new wxStaticText(this, wxID_ANY, "N/A"); 66 | m_sources[name] = s; 67 | m_fgStats->Add( s, 0, wxALL, 5); 68 | m_fgStats->Add( 0, 0, 1, wxEXPAND, 5 ); 69 | Fit(); 70 | } 71 | m_sources[name]->SetLabel(value.asString()); 72 | } 73 | } 74 | 75 | std::map &StatisticsDialog::GetWatchlist() 76 | { 77 | static std::map watchlist; 78 | watchlist.clear(); 79 | 80 | static const char *c_watchlist[] = 81 | {"ap.version", "imu.uptime", "ap.runtime", "servo.watts", "servo.amp_hours", "servo.voltage", "servo.controller_temp", "servo.motor_temp"}; 82 | 83 | for(unsigned int i=0; i<(sizeof c_watchlist)/(sizeof *c_watchlist); i++) 84 | watchlist[c_watchlist[i]] = 1; 85 | 86 | Json::Value list = m_pypilot_pi.m_client.list(); 87 | for(Json::ValueIterator val = list.begin(); val != list.end(); val++) { 88 | std::string name = val.key().asString(); 89 | if(wxString(name).EndsWith(".source")) 90 | watchlist[name] = 0; 91 | } 92 | 93 | return watchlist; 94 | } 95 | 96 | void StatisticsDialog::OnClose( wxCommandEvent& event ) 97 | { 98 | Hide(); 99 | m_pypilot_pi.UpdateWatchlist(); 100 | #ifdef __OCPN__ANDROID__ 101 | // EndModal(); 102 | #endif 103 | } 104 | 105 | void StatisticsDialog::OnResetAmpHours( wxCommandEvent& event ) 106 | { 107 | m_pypilot_pi.m_client.set("servo.amp_hours", 0.0); 108 | } 109 | -------------------------------------------------------------------------------- /src/StatisticsDialog.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2018 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #include 28 | #include "pypilotUI.h" 29 | 30 | class pypilot_pi; 31 | 32 | class StatisticsDialog : public StatisticsDialogBase 33 | { 34 | public: 35 | StatisticsDialog( pypilot_pi &_pypilot_pi, wxWindow* parent); 36 | ~StatisticsDialog(); 37 | 38 | void Receive(std::string name, Json::Value &value); 39 | std::map &GetWatchlist(); 40 | 41 | private: 42 | void OnClose( wxCommandEvent& event ); 43 | void OnResetAmpHours( wxCommandEvent& event ); 44 | 45 | std::map m_sources; 46 | pypilot_pi &m_pypilot_pi; 47 | }; 48 | -------------------------------------------------------------------------------- /src/icons.h: -------------------------------------------------------------------------------- 1 | /* Autogenerated by png2wx.pl on Mon Aug 27 13:51:44 2018 */ 2 | #ifndef ICONS_H 3 | #define ICONS_H 1 4 | 5 | #include 6 | #ifndef WX_PRECOMP 7 | # include 8 | #endif 9 | 10 | #include "ocpn_plugin.h" 11 | 12 | #include 13 | #include 14 | 15 | 16 | extern void initialize_images(void); 17 | 18 | extern wxBitmap *_img_pypilot_blue; 19 | extern wxBitmap *_img_pypilot_cyan; 20 | extern wxBitmap *_img_pypilot_green; 21 | extern wxBitmap *_img_pypilot_grey; 22 | extern wxBitmap *_img_pypilot_red; 23 | extern wxBitmap *_img_pypilot_yellow; 24 | extern wxBitmap *_img_pypilot_magenta; 25 | 26 | 27 | #ifdef PLUGIN_USE_SVG 28 | extern wxString _svg_pypilot; 29 | extern wxString _svg_pypilot_rollover; 30 | extern wxString _svg_pypilot_toggled; 31 | #endif 32 | 33 | 34 | #endif /* ICONS_H */ 35 | -------------------------------------------------------------------------------- /src/msvcdefs.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2015 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | # if !defined(M_PI) 32 | # define M_PI 3.14159265358979323846 /* pi */ 33 | # endif 34 | 35 | # if !defined(NAN) 36 | # define NAN std::numeric_limits::quiet_NaN () 37 | # endif 38 | 39 | # if !defined(INFINITY) 40 | # define INFINITY std::numeric_limits::infinity () 41 | # endif 42 | 43 | #define isnan _isnan 44 | #define isinf(x) (!_finite(x) && !_isnan(x)) 45 | 46 | //inline double trunc(double d) { return (d>0) ? floor(d) : ceil(d) ; } 47 | //inline double round(double n) { return n < 0.0 ? ceil(n - 0.5) : floor(n + 0.5); } 48 | 49 | # if !defined(snprintf) 50 | # define snprintf _snprintf 51 | # endif 52 | #define vsnprintf _vsnprintf 53 | #define strcasecmp _stricmp 54 | #define strncasecmp _strnicmp 55 | 56 | #define strtok_r strtok_s 57 | 58 | -------------------------------------------------------------------------------- /src/pypilotClientDialog.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2019 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #include "pypilotUI.h" 31 | 32 | class pypilot_pi; 33 | 34 | class pypilotClientDialog : public pypilotClientDialogBase 35 | { 36 | public: 37 | pypilotClientDialog( pypilot_pi &_pypilot_pi, wxWindow* parent); 38 | ~pypilotClientDialog() {} 39 | 40 | void Receive(std::string name, Json::Value &value); 41 | std::map &GetWatchlist(); 42 | 43 | bool Show( bool show=true ); 44 | 45 | private: 46 | void OnCommand(wxCommandEvent &event) { SendValues(); } 47 | void OnSpin(wxSpinDoubleEvent &event) { SendValues(); } 48 | 49 | void SendValues(); 50 | 51 | void OnOK( wxCommandEvent& event ); 52 | 53 | std::map m_values; 54 | std::map m_controls; 55 | 56 | pypilot_pi &m_pypilot_pi; 57 | }; 58 | -------------------------------------------------------------------------------- /src/pypilotDialog.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2018 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #ifdef __OCPN__ANDROID__ 28 | #include 29 | #endif 30 | 31 | #include "pypilotUI.h" 32 | 33 | class pypilot_pi; 34 | class TackDialog; 35 | 36 | class pypilotDialog : public pypilotDialogBase 37 | { 38 | public: 39 | pypilotDialog( pypilot_pi &_pypilot_pi, wxWindow* parent); 40 | ~pypilotDialog(); 41 | 42 | #ifdef __OCPN__ANDROID__ 43 | void OnMouseEvent( wxMouseEvent& event ); 44 | void OnEvtPinchGesture( wxQT_PinchGestureEvent &event); 45 | void OnEvtPanGesture( wxQT_PanGestureEvent &event); 46 | #endif 47 | 48 | void Disconnected(); 49 | 50 | void SetEnabled(bool enabled); 51 | void Receive(std::string name, Json::Value &value); 52 | void SetAPColor(); 53 | std::map &GetWatchlist(); 54 | 55 | void RebuildControlAngles(); 56 | void ShowTacking(); 57 | void Fit(); 58 | 59 | private: 60 | void UpdateStatus(); 61 | 62 | void OnAP( wxCommandEvent& event ); 63 | void OnMode( wxCommandEvent& event ); 64 | void OnManualEvents( wxMouseEvent& event ); 65 | void OnGains( wxCommandEvent& event ); 66 | void OnConfiguration( wxCommandEvent& event ); 67 | void OnCalibration( wxCommandEvent& event ); 68 | void OnSettings( wxCommandEvent& event ); 69 | void OnStatistics( wxCommandEvent& event ); 70 | void OnClose( wxCommandEvent& event ); 71 | void OnControlAngle( wxCommandEvent& event ); 72 | void OnTack( wxCommandEvent& event ); 73 | 74 | void OnManualCenter( wxCommandEvent& ); 75 | void OnManualTimer( wxTimerEvent & ); 76 | void ShowCenter(); 77 | 78 | void AddButton(int angle, wxSizer *sizer); 79 | 80 | bool m_bAPHaveRudder; 81 | 82 | double ApplyTrueNorth(double value); 83 | 84 | double m_HeadingCommand; 85 | wxDateTime m_HeadingCommandUpdate; 86 | 87 | double m_ManualCommand; 88 | wxDateTime m_ManualTimeout; 89 | wxTimer m_ManualTimer, m_RudderPollTimer; 90 | 91 | bool m_bTrueNorthMode; 92 | pypilot_pi &m_pypilot_pi; 93 | wxString m_servoController, m_imuerror, m_imuwarning, m_servoflags; 94 | 95 | TackDialog *m_TackDialog; 96 | wxString m_tack_direction; 97 | }; 98 | -------------------------------------------------------------------------------- /src/pypilot_client.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2020 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | class pypilotClient : public wxEvtHandler 37 | { 38 | public: 39 | pypilotClient(bool queue_mode = true, bool request_list = true); 40 | 41 | void connect(wxString host, int port=0); 42 | void disconnect(); 43 | bool connected() { return m_sock.IsConnected(); } 44 | virtual bool receive(std::string &name, Json::Value &value); 45 | 46 | void set(std::string name, Json::Value &value); 47 | void set(std::string name, double value); 48 | void set(std::string name, std::string &value); 49 | void set(std::string name, const char *value); 50 | void watch(std::string name, bool on=true, double period=0); 51 | 52 | bool info(std::string name, Json::Value &info); 53 | Json::Value &list() { return m_list; } 54 | void update_watchlist(std::map &watchlist); 55 | 56 | void GetSettings(std::list &settings, std::string member); 57 | 58 | protected: 59 | virtual void OnConnected() = 0; 60 | virtual void OnDisconnected() = 0; 61 | Json::Value m_list; 62 | 63 | private: 64 | void OnSocketEvent(wxSocketEvent& event); 65 | void OnTimer( wxTimerEvent & ); 66 | 67 | wxSocketClient m_sock; 68 | std::string m_sock_buffer; 69 | std::deque > m_queue; 70 | std::map m_map; 71 | 72 | bool m_bQueueMode; 73 | 74 | bool m_bRequestList; 75 | 76 | std::map m_watchlist; 77 | 78 | wxTimer m_timer; 79 | 80 | DECLARE_EVENT_TABLE() 81 | }; 82 | -------------------------------------------------------------------------------- /src/pypilot_pi.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Project: OpenCPN 4 | * Purpose: pypilot Plugin 5 | * Author: Sean D'Epagnier 6 | * 7 | *************************************************************************** 8 | * Copyright (C) 2018 by Sean D'Epagnier * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 3 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 24 | *************************************************************************** 25 | */ 26 | 27 | #ifndef _PYPILOTPI_H_ 28 | #define _PYPILOTPI_H_ 29 | 30 | #include 31 | 32 | #include "wx/wx.h" 33 | #include 34 | 35 | #include "version.h" 36 | #include "wxWTranslateCatalog.h" 37 | 38 | #define ABOUT_AUTHOR_URL "http://seandepagnier.users.sourceforge.net" 39 | 40 | #define OPC wxS("opencpn-pypilot_pi") 41 | 42 | #ifndef WXINTL_NO_GETTEXT_MACRO 43 | #ifdef OPC 44 | #ifdef _ 45 | #undef _ 46 | #endif // _ 47 | #define _(s) wxGetTranslation((s),OPC) 48 | #endif // OPC 49 | #else 50 | #define _(s) wxGetTranslation((s)) 51 | #endif // WXINTL_NO_GETTEXT_MACRO 52 | 53 | #include "ocpn_plugin.h" 54 | #include "qtstylesheet.h" 55 | 56 | #ifdef __MSVC__ 57 | #include "msvcdefs.h" 58 | #endif 59 | 60 | #include "pypilot_client.h" 61 | 62 | //---------------------------------- 63 | // The PlugIn Class Definition 64 | //---------------------------------- 65 | 66 | #define PYPILOT_TOOL_POSITION -1 // Request default positioning of toolbar tool 67 | 68 | class wxServDisc; 69 | 70 | class piDC; 71 | class pypilotDialog; 72 | class GainsDialog; 73 | class ConfigurationDialog; 74 | class StatisticsDialog; 75 | class CalibrationDialog; 76 | class SettingsDialog; 77 | class pypilotClientDialog; 78 | 79 | 80 | class pypilot_pi; 81 | class pypilotClient_pi : public pypilotClient 82 | { 83 | public: 84 | pypilotClient_pi( pypilot_pi &_pypilot_pi ) 85 | : pypilotClient(), m_pypilot_pi(_pypilot_pi) {} 86 | virtual void OnConnected(); 87 | virtual void OnDisconnected(); 88 | 89 | private: 90 | pypilot_pi &m_pypilot_pi; 91 | }; 92 | 93 | 94 | class pypilot_pi : public wxEvtHandler, public opencpn_plugin_117 95 | 96 | { 97 | public: 98 | 99 | pypilot_pi(void *ppimgr); 100 | 101 | int Init(void); 102 | bool DeInit(void); 103 | 104 | int GetAPIVersionMajor(); 105 | int GetAPIVersionMinor(); 106 | int GetPlugInVersionMajor(); 107 | int GetPlugInVersionMinor(); 108 | int GetPlugInVersionPatch(); 109 | int GetPlugInVersionPost(); 110 | 111 | wxBitmap *GetPlugInBitmap(); 112 | wxString GetCommonName(); 113 | wxString GetShortDescription(); 114 | wxString GetLongDescription(); 115 | 116 | int GetToolbarToolCount(void); 117 | void OnToolbarToolCallback(int id); 118 | void OnContextMenuItemCallback(int id); 119 | 120 | bool RenderOverlay(wxDC &dc, PlugIn_ViewPort *vp); 121 | bool RenderGLOverlay(wxGLContext *pcontext, PlugIn_ViewPort *vp); 122 | void Render(piDC &dc, PlugIn_ViewPort &vp); 123 | void ReadConfig(); 124 | 125 | void OnTimer( wxTimerEvent & ); 126 | 127 | // Optional plugin overrides 128 | void SetColorScheme(PI_ColorScheme cs); 129 | 130 | // Other public methods 131 | static wxString StandardPath(); 132 | 133 | void UpdateConfiguration(); 134 | 135 | double Declination(); 136 | void OnConnected(); 137 | void OnDisconnected(); 138 | void UpdateWatchlist(); 139 | double HeadingCommand() { return m_ap_heading_command; } 140 | 141 | pypilotClient_pi m_client; 142 | 143 | pypilotDialog *m_pypilotDialog; 144 | GainsDialog *m_GainsDialog; 145 | ConfigurationDialog *m_ConfigurationDialog; 146 | StatisticsDialog *m_StatisticsDialog; 147 | CalibrationDialog *m_CalibrationDialog; 148 | SettingsDialog *m_SettingsDialog; 149 | pypilotClientDialog *m_pypilotClientDialog; 150 | 151 | double m_declination; 152 | wxDateTime m_declinationTime; 153 | wxString m_mode; 154 | Json::Value m_modes; 155 | 156 | private: 157 | void SetNMEASentence(wxString &sentence); 158 | void OnNMEASocketEvent(wxSocketEvent& event); 159 | void SetPositionFixEx(PlugIn_Position_Fix_Ex &pfix); 160 | void SetPluginMessage(wxString &message_id, wxString &message_body); 161 | void RearrangeWindow(); 162 | double AdjustHeading(double heading); 163 | void Receive(std::string name, Json::Value &value); 164 | void UpdateStatus(); 165 | void SetToolbarIcon(); 166 | 167 | void StartZeroConfig(); 168 | void StopZeroConfig(); 169 | void onSDNotify(wxCommandEvent& event); 170 | 171 | wxServDisc *m_servscan; 172 | 173 | wxDateTime m_declinationRequestTime; 174 | int m_leftclick_tool_id; 175 | 176 | wxTimer m_Timer; 177 | 178 | wxString m_status; 179 | bool m_bHaveNAV; 180 | wxDateTime m_lastsocketinput; 181 | 182 | wxString m_host; 183 | bool m_bForwardNMEA, m_bSwitchToNAVMode; 184 | bool m_bEnableGraphicOverlay; 185 | 186 | PlugIn_Position_Fix_Ex m_lastfix; 187 | double m_ap_heading, m_ap_heading_command, m_imu_heading; 188 | 189 | double m_filtered_lat, m_filtered_lon, m_filtered_speed, m_filtered_track; 190 | 191 | wxDateTime m_lastMessage; 192 | 193 | bool m_enabled; 194 | int m_ReadConfig; 195 | 196 | wxSocketClient m_nmeasocket; 197 | std::string m_nmeasock_buffer; 198 | 199 | DECLARE_EVENT_TABLE() 200 | }; 201 | 202 | double heading_resolve(double degrees); 203 | double heading_resolve_pos(double degrees); 204 | 205 | wxString jsonformat(const char *format, Json::Value &value); 206 | double jsondouble(Json::Value &value); 207 | 208 | #endif 209 | -------------------------------------------------------------------------------- /src/wxWTranslateCatalog.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * $Id: ocpn_draw_pi.h,v 1.0 2015/01/28 01:54:37 jongough Exp $ 3 | * 4 | * Project: OpenCPN 5 | * Purpose: Redefine _() macro to allow usage of catalog 6 | * Author: Jon Gough 7 | * 8 | *************************************************************************** 9 | * Copyright (C) 2010 by David S. Register * 10 | * $EMAIL$ * 11 | * * 12 | * This program is free software; you can redistribute it and/or modify * 13 | * it under the terms of the GNU General Public License as published by * 14 | * the Free Software Foundation; either version 2 of the License, or * 15 | * (at your option) any later version. * 16 | * * 17 | * This program is distributed in the hope that it will be useful, * 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 20 | * GNU General Public License for more details. * 21 | * * 22 | * You should have received a copy of the GNU General Public License * 23 | * along with this program; if not, write to the * 24 | * Free Software Foundation, Inc., * 25 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 26 | *************************************************************************** 27 | */ 28 | #ifndef _ODCATTRANS_H_ 29 | #define _ODCATTRANS_H_ 30 | 31 | #ifndef WXINTL_NO_GETTEXT_MACRO 32 | #ifdef _ 33 | #undef _ 34 | #endif // _ 35 | #define _(s) wxGetTranslation((s), wxS("opencpn-pypilot_pi")) 36 | #endif // WXINTL_NO_GETTEXT_MACRO 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /update_submodule_branch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ "$#" -eq "1" && ( "$1" -eq "-h " || "$1" -eq "-help" ) ]]; then 4 | echo "Will update opencpn-libs current branch to latest version." 5 | fi 6 | 7 | git submodule update --remote --merge opencpn-libs 8 | git add opencpn-libs 9 | git commit -m "Updating current opencpn-libs to latest version" 10 | 11 | echo "This will now need to be pushed to make it available to circleci builds in the cloud" 12 | --------------------------------------------------------------------------------